ns-hud — NullSect HUD Engine
Simple by default, powerful when customised. A widget-based FiveM HUD: players get a clean classic GTA-style HUD out of the box, and can rebuild almost every part of it in a live in-game editor. Other resources plug their own widgets, rules and notifications into it through a public API.
Turkish: README.tr.md · Install: INSTALLATION.md · Config: CONFIGURATION.md
Features
- 27 built-in widgets — health, armor, hunger, thirst, stamina, stress, oxygen, cash, bank, player ID, server time, voice, compass, street, zone, speed, RPM, gear, fuel, engine, vehicle damage, seatbelt, weapon, ammo, job, objective, notifications.
- Live editor (
/hud) on the real HUD: drag & drop, corner resize, 11 anchors (9 screen anchors + beside / above minimap), offset, size, scale, opacity, rotation, colour, icon, font, spacing, variant, visibility, smart-hide. Snap grid, undo/redo, keyboard nudging, ESC to close (asks before discarding). - Layouts & profiles — ready layouts Classic, Minimal, RP, Racing, Streamer plus up to 10 personal layouts per player (save, save-as, rename, delete, switch at any time).
- Themes — Classic, Minimal, Modern, Racing, all on the same engine (CSS variables + widget variants: bar / pill / ring / vertical, digital / gauge, bar / segments / line).
- Context-aware — vehicle / on-foot / armed / firearm / underwater / job / phone / paused / dead; widgets hide when irrelevant.
- Rule system — data-driven
WHEN … THEN …(show, hide, style, opacity, scale) from config, per layout (rule editor in the UI) and from scripts. - Notification manager — 4 levels (critical / important / normal / background), stacking, max visible, priority queue, de-duplication (
×3), per-resource spam limit, synthesized sounds with volume. - Focus mode (one key, keeps speed / compass / objective…), cinematic mode (HUD, minimap, notifications, black bars), phone behaviour (shrink / hide).
- Accessibility — HUD / text / icon scale, global opacity, animation speed, UI sound volume, high contrast, larger text, reduced motion, colour-blind palettes (protanopia / deuteranopia / tritanopia).
- Resolution-safe — reference grid scaled by screen height, GTA safezone respected, game aspect followed (multi-monitor), every widget clamped inside the safe area (rotation included). Tested 720p → 4K, 21:9 and 32:9.
- Persistent — oxmysql (auto-migrated tables) or server KVP fallback; per license or per character.
- Performance — one adaptive loop (80 ms in vehicle, 250 ms on foot, 1 s hidden), values diffed and batched into a single NUI message per 40 ms window; zero NUI traffic while nothing changes.
- Secure — server-authoritative storage, strict validation of every layout / rule / pref, ownership checks, rate limits, per-player lock; external widget data is sanitised and rendered with
textContentonly. - Qbox first, QBCore / ESX / standalone through
bridge/; voice adapters for pma-voice, SaltyChat and mumble.
Commands
| Command | Default key | Description |
|---|---|---|
/hud | — | Open / close the HUD editor |
/hudfocus | F7 | Toggle focus mode |
/cinematic | — | Toggle cinematic mode |
/togglehud | — | Hide / show the HUD |
/hudreset <id> | — | Admin: wipe a player's HUD data |
/hudtest | — | Admin + Config.Debug: demo widget, objective and notification spam test |
Keys are registered with RegisterKeyMapping, players can rebind them in Settings → Key Bindings → FiveM.
Client exports
All exports remember the calling resource; everything it registered is cleaned up automatically when it stops.
local hud = exports['ns-hud']
hud:RegisterWidget(def) --> ok, errKey
hud:RemoveWidget(id)
hud:ShowWidget(id) / hud:HideWidget(id)
hud:SetWidgetVisible(id, true|false|nil) -- nil = back to automatic
hud:UpdateWidget(id, data) -- merge
hud:SetWidgetData(id, data) -- replace
hud:GetWidget(id) --> { definition, data, override }
hud:ResetWidget(id)
hud:Notify(data) -- or Notify(message, type, duration)
hud:ClearNotifications()
hud:SetObjective(title, text) / hud:ClearObjective()
hud:AddRule(rule) / hud:RemoveRule(id)
hud:SetContext(key, value) -- custom rule field 'ext.<key>'
hud:SetPhoneOpen(bool|nil) / hud:SetSeatbelt(bool) / hud:SetPlayerStatus({ hunger = 80, thirst = 60, stress = 10 })
hud:SetFocusMode(bool) / hud:ToggleFocusMode() / hud:IsFocusMode()
hud:SetCinematicMode(bool) / hud:IsCinematicMode()
hud:SetHudHidden(bool) / hud:IsHudVisible()
hud:OpenEditor() / hud:IsReady()
Server: exports['ns-hud']:Notify(playerId | -1, data).
Registering a job widget (taxi example)
local function registerTaxiWidget()
exports['ns-hud']:RegisterWidget({
id = 'taxi_ride', label = 'Taxi', category = 'job', icon = 'taxi', color = '#f5c518',
template = 'panel', -- 'panel' (title + rows) | 'value' | 'status' (bar)
focus = true, -- stays visible in focus mode
fields = {
{ key = 'passenger', label = 'Passenger', icon = 'user' },
{ key = 'destination', label = 'Destination', icon = 'pin' },
{ key = 'fare', label = 'Fare', format = 'money' }, -- text | number | money | percent | distance | time | speed
{ key = 'eta', label = 'ETA', format = 'time' },
},
defaults = { anchor = 'cr', x = 0, y = -40 },
})
end
AddEventHandler('ns-hud:cl:ready', registerTaxiWidget) -- ns-hud (re)started
CreateThread(function()
if GetResourceState('ns-hud') == 'started' then registerTaxiWidget() end
end)
-- during a ride
exports['ns-hud']:SetWidgetVisible('taxi_ride', true)
exports['ns-hud']:UpdateWidget('taxi_ride', { passenger = 'Michael', destination = 'Airport', fare = 84, eta = 95 })
-- ride finished
exports['ns-hud']:SetWidgetVisible('taxi_ride', false)
Same pattern for other jobs, e.g. bus { route, next_stop, passengers, stop_requests }, locksmith { job, target, distance (format = 'distance'), objective }, tow { call, vehicle, distance, objective }. Instead of manual visibility, set jobs = { 'taxi' } and the widget shows whenever the player has that job.
Rules
exports['ns-hud']:AddRule({
id = 'taxi_meter_running',
when = { { 'ext.meter', '==', true }, { 'speed', '>', 120 } },
actions = { { 'style', 'taxi_ride', 'warning' }, { 'show', 'objective' } },
})
exports['ns-hud']:SetContext('meter', true)
Fields: vehicle onfoot armed firearm dead underwater health armor hunger thirst stress stamina oxygen speed rpm fuel engine body seatbelt job duty phone talking radio hour and ext.<key>. Operators: == != < <= > >= in. Actions: show hide style opacity scale; styles: warning danger highlight pulse muted success.
Notifications
exports['ns-hud']:Notify({
title = 'Dispatch', message = 'New call at Legion Square',
level = 'important', -- critical | important | normal | background
type = 'info', -- info | success | warning | error
icon = 'bell', duration = 6000, sound = 'chime', priority = 60, position = 'top-right',
})
License
© NullSect. Fonts: Barlow, Barlow Condensed, Share Tech Mono — SIL Open Font License (see nui/fonts/OFL-*.txt).