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.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
GetEntityHealthas 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 fromesx_status:onTick; subscribe to it. - Stale HUD on death — without an
IsEntityDeadcheck the bars hover over the wasted screen.
Integration Notes
- Put this in
client/client.lua; declare it as aclient_scriptand add aui_page 'html/index.html'with thefiles {}block infxmanifest.lua. - Depends on
es_extendedandesx_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.