# Events and State Bags (/docs/orbit-studios-resources/orbit-dynamichud/events)



# Events and State Bags [#events-and-state-bags]

Use exports for direct client integrations when one exists. Events are provided for compatibility bridges, server-to-client UI calls, configurable phone hooks, and common framework resources. State bags are preferred for continuously owned gameplay state because they replicate and survive resource boundaries cleanly.

## Public events [#public-events]

| Event                                      | Context              | Parameters                | Purpose                                                                             |
| ------------------------------------------ | -------------------- | ------------------------- | ----------------------------------------------------------------------------------- |
| `orbit-dynamichud:notify`                  | client               | `data`                    | Show a notification. May be sent with `TriggerClientEvent` from the server.         |
| `orbit-dynamichud:showTextUI`              | client               | `text, options?`          | Show or replace Text UI. May be sent with `TriggerClientEvent`.                     |
| `orbit-dynamichud:hideTextUI`              | client               | none                      | Hide Text UI. May be sent with `TriggerClientEvent`.                                |
| `orbit-dynamichud:openControlPanel`        | client               | `category?, subcategory?` | Open the control panel, optionally at an enabled page.                              |
| `orbit-dynamichud:client:openOnboarding`   | client               | none                      | Open an incomplete onboarding flow; intended for manual onboarding integrations.    |
| `orbit-dynamichud:client:closeOnboarding`  | client               | none                      | Close the current onboarding flow and clear its onboarding state and focus.         |
| `hud:server:toggleHud`                     | server network event | `visible`                 | Set the calling player's replicated HUD visibility. Client export use is preferred. |
| `orbit-dynamichud:standalone:playerLoaded` | client               | none                      | Tell a standalone installation to reload normalized player data after login.        |
| `orbit-dynamichud:progressBarOver`         | local client event   | `result`                  | Observe a progress-bar NUI result. The blocking export return is preferred.         |
| `orbit-dynamichud:skillCheckOver`          | local client event   | `result`                  | Observe a skill-check NUI result. The blocking export return is preferred.          |

See [Interface APIs](/docs/orbit-studios-resources/orbit-dynamichud/interface) for notification, Text UI, progress bar, and skill-check payloads.

## Trigger and close onboarding [#trigger-and-close-onboarding]

From another client resource:

```lua title="resources/[custom]/client/main.lua"
TriggerEvent('orbit-dynamichud:client:openOnboarding')
```

Close the current flow from another client resource:

```lua title="resources/[custom]/client/main.lua"
TriggerEvent('orbit-dynamichud:client:closeOnboarding')
```

From the server, target the player after your character, spawn, or tutorial flow is complete:

```lua title="resources/[custom]/server/main.lua"
TriggerClientEvent(
    'orbit-dynamichud:client:openOnboarding',
    source
)

-- The same event can be targeted later if an external flow must close it.
TriggerClientEvent(
    'orbit-dynamichud:client:closeOnboarding',
    source
)
```

The open event never forces onboarding onto a client that already completed it. Start requests are ignored when onboarding is disabled or settings are locked, and manual starts do not create the automatic first-run polling thread. The close event is idempotent and may be called even when onboarding is already closed. Prefer the matching `startOnboarding` and `closeOnboarding` client exports when integrating from another local resource. See [Onboarding](/docs/orbit-studios-resources/orbit-dynamichud/onboarding) for the complete mode and lifecycle guide.

## Open a control-panel page [#open-a-control-panel-page]

```lua title="resources/[custom]/client/main.lua"
TriggerEvent('orbit-dynamichud:openControlPanel', 'customize', 'shape_selector')
```

From a server script, target the player:

```lua title="resources/[custom]/server/main.lua"
TriggerClientEvent(
    'orbit-dynamichud:openControlPanel',
    source,
    'settings',
    'audio'
)
```

Supported category and subcategory IDs are:

| Category         | Subcategories                                                                                       |
| ---------------- | --------------------------------------------------------------------------------------------------- |
| `customize`      | `color_picker`, `status_selector`, `shape_selector`, `player_info_selector`, `speedometer_selector` |
| `music`          | `play`, `playlists`, `music_settings`                                                               |
| `car_control`    | none                                                                                                |
| `settings_share` | none                                                                                                |
| `settings`       | `display`, `audio`, `performance_settings`, `edit_mode`, `panel_theme`                              |

The requested category and subcategory must be enabled by `Config.ControlPanel`. The car-control category opens only while the player is in a vehicle. Settings Share does not open while settings are locked or its launcher is disabled. Omitting IDs opens the normal/default control-panel page.

## Phone open and close events [#phone-open-and-close-events]

The event names are configurable in `Config.PhoneOffset`:

```lua title="resources/[orbit]/orbit-dynamichud-v2/shared/config.lua"
Config.PhoneOffset = {
    enabled = true,
    side = 'right',
    offset = 18.0,
    openEvent = 'orbit-dynamichud:phoneOpened',
    closeEvent = 'orbit-dynamichud:phoneClosed'
}
```

Trigger the configured events from the phone resource:

```lua title="resources/[phone]/client/main.lua"
TriggerEvent('orbit-dynamichud:phoneOpened', 'right')
TriggerEvent('orbit-dynamichud:phoneClosed')
```

The open payload may be `"left"`, `"right"`, or a table with `side` or `position`. A valid payload overrides the configured side for that opening. The events are registered as network events, so server resources may target a client when necessary.

## Framework compatibility events [#framework-compatibility-events]

These events exist for compatibility with common ESX, QB, and QBX resources. New standalone integrations should prefer the state bags in the next section.

| Event                            | Parameters                 | Behavior                                                                                    |
| -------------------------------- | -------------------------- | ------------------------------------------------------------------------------------------- |
| `esx:setAccountMoney`            | `account`                  | Updates `money`, `bank`, `black_money`, or `dirty` from `account.name` and `account.money`. |
| `esx_status:onTick`              | `statuses`                 | Reads hunger and thirst percentages from the ESX status array.                              |
| `hud:client:OnMoneyChange`       | `account, amount, isMinus` | Applies a cash, bank, dirty, or black-money delta.                                          |
| `hud:client:UpdateNeeds`         | `hunger, thirst`           | Replaces QB/QBX needs values.                                                               |
| `hud:client:UpdateStress`        | `stress`                   | Replaces the stress value.                                                                  |
| `QBCore:Client:OnPlayerLoaded`   | none                       | Reloads normalized HUD player data after the QB player is ready.                            |
| `esx:onPlayerSpawn`              | `xPlayer, skin`            | Reloads normalized HUD player data after an ESX spawn.                                      |
| `seatbelt:client:ToggleSeatbelt` | none                       | Re-reads the local `seatbelt` or `harness` state.                                           |
| `seatbelt:client:ToggleCruise`   | none                       | Toggles the compatibility cruise value. A `cruiseControl` state bag is preferred.           |
| `hud:client:UpdateNitrous`       | `unused, level, active`    | Deprecated QB-style nitrous update. Vehicle state bags are preferred.                       |

```lua title="resources/[custom]/client/needs.lua"
TriggerEvent('hud:client:UpdateNeeds', 82, 64)
TriggerEvent('hud:client:UpdateStress', 15)
```

## State bags [#state-bags]

### Player state [#player-state]

| Key                      | Value            | Purpose                                                      |
| ------------------------ | ---------------- | ------------------------------------------------------------ |
| `hud:showHud`            | `boolean`        | Master HUD visibility.                                       |
| `hud:deathState`         | `1`, `2`, or `3` | `1` alive, `2` last stand, `3` dead.                         |
| `hunger`                 | `number`         | Hunger percentage/value.                                     |
| `thirst`                 | `number`         | Thirst percentage/value.                                     |
| `stress`                 | `number`         | Stress percentage/value.                                     |
| `invOpen`                | `boolean`        | Hides the HUD while an inventory is open.                    |
| `seatbelt`               | `boolean`        | Seatbelt indicator.                                          |
| `harness`                | `boolean`        | Compatibility fallback read with seatbelt state.             |
| `cruiseControl`          | `boolean`        | Cruise-control indicator.                                    |
| `qbx_medical:deathState` | framework value  | Mirrored into `hud:deathState` by the QBX bridge.            |
| `proximity`              | table            | Reads the pma-voice-compatible `mode` value for voice range. |
| `disableRadio`           | number           | pma-voice-compatible radio availability state.               |
| `radioChannel`           | number           | Current pma-voice-compatible radio channel.                  |

Set authoritative player state on the server with replication enabled:

```lua title="resources/[custom]/server/main.lua"
Player(source).state:set('hud:deathState', 2, true)
Player(source).state:set('stress', 35, true)
Player(source).state:set('hud:showHud', true, true)
```

A client-owned vehicle resource can update its local state when appropriate:

```lua title="resources/[custom]/client/seatbelt.lua"
LocalPlayer.state:set('seatbelt', true, true)
LocalPlayer.state:set('cruiseControl', false, true)
```

Do not write unchanged state every frame. Update only when the value changes.

### Vehicle state [#vehicle-state]

DynamicHUD reads these state bags from the current vehicle:

| Key           | Value     | Purpose                                                                                          |
| ------------- | --------- | ------------------------------------------------------------------------------------------------ |
| `nitro`       | `number`  | Current nitrous level.                                                                           |
| `nitroFlames` | `boolean` | Whether nitrous is actively firing.                                                              |
| `hasNeons`    | `table`   | Installed neon sides used by Car Control (`neonLeft`, `neonRight`, `neonFront`, and `neonBack`). |

```lua title="resources/[custom]/client/nitrous.lua"
local vehicle = cache.vehicle
if vehicle then
    Entity(vehicle).state:set('nitro', 75, true)
    Entity(vehicle).state:set('nitroFlames', true, true)
end
```

DynamicHUD checks that the changed vehicle matches the player's current vehicle before updating the speedometer.

### Global state [#global-state]

DynamicHUD publishes server population values for its own player-count UI. Other resources may read them without polling `GetPlayers()`:

| Key                          | Value    | Purpose                                                    |
| ---------------------------- | -------- | ---------------------------------------------------------- |
| `GlobalState.currentPlayers` | `number` | Current connected player count.                            |
| `GlobalState.maxPlayers`     | `number` | `sv_maxclients`, initialized when the HUD resource starts. |

These values are outputs owned by DynamicHUD. Do not overwrite them from another resource.

## Inventory and death handlers [#inventory-and-death-handlers]

For inventories that publish `invOpen`, no extra hide/show event is needed. Otherwise, use the server `toggleHud` export in your inventory's server handlers:

```lua title="resources/[custom]/server/inventory.lua"
AddEventHandler('my_inventory:opened', function(source)
    exports['orbit-dynamichud-v2']:toggleHud(source, false)
end)

AddEventHandler('my_inventory:closed', function(source)
    exports['orbit-dynamichud-v2']:toggleHud(source, true)
end)
```

For custom medical resources, set `hud:deathState` rather than calling internal NUI events.

The editable `server/handlers.lua` file contains starter hooks for common inventory, QB hospital, and ESX death events. Event names and signatures vary between resource versions, so keep only the handlers that match your server and adapt them to the state/export patterns above.

## Internal events [#internal-events]

Sound synchronization, Settings Share callbacks, car-control status, NUI callbacks, and `orbit-dynamichud:client:updateSound` are internal implementation details. Do not call them from third-party resources. Their payloads are validated for the owning UI flow and can change without being part of the public API.
