Browse docs

External Nitro HUD

Connect an external HUD to Nitro state, consumption, bottle data, and live client updates.

Sky Mechanic Job exposes the local player's Nitro state through client exports and a live client event. An external HUD can therefore display the remaining amount, percentage, bottle count, current consumption, and boost state without reading internal resource data.

The public API remains active when the built-in Nitro HUD is disabled.

1. Disable the built-in Nitro HUD

Set enabled = false inside Config.Nitro.hud in config/adv_config.lua:

Config.Nitro = {
    -- Keep the rest of your Nitro configuration here.
    externalUpdateIntervalMs = 100,
    hud = {
        enabled = false,
        position = {
            left = "50%",
            top = "3vh"
        }
    }
}

externalUpdateIntervalMs controls how frequently consumption changes may be sent to external listeners. The minimum runtime value is 16 milliseconds. A value between 50 and 150 is suitable for most HUDs.

Disabling Config.Nitro.hud.enabled only hides the built-in display. Installation, activation, consumption, persistence, effects, exports, and live external updates continue to work.

2. Add the resource dependency

Add Sky Mechanic Job to the external HUD's fxmanifest.lua:

dependency "sky_mechanicjob"

This ensures that the Nitro exports are registered before the HUD resource starts.

3. Read the initial state

Call GetNitroState() when the HUD starts. With no argument, it uses the local player's current vehicle. A vehicle entity can be passed when another specific vehicle must be queried.

local function updateNitroHud(nitro)
    SendNUIMessage({
        action = "hud:setNitro",
        data = {
            visible = nitro.installed,
            active = nitro.active,
            percent = nitro.percent,
            level = nitro.level,
            capacity = nitro.capacity,
            bottles = nitro.bottles,
            maxBottles = nitro.maxBottles,
            consumptionPerSecond = nitro.consumptionPerSecond
        }
    })
end

CreateThread(function()
    Wait(0)
    updateNitroHud(exports["sky_mechanicjob"]:GetNitroState())
end)

Reading the initial state is important because a state event may have occurred before the external HUD registered its event handler.

4. Listen for live updates

Listen to sky_mechanicjob:nitroStateChanged in the external HUD's client script:

AddEventHandler("sky_mechanicjob:nitroStateChanged", function(nitro)
    updateNitroHud(nitro)
end)

The event is local to the client. It is emitted when Nitro state is loaded, activated, consumed, stopped, emptied, or changed during the relevant vehicle lifecycle. Do not register it as a server event and do not forward the high-frequency consumption updates through the server.

Complete client example

local function sendNitroState(nitro)
    SendNUIMessage({
        action = "hud:setNitro",
        data = {
            visible = nitro.vehicle ~= 0 and nitro.installed,
            active = nitro.active,
            priming = nitro.priming,
            percent = math.floor(nitro.percent + 0.5),
            level = nitro.level,
            capacity = nitro.capacity,
            bottles = nitro.bottles,
            maxBottles = nitro.maxBottles,
            bottleLevels = nitro.bottleLevels,
            boost = nitro.boost,
            consumptionPerSecond = nitro.consumptionPerSecond
        }
    })
end

AddEventHandler("sky_mechanicjob:nitroStateChanged", function(nitro)
    sendNitroState(nitro)
end)

CreateThread(function()
    Wait(0)
    sendNitroState(exports["sky_mechanicjob"]:GetNitroState())
end)

Payload reference

FieldTypeDescription
vehiclenumberLocal vehicle entity, or 0 when no relevant vehicle exists
netIdnumberVehicle network ID, or 0
platestringNormalized vehicle plate
installedbooleanWhether usable Nitro is installed
activebooleanWhether Nitro is currently boosting and consuming
primingbooleanWhether the Nitro start or purge phase is active
boostnumberCurrent boost blend from 0.0 to 1.0
levelnumberTotal remaining Nitro amount
capacitynumberCurrent total capacity of non-empty bottles
percentnumberRemaining amount from 0.0 to 100.0
bottlesnumberNumber of non-empty bottles
maxBottlesnumberConfigured bottle limit
bottleCapacitynumberConfigured capacity of one bottle
bottleLevelstableRemaining amount in each bottle
drainPerSecondnumberConfigured maximum consumption per second
consumptionPerSecondnumberCurrent consumption per second; 0 while inactive

Optional polling and boolean checks

Event-driven updates are recommended for HUD rendering. The exports can also be polled or used for simple conditions:

local vehicle = GetVehiclePedIsIn(PlayerPedId(), false)
local nitro = exports["sky_mechanicjob"]:GetNitroState(vehicle)
local installed = exports["sky_mechanicjob"]:HasNitro(vehicle)
local active = exports["sky_mechanicjob"]:IsNitroActive(vehicle)

Avoid polling every frame. When polling is required, an interval around 250 milliseconds is normally sufficient.

Testing checklist

  • Confirm the built-in Nitro HUD stays hidden with Config.Nitro.hud.enabled = false.
  • Enter a vehicle with and without Nitro and verify the external HUD visibility.
  • Activate Nitro and verify active, boost, level, percent, and consumptionPerSecond update.
  • Release the activation key and verify consumption returns to 0.
  • Empty a bottle and verify bottle and capacity values update.
  • Leave the vehicle and verify the external HUD hides.
  • Restart the HUD while already inside a Nitro vehicle and verify the initial export restores the display.