gta6/prompts
ui
Freebeginnerui

Status HUD: Health, Armor, Hunger, Thirst

A live ESX status HUD that pushes health, armor, hunger and thirst to an NUI overlay and hides itself on death.

NON-TESTÉ — the reference Lua is syntax-validated, not run in a live FiveM server. Adapt and test on your own dev server before shipping.
Est. Lua
~69 loc
Claude
Claude Opus 4.x / Sonnet 4.x
Validation
syntax-validated
Updated
2026-06-24

Description

A complete client-side status HUD for ESX servers. It displays the player's health, armor, hunger and thirst as a four-bar NUI overlay, refreshing a few times a second. Health is remapped from GTA's raw 100-200 range to a clean 0-100 bar, hunger/thirst come from the esx_status tick, and the HUD hides itself on death and exposes a /togglehud command. Every roleplay server wants this as its baseline player HUD.

Prompt Template

You are writing a FiveM CLIENT script for es_extended (stable, exports-based
getSharedObject). Produce one client.lua that renders a status HUD via NUI.

Requirements:
1. Fetch ESX with: local ESX = exports['es_extended']:getSharedObject().
2. Subscribe to the "esx_status:onTick" event and cache the "hunger" and
   "thirst" percentages — do NOT invent natives for needs.
3. In a CreateThread loop that runs with Wait(200) (NOT Wait(0)):
   - get the ped with PlayerPedId() (never GetPlayerPed(-1)),
   - read health with GetEntityHealth and REMAP it: GTA health is 100-200 for a
     living ped, so bar = max(0, (health-100)/100*100),
   - read armor with GetPedArmour,
   - SendNUIMessage({ action='updateStatus', health=, armor=, hunger=, thirst= }).
4. Toggle the HUD on "esx:playerLoaded", hide it when IsEntityDead(ped) is true,
   and register a /togglehud command.
Use SendNUIMessage for all UI updates. Return only Lua, no markdown fences.

Expected Output

The reference Lua lives at content/expected-outputs/ui/01-status-hud.lua. It is a single client script: it caches needs from esx_status:onTick, runs a Wait(200) polling loop that remaps health and pushes values via SendNUIMessage, and toggles visibility on spawn/death. In fxmanifest.lua this is a client_script plus a ui_page and files for the HTML/CSS/JS.

01-status-hud.lua70 lines
-- 01-status-hud.lua
-- Client-side ESX status HUD: health, armor, hunger, thirst as a NUI overlay.
-- Pushes live values to an NUI page every frame-tick; requires es_extended.

local ESX = exports["es_extended"]:getSharedObject()

-- Cached status values (0-100). Hunger/thirst come from ESX status ticks.
local status = { hunger = 100.0, thirst = 100.0 }

-- ESX broadcasts player status on a loop; cache the relevant metrics.
AddEventHandler("esx_status:onTick", function(data)
    for _, st in ipairs(data) do
        if st.name == "hunger" then
            status.hunger = st.percent
        elseif st.name == "thirst" then
            status.thirst = st.percent
        end
    end
end)

-- Show the HUD only once the player has spawned in.
local hudVisible = false
RegisterNetEvent("esx:playerLoaded", function()
    hudVisible = true
    SendNUIMessage({ action = "toggleHud", show = true })
end)

-- Push health + armor + the cached needs to the NUI layer ~5x/second.
CreateThread(function()
    while true do
        if hudVisible then
            local ped = PlayerPedId()
            -- GTA health floor is 100; remap 100-200 to a 0-100 bar.
            local rawHealth = GetEntityHealth(ped)
            local health = math.max(0, (rawHealth - 100) / 100 * 100)
            local armor = GetPedArmour(ped)

            SendNUIMessage({
                action = "updateStatus",
                health = math.floor(health),
                armor  = math.floor(armor),
                hunger = math.floor(status.hunger),
                thirst = math.floor(status.thirst),
            })
        end
        Wait(200)
    end
end)

-- Hide the HUD on death so it does not overlay the wasted screen.
CreateThread(function()
    while true do
        local ped = PlayerPedId()
        if hudVisible and IsEntityDead(ped) then
            SendNUIMessage({ action = "toggleHud", show = false })
            hudVisible = false
        elseif not hudVisible and not IsEntityDead(ped) and NetworkIsPlayerActive(PlayerId()) then
            hudVisible = true
            SendNUIMessage({ action = "toggleHud", show = true })
        end
        Wait(1000)
    end
end)

-- Let players toggle the HUD with a command.
RegisterCommand("togglehud", function()
    hudVisible = not hudVisible
    SendNUIMessage({ action = "toggleHud", show = hudVisible })
end, false)

Known Failure Modes

  • Health range confusion — Claude often treats GetEntityHealth as 0-100; a living ped is 100-200. Always remap (health-100)/100*100.
  • Wait(0) HUD loop — a per-frame loop burns CPU for no visual gain. Tell Claude to use Wait(200) (~5 fps) for status bars.
  • Invented needs natives — there is no GetPlayerHunger. Hunger/thirst come from esx_status:onTick; subscribe to it.
  • Stale HUD on death — without an IsEntityDead check the bars hover over the wasted screen.

Integration Notes

  • Put this in client/client.lua; declare it as a client_script and add a ui_page 'html/index.html' with the files {} block in fxmanifest.lua.
  • Depends on es_extended and esx_status (which emits the tick event).
  • Test on a dev server: spawn in, run /togglehud, take damage and let hunger drain to confirm each bar moves and the HUD hides on death.

Profit Potential

$100–$1200/mo on Tebex (expected ~$300). [INFERRED] priced at the low end of the $50-389 script band against the signal-scraper tebex_snapshot corpus (median seller $11.85K/mo, n=100) — a free-tier, heavily-cloned status HUD earns little standalone but anchors a paid HUD bundle.

Trend Signal

stable — [INFERRED] HUD/UI utilities are always-needed but commoditized.

Sales Angle

Ship it free as the baseline status HUD that hooks server owners, then upsell the vehicle and phone HUDs alongside it. Bundle the HUD pack at $50 on Tebex.

Difficulty & Ship Time

beginner · ships in 2-4h.