Onboarding
Configure automatic, manual, or disabled onboarding and integrate it with character, spawn, and tutorial flows.
Onboarding
Orbit Dynamic HUD 2.0 can start onboarding automatically for a new player, wait for another resource to trigger it, or disable it completely. Completion is remembered by the NUI, while the backend configuration remains authoritative over whether onboarding is available.
Configuration
Use the object form in shared/config.lua:
Config.Onboarding = {
enabled = true,
trigger = "auto", -- "auto" or "manual"
}
Config.Commands = {
controlpanel = { enabled = true },
customize = { enabled = true },
music = { enabled = true },
carcontrol = { enabled = true },
settings = { enabled = true },
settingsshare = { enabled = true },
editmode = { enabled = true },
restarthud = { enabled = true },
engine = { enabled = true },
onboarding = { enabled = true },
}| Setting | Value | Effect |
|---|---|---|
enabled | true | Allow onboarding to start through the configured mode, public event, export, and optionally its command. |
enabled | false | Disable onboarding starts completely. Public start calls remain safe no-ops and the command is not registered. |
trigger | "auto" | Show onboarding automatically when an incomplete first run is ready. |
trigger | "manual" | Keep an incomplete first run hidden until another resource triggers it. |
Config.Commands.onboarding.enabled | true | Register the localized /onboarding command. |
Config.Commands.onboarding.enabled | false | Disable only the command. The public event remains available while onboarding itself is enabled. |
The legacy boolean form is still accepted for compatibility: true means enabled with automatic triggering, while false disables onboarding. The object form is recommended because it exposes the trigger mode explicitly.
Settings lock takes priority
Config.SettingsLocked = true blocks onboarding regardless of its own configuration. This prevents onboarding from replacing server-enforced defaults.
Automatic mode
Config.Onboarding = {
enabled = true,
trigger = "auto",
}Automatic mode is appropriate when DynamicHUD can own the first-run flow. For an incomplete first run, the client waits until:
- normalized player data reports that the player is logged in
- another NUI is not holding focus
- the built-in Text UI is not already showing a prompt owned by another resource
Once those conditions are met, a localized Text UI notice counts down from five seconds. Only an uninterrupted five-second availability window counts. If another NUI takes focus or another Text UI prompt appears, DynamicHUD hides only its own notice, resets the timer, and waits. The notice and full five-second countdown start again when the interface is free.
Translate the notice with the onboarding_countdown key in every enabled locales/*.json file. Keep the %d placeholder in the translated value; it is replaced with the current remaining second.
The countdown cannot mature in a character selector because it starts only after the normalized logged-in state becomes true. The availability watcher runs only for the initial incomplete automatic flow. Opening onboarding later through the command, event, or export bypasses both the watcher and countdown and requests focus directly.
Players who already completed onboarding do not see it automatically again.
Manual mode
Config.Onboarding = {
enabled = true,
trigger = "manual",
}Manual mode keeps first-run onboarding dormant until your login, character, spawn, or tutorial resource decides the player is ready. Trigger it after the player has loaded and the DynamicHUD client resource has initialized.
Trigger from a client resource
RegisterNetEvent("my-intro:client:finished", function()
TriggerEvent("orbit-dynamichud:client:openOnboarding")
end)The equivalent client export returns whether the request passed the local configuration and login guards:
local requested = exports['orbit-dynamichud-v2']:startOnboarding()Trigger from a server resource
local function finishPlayerSetup(playerSource)
TriggerClientEvent(
"orbit-dynamichud:client:openOnboarding",
playerSource
)
endThe event is intentionally non-forcing. It opens onboarding only when that client still has an incomplete onboarding state. Triggering it for somebody who already finished onboarding does nothing, so a server event cannot overwrite a completed player's choice.
Use manual mode when:
- a multicharacter resource must finish character selection first
- identity, apartment, or spawn selection owns the initial focus
- a server tutorial or cutscene should finish before HUD configuration
- the player starts in a routing bucket and should configure the HUD after leaving it
- framework data is not ready at the moment the HUD resource starts
Avoid triggering the event every tick or on every respawn. Call it once at the meaningful completion point in your flow. The completed-state check makes duplicate calls harmless, but they are still unnecessary work.
Command and event behavior
| Entry point | Reopens completed onboarding | Starts automatic watcher | Requirements |
|---|---|---|---|
| Initial automatic run | No | Yes | enabled = true, trigger = "auto", incomplete state, settings unlocked |
orbit-dynamichud:client:openOnboarding | No | No | enabled = true, incomplete state, settings unlocked |
startOnboarding export | No | No | enabled = true, incomplete state, player logged in, settings unlocked |
/onboarding | Yes | No | onboarding enabled, command enabled, settings unlocked |
The localized /onboarding command is the support and testing path. It deliberately forces the flow open even after completion, but it does not change automatic/manual mode and does not create a background onboarding thread.
Query or close onboarding
Read the current state and close the flow from a client resource with exports:
local onboardingState = exports['orbit-dynamichud-v2']:getOnboardingState()
if onboardingState then
exports['orbit-dynamichud-v2']:closeOnboarding()
endThe event form is suitable for both client and targeted server integrations:
TriggerEvent('orbit-dynamichud:client:closeOnboarding')TriggerClientEvent(
'orbit-dynamichud:client:closeOnboarding',
playerSource
)Closing is idempotent. It resets the onboarding flow in the NUI and releases focus only when onboarding is the interface using it. Use getHudVisibility() when another client resource also needs the gameplay HUD's current effective visibility.
Recommended manual integration
- Set
Config.Onboarding.trigger = "manual". - Keep
Config.Onboarding.enabled = true. - Decide which existing resource owns the last step before normal gameplay.
- Trigger
orbit-dynamichud:client:openOnboardingonce after that step and after player data is loaded. - Keep
/onboardingenabled while testing, then decide whether players should retain that recovery command. - Test both a fresh client state and a client that already completed onboarding.
If the manual event does not open anything, verify that onboarding is enabled, settings are not locked, the player has not already completed onboarding, and the event is fired after orbit-dynamichud-v2 starts. Use /onboarding to distinguish a completed-state no-op from a configuration or focus problem.