Events & Exports
Client Events
lua
-- Money update (sent from server when balance changes)
RegisterNetEvent('orb_customs:updatePlayerMoney', function(newMoney)
-- Updates the money display in the NUI
end)Server Callbacks (ox_lib)
All server communication uses lib.callback from ox_lib:
lua
-- Check if player can afford a modification and charge them
-- Returns: boolean (true if purchase successful)
lib.callback.register('orb_customs:canAffordMod', function(source, amount)
-- Validates player, checks balance, removes money
end)
-- Get player's current money balance
-- Returns: number
lib.callback.register('orb_customs:getPlayerMoney', function(source)
-- Returns money via Bridge.GetPlayerMoney()
end)
-- Enter customs (assigns routing bucket)
-- Returns: boolean (true if bucket available)
lib.callback.register('orb_customs:enterCustoms', function(source)
-- Validates player is in vehicle, assigns bucket
end)
-- Exit customs (releases routing bucket)
-- Returns: boolean
lib.callback.register('orb_customs:exitCustoms', function(source)
-- Resets player and vehicle to bucket 0
end)
-- Save vehicle properties to database
-- Returns: boolean
lib.callback.register('orb_customs:saveVehicle', function(source, plate, props)
-- Validates and saves via Bridge.SaveVehicleProperties()
end)NUI Callbacks
These are internal callbacks between the React UI and Lua:
| Callback | Direction | Purpose |
|---|---|---|
hideFrame | UI → Lua | Close the customs menu |
setMenu | UI → Lua | Navigate menu / select category |
applyMod | UI → Lua | Preview a modification |
buyMod | UI → Lua | Purchase a modification |
toggleMod | UI → Lua | Toggle a mod (turbo, custom tires) |
customsLoaded | UI → Lua | Signal that NUI has finished loading |
cameraHandle | UI → Lua | Send mouse movement for camera rotation |
getPlayerMoney | UI → Lua | Request current money balance |
getVehicleStats | UI → Lua | Request vehicle performance stats |
updateStanceValue | UI → Lua | Apply stance preview value |
applyStance | UI → Lua | Purchase stance modifications |
cancelStance | UI → Lua | Cancel stance preview and revert |
State Bag
Engine sound synchronization uses FiveM state bags:
lua
-- Set engine sound (syncs across all clients)
Entity(vehicle).state['vehdata:sound'] = soundHash
-- Listen for engine sound changes
AddStateBagChangeHandler('vehdata:sound', nil, function(bagName, _, value)
local entity = GetEntityFromStateBagName(bagName)
if entity == 0 or not IsEntityAVehicle(entity) then return end
ForceUseAudioGameObject(entity, value)
end)Bridge API
The bridge exposes these functions for framework integration. If you need to extend the bridge for a custom framework, implement these functions:
Server-Side
lua
-- Get player's money balance
-- @param source number - Player server ID
-- @return number - Money amount
Bridge.GetPlayerMoney(source)
-- Remove money from player
-- @param source number - Player server ID
-- @param amount number - Amount to remove
-- @param reason string - Transaction reason
-- @return boolean - Success
Bridge.RemoveMoney(source, amount, reason)
-- Save vehicle properties to database
-- @param plate string - Vehicle plate
-- @param props table - Vehicle properties table
-- @return boolean - Success
Bridge.SaveVehicleProperties(plate, props)Adding a Custom Framework
To add support for a framework not included, create a new file in bridge/server/ and implement the three bridge functions. The framework is detected in bridge/_detect.lua — add your resource name to the frameworks table:
lua
local frameworks = {
['qbx_core'] = 'qbox',
['qb-core'] = 'qbcore',
['es_extended'] = 'esx',
['your_core'] = 'your_framework', -- Add here
}Then in bridge/server/framework.lua, add a new elseif block:
lua
elseif Bridge.Framework == 'your_framework' then
function Bridge.GetPlayerMoney(source)
-- Your implementation
end
function Bridge.RemoveMoney(source, amount, reason)
-- Your implementation
end
function Bridge.SaveVehicleProperties(plate, props)
-- Your implementation
end