Client Exports
HUD Visibility
Show, hide, or toggle the entire HUD at runtime. This is separate from the player-loaded lifecycle — it’s intended for scripts that need to clear the screen (cutscenes, minigames, photo mode, etc.).
exports["bablo-hud"]:ShowHud()
exports["bablo-hud"]:HideHud()
exports["bablo-hud"]:ToggleHud()
-- return: bool - whether the HUD is currently visible
exports["bablo-hud"]:IsHudVisible()Per-Component Visibility
Hide or show individual HUD components. Useful when you only want to suppress part of the HUD (e.g. hide the player info panel during a cutscene but keep the speedometer).
Valid component names:
status, speedometer, playerInfo, minimap, voice,
notifications, progressBar, controlHints
-- component: string - one of the names listed above
-- visible: bool - true to show, false to hide
exports["bablo-hud"]:SetComponentVisible(component, visible)
-- return: bool - whether the component is currently visible
exports["bablo-hud"]:IsComponentVisible(component)Examples:
-- Hide just the player info panel
exports["bablo-hud"]:SetComponentVisible("playerInfo", false)
-- Hide the minimap (also hides the native GTA radar)
exports["bablo-hud"]:SetComponentVisible("minimap", false)
-- Restore the speedometer
exports["bablo-hud"]:SetComponentVisible("speedometer", true)Notifications
Show a notification with a title, body, type and duration.
-- title: string - notification title
-- body: string - notification body text
-- type: string - "primary" | "success" | "error" | "info" | "warning"
-- duration: number - duration in milliseconds
exports["bablo-hud"]:Notify(title, body, type, duration)Progress Bar
Start a progress bar. Accepts an optional callback that fires when the bar
finishes or is cancelled. Bars are either timed (pass duration) or
manual (pass manual = true and drive the value yourself with
UpdateProgressBar).
-- data: table
-- duration: number - duration in milliseconds (required unless manual = true)
-- manual: bool - start at 0% and wait for UpdateProgressBar / CompleteProgressBar (default: false)
-- label: string - label shown on the bar (default: "Processing...")
-- color: string - "primary" | "success" | "error" | "info" | "warning"
-- control: string - key hint shown to the player (e.g. "E")
-- useWhileDead: bool - keep the bar running while the player is dead (default: false)
-- controlDisables: table - input groups to lock while the bar is active:
-- disableMovement: bool
-- disableCarMovement: bool
-- disableMouse: bool
-- disableCombat: bool
-- animation: table - animation to play while the bar is active (optional)
-- -- Option A: native GTA animation
-- animDict: string - animation dictionary
-- anim: string - animation name
-- flags: number - animation flags (default: 1)
-- -- Option B: bablo-animations (requires bablo-animations resource)
-- babloAnim: string - animation name registered in bablo-animations
-- prop_left: table - prop attached to the left hand while the bar is active (optional)
-- model: string - prop model name
-- bone: number - ped bone index (default: 60309)
-- coords: table - position offset { x, y, z }
-- rotation: table - rotation offset { x, y, z }
-- prop_right: table - prop attached to the right hand, same structure as prop_left (optional)
--
-- cb: function(cancelled: bool) - called when the bar finishes or is stopped early
exports["bablo-hud"]:ProgressBar(data, cb)Examples:
-- Simple bar
exports["bablo-hud"]:ProgressBar({ duration = 5000, label = "Searching..." })
-- With bablo-animations and callback
exports["bablo-hud"]:ProgressBar({
duration = 8000,
label = "Picking lock...",
animation = { babloAnim = "lockpick" },
controlDisables = { disableMovement = true, disableCombat = true },
}, function(cancelled)
if not cancelled then
-- success
end
end)
-- With native animation and props on both hands
exports["bablo-hud"]:ProgressBar({
duration = 8000,
label = "Repairing...",
color = "success",
controlDisables = { disableMovement = true, disableCombat = true },
animation = {
animDict = "mini@repair",
anim = "fixing_a_ped",
flags = 49,
},
prop_left = {
model = "prop_tool_wrench",
bone = 28422, -- PH_L_Hand
coords = { x = 0.0, y = 0.0, z = 0.0 },
rotation = { x = 0.0, y = 0.0, z = 0.0 },
},
prop_right = {
model = "prop_tool_screwdvr01",
bone = 60309, -- PH_R_Hand
coords = { x = 0.0, y = 0.0, z = 0.0 },
rotation = { x = 0.0, y = 0.0, z = 0.0 },
},
}, function(cancelled)
if not cancelled then
-- repair complete
end
end)Update Progress Bar
Update the value and/or label of the running progress bar. Intended for manual bars driven by repeated player actions (no fixed duration), but the label update also works on timed bars.
-- value: number - progress 0-100 (optional)
-- label: string - new label (optional)
exports["bablo-hud"]:UpdateProgressBar(value, label)
-- table form; either field may be omitted
exports["bablo-hud"]:UpdateProgressBar({ value = 40, label = "Digging 2/5" })Reaching 100 on a manual bar completes it automatically (callback fires
with cancelled = false).
Example — a bar that advances per action:
local hits, needed = 0, 5
exports["bablo-hud"]:ProgressBar({
manual = true,
label = "Digging 0/5",
controlDisables = { disableCombat = true },
}, function(cancelled)
if not cancelled then
-- finished digging
end
end)
RegisterCommand("dig", function()
hits = hits + 1
exports["bablo-hud"]:UpdateProgressBar((hits / needed) * 100, ("Digging %d/%d"):format(hits, needed))
end, false)Complete Progress Bar
Finish the running progress bar immediately (fills to 100%). If a callback
was provided to ProgressBar, it fires with cancelled = false.
exports["bablo-hud"]:CompleteProgressBar()Stop Progress Bar
Stops the current progress bar immediately. If a callback was provided to
ProgressBar, it will fire with cancelled = true.
exports["bablo-hud"]:StopProgressBar()The progress bar can also be controlled with client events:
bablo-hud:progressbar:start (duration, label, color, control),
bablo-hud:progressbar:update (value, label),
bablo-hud:progressbar:complete and bablo-hud:progressbar:stop.
Control Hints
Push key + label prompts into the Control Hints panel at runtime, alongside
the static list from Config.ControlHints.hints. Each hint has a stable
id: showing the same id again updates it in place and restarts its
timer. Requires Config.ControlHints.enabled = true.
-- hints: table - one hint { id, label, key, duration? } or a list of them
-- id: string - unique key for this hint
-- label: string - text shown next to the key
-- key: string - key name shown in the key badge (e.g. "E")
-- duration: number - optional auto-hide time in ms for this hint
-- duration: number - optional shared auto-hide time in ms for the whole list
exports["bablo-hud"]:ShowControlHints(hints, duration)
-- positional form for a single hint
exports["bablo-hud"]:ShowControlHint(id, label, key, duration)
-- ids: string | table - one id, a list of ids, or the hint tables you passed in
exports["bablo-hud"]:HideControlHints(ids)
-- remove every script-pushed hint (config hints stay)
exports["bablo-hud"]:ClearControlHints()Examples:
-- Show a set of hints for 5 minutes; one of them disappears after 30 seconds
exports["bablo-hud"]:ShowControlHints({
{ id = "race_join", label = "Join Race", key = "E" },
{ id = "race_leave", label = "Leave Race", key = "H" },
{ id = "race_map", label = "Show Route", key = "M", duration = 30000 },
}, 5 * 60000)
-- Single hint that stays until hidden
exports["bablo-hud"]:ShowControlHint("trunk", "Open Trunk", "E")
exports["bablo-hud"]:HideControlHint("trunk")
-- Hide several at once
exports["bablo-hud"]:HideControlHints({ "race_join", "race_leave" })The same calls are available as client events, which also makes them usable
from the server via TriggerClientEvent:
bablo-hud:controlhint:show (hints, duration), bablo-hud:controlhint:hide (ids),
bablo-hud:controlhint:clear.
-- server side
TriggerClientEvent("bablo-hud:controlhint:show", src, {
{ id = "event_join", label = "Join Event", key = "E" },
}, 300000)Refresh Player Info
Rebuild the Player Info snapshot (job, money, dirty money, gang, ID, weapon) immediately instead of waiting for the next tick. Useful right after a change in a script the HUD reads through the framework bridge (see Framework Bridge).
-- return: bool - false if the HUD is not active yet
exports["bablo-hud"]:RefreshPlayerInfo()Also available as the client event bablo-hud:playerinfo:refresh.
HUD Offset
Move HUD elements out of the way of another interface — typically a phone — and put them back afterwards. Nothing is saved: offsets are cleared on restart, on reconnect, when the calling resource stops, and when a player opens Edit Mode, so a stuck offset can never become part of someone’s layout.
-- push everything near one screen edge inward
-- return: bool - false if Config.HudOffset.enabled = false
exports["bablo-hud"]:SetHudOffset("bottom", 320) -- screen pixels
exports["bablo-hud"]:SetHudOffset("bottom", "38vh") -- % of screen height
exports["bablo-hud"]:SetHudOffset("bottom", 0) -- release this side
-- several edges at once (a corner-docked phone)
exports["bablo-hud"]:SetHudOffset({ bottom = "38vh", right = "22vw" })
-- release everything this resource asked for
exports["bablo-hud"]:ClearHudOffset()
-- read what is currently applied: { top = 0, right = 0, bottom = 320, left = 0 }
exports["bablo-hud"]:GetHudOffset()
-- alias for SetHudOffset("bottom", px), for scripts written against other HUDs
exports["bablo-hud"]:SetPhoneHeight(320)Also available as client events, for non-Lua callers or load-order safety:
bablo-hud:hudoffset:set (same arguments) and bablo-hud:hudoffset:clear.
Sizes accept a number (screen pixels), or a string in vh, vw, % or
px. Phones size themselves in vh, so the string form is usually the
accurate one. No side may take more than Config.HudOffset.maxFraction of
its axis (45% by default) — larger requests are clamped rather than rejected.
Only moving part of the HUD
By default an offset affects everything near that edge, which will also move
elements on the far side of the screen. Add an area to restrict it to the
region the phone actually covers:
-- a phone in the bottom-right: lift only the right-hand elements,
-- leave the status icons on the left exactly where they are
exports["bablo-hud"]:SetHudOffset({
bottom = "38vh",
area = { right = "30vw" },
})area uses the same side vocabulary and describes the region inward from
those edges, so { right = "30vw" } is the right-hand 30% of the screen and
{ right = "30vw", bottom = "60vh" } is just that corner. Elements outside
the area are never touched.
Everything inside the area moves by the same amount, so the spacing between elements is preserved and they cannot land on top of each other.
Example — a phone
-- lb-phone publishes a `phoneOpen` state bag, so no polling is needed
CreateThread(function()
local bag = ("player:%s"):format(GetPlayerServerId(PlayerId()))
AddStateBagChangeHandler("phoneOpen", bag, function(_, _, open)
if open then
exports["bablo-hud"]:SetHudOffset({ bottom = "38vh", area = { right = "30vw" } })
else
exports["bablo-hud"]:ClearHudOffset()
end
end)
end)Built-in phone integration
You usually don’t need to write any of the above. Turn on
Config.HudOffset.phone and the HUD follows the phone by itself:
Config.HudOffset = {
enabled = true,
maxFraction = 0.45, -- no side may take more than 45% of its axis
moveMinimap = false, -- also slide the real GTA radar
phone = {
enabled = true,
resource = "auto", -- or "lb-phone" / "roadphone" / "gksphone"
offset = { bottom = "38vh" }, -- how far to push while the phone is open
area = { right = "30vw" }, -- which part of the screen is affected
pollInterval = 400, -- only used by phones without a state bag
-- shift briefly while a phone notification is on screen
notification = {
enabled = true,
offset = { bottom = "18vh" },
area = { right = "30vw" },
duration = 5000, -- ms to hold after each notification
},
},
}resource = "auto" picks whichever supported phone is running. lb-phone
is driven by its phoneOpen state bag, so it reacts instantly with no
polling; the others are polled every pollInterval ms. Nothing inside the
phone resource is modified.
Tune offset until the phone stops covering your HUD, and area so only the
side the phone sits on moves. Two commands help while tuning:
/hudphonetest sends a real phone notification, and
/hudoffsettest bottom 24vh applies a shift by hand
(/hudoffsettest off clears it).
Write your own integration only for a phone the HUD does not recognise.
Each resource holds its own offset and the largest wins per side, so two
scripts cannot cancel each other out, and one closing its UI never releases
another’s offset. /hudoffsetreset clears everything if a script forgets.
Vehicle Control Panel
Open, close or toggle the Vehicle Control panel (the same panel players open
with the M keybind or /carcontrol). Follows the same rules as the keybind:
it does nothing when Config.VehicleControl.enabled = false, and unless
Config.VehicleControl.allowOnFoot = true it only opens while the player is
inside a vehicle (the player gets the usual warning notification otherwise).
-- return: bool - true if the panel was opened
exports["bablo-hud"]:OpenVehicleControl()
-- return: bool - true if the panel was open and is now closed
exports["bablo-hud"]:CloseVehicleControl()
-- return: bool - the new state (true = opened, false = closed)
exports["bablo-hud"]:ToggleVehicleControl()
-- return: bool - whether the panel is currently open
exports["bablo-hud"]:IsVehicleControlOpen()The same actions are available as client events (also usable from the server
with TriggerClientEvent):
bablo-hud:vehiclecontrol:open, bablo-hud:vehiclecontrol:close,
bablo-hud:vehiclecontrol:toggle.
-- e.g. from a keys/interaction script
if exports["bablo-hud"]:IsVehicleControlOpen() then
exports["bablo-hud"]:CloseVehicleControl()
else
exports["bablo-hud"]:OpenVehicleControl()
endCinematic Mode
Toggle, set, or query the cinematic letterbox mode.
-- active: bool - whether cinematic mode is active
exports["bablo-hud"]:SetCinematic(active)
exports["bablo-hud"]:ToggleCinematic()
-- return: bool - whether cinematic mode is currently active
exports["bablo-hud"]:IsCinematicActive()Seatbelt
Toggle the seatbelt or check the current state. Requires Config.Seatbelt.enabled = true.
exports["bablo-hud"]:ToggleSeatbelt()
-- return: bool - whether the seatbelt is fastened
exports["bablo-hud"]:IsSeatbeltOn()Stress System
Read and write the integrated stress value. Requires Config.Stress.integrated = true.
-- return: number - current stress value (0-100)
exports["bablo-hud"]:GetStress()
-- value: number - new stress value (clamped to config min/max)
exports["bablo-hud"]:SetStress(value)
-- amount: number - amount to add
exports["bablo-hud"]:AddStress(amount)
-- amount: number - amount to remove
exports["bablo-hud"]:RemoveStress(amount)Minimap
Utilities to work with the styled minimap.
-- return: table - x, y, w, h anchor of the minimap in screen space
exports["bablo-hud"]:getAnchor()
-- visible: bool - show or hide the native radar
exports["bablo-hud"]:setRadarVisible(visible)
