Skip to content

Bridges ​

np_phone talks to frameworks and voice resources only through Phone.Framework and Phone.Voice (see Architecture §4–5). Each bridge file calls Phone.Bridge.shouldLoad(kind, name, resource) and returns early unless its resource is started and selected (Config.Framework / Config.Voice, or 'auto'). Files are numbered so auto prefers qbx over qb (qbx also provides qb-core) and pma-voice over the others. Optional exports are called through pcall, so a missing or broken dependency degrades instead of erroring.

bridge/framework/server/0_common.lua holds shared helpers (Phone.BridgeUtil: amount validation, ox_inventory item count, qb vehicle state mapping, pcall wrapper). It doesn't define a bridge.

Framework (server) ​

Contractqbx (qbx_core)qb (qb-core)esx (es_extended)
core objectexports.qbx_coreexports['qb-core']:GetCoreObject()exports.es_extended:getSharedObject()
getIdentifierGetPlayer(src).PlayerData.citizenidQBCore.Functions.GetPlayer(src).PlayerData.citizenidESX.GetPlayerFromId(src).identifier
getNamecharinfo.firstname/lastnamecharinfo.firstname/lastnamexPlayer.get('firstName'/'lastName'), else xPlayer.getName()
getJobjob.name/label/grade.level/grade.name/ondutysame as qbxjob.name/label/grade/grade_label/onDuty (missing onDuty = on duty)
getMoneyPlayerData.money[cash|bank]samexPlayer.getAccount('money'|'bank').money (cash → money)
removeMoneyexports.qbx_core:RemoveMoney(src, type, amount, reason)Player.Functions.RemoveMoneybalance check, then xPlayer.removeAccountMoney
addMoneyexports.qbx_core:AddMoney(src, …)Player.Functions.AddMoneyxPlayer.addAccountMoney
addMoneyOfflineexports.qbx_core:AddMoney(citizenid, …) (qbx loads offline players itself)online: GetPlayerByCitizenId; offline: UPDATE players SET money = JSON_SET(…)online: GetPlayerFromIdentifier; offline: UPDATE users SET accounts = JSON_SET(…)
getSourceByIdentifierGetPlayerByCitizenIdQBCore.Functions.GetPlayerByCitizenIdESX.GetPlayerFromIdentifier(id).source
hasItemox_inventory GetItemCount, else qb-inventory HasItemox_inventory, qb-inventory HasItem, else Player.Functions.GetItemByNameox_inventory, else xPlayer.getInventoryItem(item).count
getVehiclesplayer_vehicles (state 0 out / 1 garaged / 2 impounded)sameowned_vehicles (stored = 1 garaged, pound set = impounded, props JSON for model/fuel/health)
getCharacterInfocharinfo + metadata.licencessamexPlayer.get('firstName','lastName','dateofbirth','sex') + optional user_licenses table
onPlayerLoadedQBCore:Server:PlayerLoaded (player)sameesx:playerLoaded (playerId, xPlayer, isNew)
onPlayerUnloadedQBCore:Server:OnPlayerUnload, qbx_core:server:playerLoggedOutQBCore:Server:OnPlayerUnload (also fired on drop)esx:playerLogout, esx:playerDropped

The core also listens to playerDropped itself, so every framework unloads correctly.

Framework (client) ​

Contractqbxqbesx
isLoadedLocalPlayer.state.isLoggedIn / load eventsame + GetPlayerData().citizenidESX.IsPlayerLoaded()
isDeadmetadata.isdead / inlaststand (via exports.qbx_core:GetPlayerData())QBCore.Functions.GetPlayerData().metadataesx:onPlayerDeath / esx:onPlayerSpawn, ESX.GetPlayerData().dead, IsEntityDead
isCuffedmetadata.ishandcuffed, IsPedCuffedsameLocalPlayer.state.handcuffed / isCuffed, IsPedCuffed (ESX has no standard flag)
onLoadedQBCore:Client:OnPlayerLoadedsameesx:playerLoaded
onUnloadedQBCore:Client:OnPlayerUnloadsameesx:onPlayerLogout

Voice (server) ​

Contractpma-voiceSaltyChat (saltychat)YACA (yaca-voice)
startCall(callId, sources)setPlayerCall(src, channel) for each source; string ids are mapped to numeric channelsAddPlayersToCall('np_phone:'..callId, sources)callPlayer(a, b, true) for every new pair
endCall(callId, sources)setPlayerCall(src, 0)RemovePlayersFromCall('np_phone:'..callId, sources)callPlayer(src, other, false) for every remaining participant
setSpeaker(src, on)no-op (no server export)SetPhoneSpeaker(src, on)enablePhoneSpeaker(src, on)

startCall adds sources to a call (creating it), and endCall removes the given sources. Call endCall with every participant to end the call. With no voice resource, Phone.Voice.name == 'none' and every method is a no-op.

Sources (verified 2026-10-04) ​

Not verified against a running server: the qbx/qb player_vehicles column set (taken from the qb-core schema that qbx_vehicles keeps), ESX user_licenses (esx_license, optional), and handcuff flags of third-party police scripts (ESX).

np_* FiveM resources