Koja Scripts
FREE

Exports & Events

Client API: notifications, progress bar, text UI, status effects, killfeed, stress, seatbelt, nitro and visibility.

Exports & Events

This is the HUD's API for your other resources: notifications, progress bars, text prompts, status effects, the killfeed, stress, nitro, seatbelt and visibility. Every export here is client-side. From server code, trigger one of the events or a client event of your own that calls the export.

The resource is called koja-hud:

local hud = exports['koja-hud']
hud:sendNotify({ title = 'Bank', desc = 'Transfer complete' })

Summary

ExportReturnsPurpose
sendNotify(data)—Show a notification
startProgressbar(data, cb)—Run a progress bar, call cb(finished) at the end
cancelProgressbar()—Cancel the running progress bar
isProgressbarActive()booleanIs a progress bar running
TextUI(data)—Show the "press E" prompt
HideUI()—Hide it
ToggleHUD(visible)—Show or hide the whole HUD
HideComponent(name, hide)—Show or hide one component
HideComponents(map)—Several at once
SetStatusEffects(list)—Replace the active status effects
AddStatusEffect(effect)—Add or update one effect
RemoveStatusEffect(id)—Remove one effect
AddKillfeed(killer, victim, weapon, distance, opts)—Add a killfeed entry
GetStress()numberCurrent stress, 0–100
IsSeatbeltOn()booleanIs the seatbelt fastened
SeatbeltState(state)—Set the seatbelt state
GetNitro()numberNitro left in the current vehicle
SetNitro()—Install nitro in the owned vehicle in front of the player

Notifications

sendNotify

exports['koja-hud']:sendNotify({
    type = 'info',
    title = 'Bank',
    desc = 'You received <strong>$500</strong>',
    icon = 'fa-solid fa-building-columns',
    color = '#35c76c',
    time = 5000
})
FieldTypeDefaultNotes
titlestring'Notify'Plain text
descstring''May contain simple HTML, see below
iconstring'fas fa-info-circle'Any Font Awesome 6 class
colorstring'#ffffff'Accent colour, hex
timenumber5000How long it stays, in milliseconds
typestring'info''success' and 'error' replace icon and color with a green tick or a red mark; anything else keeps yours

It always uses the HUD's notifications, whatever KOJA.Notify is set to, and is hidden if the player switched notifications off.

HTML in desc. Allowed tags: b, strong, i, em, u, s, small, span, br, p, div, ul, ol, li. Allowed inline styles: color, font-weight, font-style, text-decoration, opacity. Everything else — scripts, images, links, other attributes — is removed, so passing player-written text is safe.

exports['koja-hud']:sendNotify({
    title = 'Job',
    desc = "You earned <span style='color:#7cf14e'>$5,463</span> for finished work.",
    type = 'success'
})

From the server

There is no server export. Send a client event of your own:

client.lua
RegisterNetEvent('my-resource:notify', function(data)
    exports['koja-hud']:sendNotify(data)
end)
server.lua
TriggerClientEvent('my-resource:notify', source, { title = 'Garage', desc = 'Vehicle stored', type = 'success' })

Progress bar

startProgressbar

exports['koja-hud']:startProgressbar({
    label = 'Repairing',
    icon = 'fa-solid fa-wrench',
    time = 5,
    cancelable = true,
    animation = { dict = 'mini@repair', name = 'fixing_a_ped' },
    inputBlock = { keys = { 'W', 'A', 'S', 'D' } }
}, function(finished)
    if finished then
        -- repaired
    else
        -- cancelled
    end
end)
FieldTypeNotes
labelstringText above the bar
iconstringFont Awesome class
timenumberDuration in seconds
cancelablebooleanThe player can cancel with X
animationtableOptional { dict, name }. Loaded, played for the duration, stopped at the end
inputBlocktableOptional { keys = { ... } } — keys disabled while the bar runs

The call returns immediately; the callback runs when the bar ends, with true if it completed and false if it was cancelled or replaced. Starting a new progress bar while one is running replaces it, and the old callback gets false.

Key names for inputBlock.keys: ESC, F1–F3, F5–F10, ~, 1–9, -, =, BACKSPACE, TAB, Q, W, E, R, T, Y, U, P, [, ], ENTER, CAPS, A, S, D, F, G, H, K, L, LEFTSHIFT, Z, X, C, V, B, N, M, ,, ., LEFTCTRL, LEFTALT, SPACE, RIGHTCTRL, HOME, PAGEUP, PAGEDOWN, DELETE, LEFT, RIGHT, TOP, DOWN, NENTER, N4–N9, N+, N-. Unknown names are ignored.

To wait for the result inline, wrap it in a promise:

local p = promise.new()
exports['koja-hud']:startProgressbar({ label = 'Searching', icon = 'fa-solid fa-magnifying-glass', time = 3 }, function(finished)
    p:resolve(finished)
end)
local finished = Citizen.Await(p)

cancelProgressbar

exports['koja-hud']:cancelProgressbar()

Cancels the running bar; its callback gets false.

isProgressbarActive

if exports['koja-hud']:isProgressbarActive() then return end

Text UI

TextUI

exports['koja-hud']:TextUI({
    input = 'E',
    type = 'Stash',
    desc = 'Open the stash'
})
FieldNotes
inputThe key shown in the box
typeSmall heading above the text
descThe text

Calling it again replaces the prompt. It does not listen for the key for you — check the key in your own loop and call HideUI when the player walks away.

CreateThread(function()
    local shown = false
    while true do
        local near = #(GetEntityCoords(PlayerPedId()) - vec3(215.0, -810.0, 30.7)) < 2.0
        if near and not shown then
            exports['koja-hud']:TextUI({ input = 'E', type = 'Garage', desc = 'Take out a vehicle' })
            shown = true
        elseif not near and shown then
            exports['koja-hud']:HideUI()
            shown = false
        end
        if near and IsControlJustPressed(0, 38) then
            -- open your menu
        end
        Wait(near and 0 or 500)
    end
end)

HideUI

exports['koja-hud']:HideUI()

Visibility

ToggleHUD

exports['koja-hud']:ToggleHUD(false) -- hide everything
exports['koja-hud']:ToggleHUD(true)  -- bring it back

Hides or shows the whole HUD — for cutscenes, character creation, cameras. It does not touch the player's own HUD Visibility setting.

HideComponent

exports['koja-hud']:HideComponent('carhud', true)
exports['koja-hud']:HideComponent('carhud', false)

Valid names: status, carhud, progressbar, notify, textui, informations. Anything else is ignored (and logged with KOJA.Debug = true). The change lasts until the resource restarts; the starting values come from KOJA.HideComponents.

HideComponents

exports['koja-hud']:HideComponents({ status = true, informations = true })

Same names; components not in the table keep their state.

Status effects

Small icons for active effects, each with an optional countdown ring.

{
    id = 'drunk',                    -- unique; adding the same id again updates it
    icon = 'fa-solid fa-wine-bottle',
    color = '#c77dff',               -- optional
    duration = 30                    -- optional, seconds, draws the countdown
}

SetStatusEffects

exports['koja-hud']:SetStatusEffects({
    { id = 'drunk', icon = 'fa-solid fa-wine-bottle', color = '#c77dff', duration = 30 },
    { id = 'cold', icon = 'fa-solid fa-snowflake', color = '#6ab7ff' },
})

Replaces every effect added from code. Built-in effects (sprinting, swimming) are not affected. SetStatusEffects({}) clears them.

AddStatusEffect

exports['koja-hud']:AddStatusEffect({ id = 'cold', icon = 'fa-solid fa-snowflake', color = '#6ab7ff' })

RemoveStatusEffect

exports['koja-hud']:RemoveStatusEffect('cold')

Killfeed

AddKillfeed

exports['koja-hud']:AddKillfeed('Mike_R', 'Alex_92', 'fa-solid fa-gun', 48.0, { headshot = true })
ArgumentTypeNotes
killerstringRequired
victimstringRequired
weaponstringFont Awesome class for the weapon icon. Default 'fa-solid fa-skull'
distancenumberMetres. Optional
opts.headshotbooleanShows the headshot marker
opts.selfbooleanCounts towards this player's killstreak

The entry is dropped if it is further than the player's distance limit, and only shown if the player has the killfeed on (or is in PVP mode). The HUD already adds the player's own kills; use this for everybody else's.

A server-side kill log can broadcast to everyone with the koja_hud:killfeed event.

Stress

The HUD keeps a stress value from 0 to 100 and shows it as a bar. Nothing raises it automatically — your resources decide what is stressful — and it is not saved: it starts at 0 on every join and resource restart.

GetStress

local stress = exports['koja-hud']:GetStress()

To change it, use the koja-hud:addStress and koja-hud:removeStress events.

Seatbelt

IsSeatbeltOn

if exports['koja-hud']:IsSeatbeltOn() then ... end

Always false when KOJA.Seatbelt.Enabled = false.

SeatbeltState

exports['koja-hud']:SeatbeltState(true)

Sets the HUD's seatbelt flag without a notification — for a resource that handles buckling itself and wants the icon and the exit lock to match. Registered only when KOJA.Seatbelt.Enabled = true.

Nitro

GetNitro

local nitro = exports['koja-hud']:GetNitro() -- 0-100

Nitro in the vehicle the player is driving. 0 on foot, as a passenger, or in a vehicle the player does not own.

SetNitro

exports['koja-hud']:SetNitro()

Starts installing nitro in the vehicle directly in front of the player (within about 5 metres). The player must be on foot and own the vehicle, and its tank must be empty. After a five-second animation the tank is filled to 100 and, when KOJA.Nitro.Item is set, one item is removed from the player on the server. Each failure — in a vehicle, no vehicle, not the owner, already installed, no item — shows a notification.

Hook it to a usable item. The HUD removes the item itself, so do not remove it in your handler:

server.lua (ESX)
ESX.RegisterUsableItem('nitro', function(source)
    TriggerClientEvent('my-resource:installNitro', source)
end)
server.lua (QBCore)
QBCore.Functions.CreateUseableItem('nitro', function(source)
    TriggerClientEvent('my-resource:installNitro', source)
end)
client.lua
RegisterNetEvent('my-resource:installNitro', function()
    exports['koja-hud']:SetNitro()
end)

Events

All of these are client events registered as net events, so they can be sent from the server with TriggerClientEvent or from another client script with TriggerEvent.

koja-hud:addStress

TriggerClientEvent('koja-hud:addStress', source, 10)   -- server
TriggerEvent('koja-hud:addStress', 10)                 -- client

Adds to stress, capped at 100.

koja-hud:removeStress

TriggerClientEvent('koja-hud:removeStress', source, 25)

Takes away from stress, never below 0.

koja_hud:killfeed

TriggerClientEvent('koja_hud:killfeed', -1, {
    killer = 'Mike_R',
    victim = 'Alex_92',
    weapon = 'fa-solid fa-gun',
    distance = 48.0,
    headshot = true
})

Same fields as AddKillfeed, plus self.

koja_hud:setStatusEffects

TriggerClientEvent('koja_hud:setStatusEffects', source, {
    { id = 'wanted', icon = 'fa-solid fa-star', color = '#ffc933' }
})

Same as SetStatusEffects.

koja_hud:startTextUI

TriggerClientEvent('koja_hud:startTextUI', source, { input = 'E', type = 'Shop', desc = 'Browse items' })

Same as TextUI.

koja_hud:cancelTextUI

TriggerClientEvent('koja_hud:cancelTextUI', source)

Same as HideUI.

Internal events and callbacks

These exist for the HUD's own use. They are listed so you recognise them in logs; do not call them.

NameKindPurpose
koja_hud:setVehicleNitroserver net eventSaves the nitro left in a vehicle. Only accepts a lower value than stored, and only from the owner
koja_hud:getVehicleNitrokoja-lib server callbackReads a vehicle's nitro for its owner
koja_hud:installNitrokoja-lib server callbackChecks the item and fills the tank

Commands

CommandAvailableDoes
/settingsAlways (KOJA.SettingsCommand)Opens the settings menu
/vehicleWhen KOJA.VehicleMenu.Command is setOpens the vehicle menu while driving
koja_vehiclemenuAlways, bound to UThe key-mapped vehicle menu command
+toggle_engine, +toggle_seatbelt, +toggle_cruisemode, +toggle_nitroWhen each feature is enabledKey-mapped actions, registered through koja-lib
/testnotify [type] [ms]KOJA.Debug = trueSample notifications: success, error, info, warning, or all four
/testprogress [seconds] [label]KOJA.Debug = trueA cancellable progress bar
/testtextui [key] [text]KOJA.Debug = trueA text UI prompt
/hidetextuiKOJA.Debug = trueHides it