Skip to main content
The bridge files are intentionally left outside the escrow encrypted set — escrow_ignore in fxmanifest.lua covers bridge/*.lua, so you can plug in ND_Core, ox_core, or a fully custom framework without source access to the rest of the resource.

Bridge API

bridge/server.lua is the single integration surface. To add a new framework, add a branch alongside the existing FW_QBX / FW_QB / FW_ESX checks. Mirror any event subscriptions on the client side in bridge/client.lua. The rest of the resource calls only these functions:

Player & identity

Bridge.GetPlayer(source)         -> opaque player object
Bridge.GetIdentifier(player)     -> string (license/citizenid/etc.)
Bridge.GetName(player)           -> "First Last"

Job & grade

Bridge.GetPlayerJob(source)      -> { name, label, grade, grade_name, isboss }
Bridge.GetAllJobs()              -> { [jobName] = jobObject, ... }
Bridge.GetJobLabel(jobName)      -> string
Bridge.JobExists(jobName)        -> boolean
Bridge.GetJobGrades(jobName)     -> { [grade] = { name, label, salary }, ... }
Bridge.IsBoss(source, jobName)   -> boolean
Bridge.SetJob(source, jobName, grade)
Bridge.RemoveFromJob(source, jobName)        -- used for fire (clean drop)
Bridge.SetJobOffline(identifier, jobName, grade)
Bridge.GetEmployees(jobName)     -> { { id, name, grade, isboss }, ... }
GetPlayerJob is the most important one — return shape must match exactly. The resource treats isboss = true as overriding Config.BossGradeNames, so set it correctly for grades that are bosses.

Money

Bridge.GetPlayerMoney(source, account)             -> number
Bridge.AddPlayerMoney(source, account, amount)     -> boolean
Bridge.RemovePlayerMoney(source, account, amount)  -> boolean
account is 'cash' or 'bank'. Return false on insufficient funds — the boss menu uses this to gate Deposit.

Society

Bridge.GetSocietyBalance(jobName)         -> number
Bridge.AddSociety(jobName, amount)        -> boolean
Bridge.RemoveSociety(jobName, amount)     -> boolean
Make sure both AddSociety and RemoveSociety return false on failure — the boss menu uses the return value to drive the refund-on-failure behaviour. Returning true after a silent failure means money disappears.

Admin & UX

Bridge.IsAdmin(source)                    -> boolean
Bridge.Notify(source, msg, kind, title)   -- 'success' | 'error' | 'inform'
IsAdmin is consulted alongside Config.Admin.acePermissions — return true from either path grants admin.

Client side

bridge/client.lua mirrors the framework-specific event subscriptions the resource needs — typically the “player loaded” and “job changed” events. Add your branch and emit the same internal events used by the existing branches. The most important client-side hook is publishing a refreshed PlayerData whenever the player’s job changes, so the marker / blip filtering updates without waiting for the next Config.JobPollMs tick.

Testing your branch

  1. Set Config.Framework = 'auto' (or pin to your new value if you’ve added one to the framework switch).
  2. Set Config.SocietyBackend accordingly.
  3. Start your framework, then nex_bossmenu. The boot line should print:
    [nex_bossmenu] Framework: <your-key>
    
  4. Run /bossmenu_admin as an admin, place a marker for a job that exists in your framework.
  5. Walk to it as a boss of that job — the prompt should appear and the menu should open.
  6. Try every action: balance read, withdraw, deposit, hire (with a candidate nearby), promote, demote, fire. Each one exercises a different bridge function — any missing return path will surface as a Society account write failed or setJob did not stick error.
Failed mutations log in red with the failing step, so you can map errors back to bridge functions immediately.