Kartik Scripts

Custom Statuses & Buffs

Other resources can add their own values to the HUD:

  • 📊 Statuses appear in the player status row next to health and hunger. They work in every status style. Examples: nitro, battery, temperature.
  • ⏳ Buffs appear in their own Buffs component, which by default sits right after the last tile of the player status row (movable in /hudedit). They use the player's status style, so they look like the rest of the row. The fill drains as the timer runs down, a badge shows the stack count, and the time left is shown underneath. Examples: adrenaline, drunk, VIP, double XP.

Players can change the mode and colour of each one in /hud → Player Status unless your script locks them. HUD Builder designs can use them too.


🚀 Quick start

-- Nitro gauge in the status row, only in vehicles
exports['kartik-hud']:registerStatus('nitro', {
    label = 'Nitro', icon = 'flame', color = '#22d3ee',
    value = 100, context = 'vehicle', order = 75,
    warn = { below = 20, blink = true },
})

-- Update it whenever it changes (it is fine to call this every frame)
exports['kartik-hud']:setStatusValue('nitro', 42)

-- A 60 second buff
exports['kartik-hud']:addBuff('adrenaline', { label = 'Adrenaline', icon = 'activity', duration = 60 })

-- A stacking debuff: each drink adds a stack and restarts the timer
exports['kartik-hud']:addBuff('drunk', {
    label = 'Drunk', icon = 'beer', type = 'debuff',
    duration = 120, stack = true, maxStacks = 5,
    onExpire = function() print('sober again') end,
})

-- Let the HUD read the value itself
exports['kartik-hud']:registerStatus('battery', {
    label = 'Battery', icon = 'battery', interval = 500,
    getValue = function() return exports['my-phone']:getBattery() end,
})

Statuses belong to the resource that registered them and are removed when it stops. Pass persist = true to keep them after it stops.


⚙️ Options

registerStatus, addBuff and updateStatus all take the same options. Leave out anything you don't need.

OptionDefaultWhat it does
labelthe idName shown in /hud, the builder and under the buff tile
icon"star"A built-in icon, an image ("https://…" or "nui://resource/icon.png"), or an SVG path ("svg:M12 2 4 22h16z" on a 24×24 box), or short text ("text:TCS", up to 4 characters)
tintautotrue colours an image with color, which works best with white PNG icons. false keeps built-in icons white
colorfrom typeHex colour such as "#22d3ee"
type"neutral", or "buff" for addBuff"buff", "debuff" or "neutral". Sets the default colour (green, red or blue) and how strongly the tile is tinted
display"status", or "buff" for addBuffWhere it appears: "status" (status row), "buff" (buff tiles) or "none" (only builder designs use it)
value100Current value
min / max0 / 100The range value is measured against
unit"%"Unit shown in builder text
textnoneReplaces the timer text under a buff tile, and the builder's text
mode"always""always", "auto" (only when relevant, see autoShow) or "never". This is the default; players can change it
autoShow"notFull"When "auto" shows it: "notFull", "notEmpty", { below = 50 } or { above = 0 } (percent of the range)
visibletrueScript-side switch to hide or show it
context"all""all", "foot" or "vehicle"
order100Position in the row. Built-in stats are numbered 10 (health), 20, 30 and so on up to 70 (stamina), so 25 places a status between armour and hunger
warnnone{ below = 20, color = "#ef4444", blink = true } or { above = 80, … }. Changes the colour and blinks past the threshold
durationnoneTimer in seconds. When it runs out, the status is removed and onExpire fires. Buffs blink during their last 5 seconds
stacks / maxStacks0 / noneStack count, shown as a badge when it is 2 or more
lockedfalsePlayers can't change its mode or colour in /hud
persistfalseKeep it after your resource stops
getValuenoneA function the HUD polls. Return a number, or a table of options to update several at once
interval250How often getValue is polled, in ms
onExpire(id)noneCalled when the timer runs out
onRemove(id, reason)noneCalled when the status is removed: "removed", "expired", "cleared" or "resource_stopped"

Adding a buff that is already active

addBuff on an id that already exists refreshes the buff instead of creating a second one:

OptionWhat it does
stack = trueAdds 1 to the stack count (up to maxStacks)
refresh = "reset"Default. Starts the timer over
refresh = "extend"Adds duration to the time left
refresh = "keep"Leaves the timer alone

💻 Client exports

local ok, reason = exports['kartik-hud']:registerStatus(id, options)
local ok, reason = exports['kartik-hud']:addBuff(id, options)
exports['kartik-hud']:updateStatus(id, options)
exports['kartik-hud']:setStatusValue(id, value)
exports['kartik-hud']:setStatusVisible(id, visible)
exports['kartik-hud']:setStatusText(id, text)        -- nil clears it
exports['kartik-hud']:extendStatus(id, seconds)      -- negative shortens the timer
local seconds = exports['kartik-hud']:getStatusTimeLeft(id)
exports['kartik-hud']:removeStatus(id)               -- removeBuff(id) does the same
local exists = exports['kartik-hud']:hasStatus(id)
local status = exports['kartik-hud']:getStatus(id)
local list = exports['kartik-hud']:getStatuses()
exports['kartik-hud']:clearStatuses()                -- your resource's statuses; '*' for all
ReturnsType
okbooleanWhether it was added
reasonstring"invalid_id" or "limit" when it failed

Ids can use letters, numbers, _ and -, up to 40 characters. Registering an id that already exists replaces it and keeps its place in the order. Up to Config.CustomStatuses.max statuses can exist at once.


🖥️ Server exports

These are the same calls with a player id first. Use -1 for every player.

exports['kartik-hud']:addBuff(source, 'double_xp', { label = '2x XP', icon = 'sparkles', duration = 3600 })
exports['kartik-hud']:setStatusValue(source, 'nitro', 80)
exports['kartik-hud']:removeStatus(source, 'double_xp')

Available: registerStatus, addBuff, updateStatus, setStatusValue, setStatusVisible, setStatusText, removeStatus, removeBuff and extendStatus.

Functions can't be sent over the network, so getValue, onExpire and onRemove only work through the client exports.


📡 Events

EventSide
kartik-hud:client:statusExpiredClient (local)(id): a timer ran out
kartik-hud:client:statusRemovedClient (local)(id, reason): removed for any reason
kartik-hud:client:registerStatusClient (net)TriggerClientEvent('kartik-hud:client:registerStatus', source, id, options)
kartik-hud:client:addBuffClient (net)(id, options)
kartik-hud:client:updateStatusClient (net)(id, options)
kartik-hud:client:setStatusValueClient (net)(id, value)
kartik-hud:client:removeStatusClient (net)(id)
kartik-hud:client:extendStatusClient (net)(id, seconds)

📋 Presets in config

Statuses listed in Config.CustomStatuses.presets exist from the moment the HUD starts, so other scripts only need to call setStatusValue. See Configuration → Custom statuses.


🛠️ In the HUD Builder

Registered statuses appear under Scripts in Data → Shows:

Data
custom.<id>The value, over its min–max range
custom.<id>.activeWhether it is on screen (registered, visible, right context, not expired)
custom.<id>.textIts text, otherwise the time left, otherwise the value with its unit
custom.<id>.timeTime left as a percentage (statuses with a timer)
custom.<id>.stacksStack count (buffs)

A design keeps its binding while the resource that registers the status is stopped.


🎨 Icons

heart drop run shield food water lungs brain bolt fuel engine seatbelt cruise hazard plane bicycle mic radio volume crosshair gauge clock pin navigation compass user wallet cash briefcase thermometer battery zap wrench car anchor droplet flame wind skull star heartOutline shieldOutline brainOutline rocket sparkles snowflake sun moon timer hourglass pill syringe bandage activity beer wine coffee cigarette cannabis leaf dumbbell footprints eye ghost swords target crown trophy key magnet siren biohazard radiation

On this page