Framework & Bridges
On this page10
Every third-party system the script talks to sits behind a small open adapter in
bridge/. You pick your systems with the Config.*System selectors in config.lua.
The four values every selector accepts
| Value | Meaning |
|---|---|
'auto' | Find the running script by itself, in a fixed order (listed per selector below). |
'<resource name>' | Force exactly that one. The folder name, spelled exactly. |
'custom' | Use your code in the matching bridge/*.lua file. See Writing a Custom Adapter. |
'none' | Turn the integration off entirely (only where the table below offers it). |
Core
| Key | Default | Allowed values | Auto order |
|---|---|---|---|
Config.Framework | 'auto' | auto · qbx_core · es_extended · qb-core · ox_core · standalone · custom | 1 qbx_core → 2 es_extended → 3 qb-core → 4 ox_core → 5 standalone |
Config.MulticharSystem | 'auto' | auto · qb-multicharacter · qbx_core · esx_multicharacter · um-multicharacter · 17mov_CharacterSystem · 0r-multicharacterv3 · codem-multicharacter · qs-multicharacter · op-multicharacter · ak47_multicharacter · vms_multichars · custom · none | external selectors first, qbx_core's built-in last |
Config.InventorySystem | 'auto' | auto · ox_inventory · qb-inventory · qs-inventory · jaksam_inventory · tgiann-inventory · ak47_inventory · ak47_qb_inventory · origen_inventory · codem-inventory · core_inventory · ps-inventory · lj-inventory · esx · standalone · custom | see Inventories |
The character selector is only used for three things: sending a player back to the selector after a face implant (off by default), hiding our HUD while the selector is open, and the install notes. Every surveyed selector logs characters in through the framework, so framework events cover them all.
Appearance and tattoos
| Key | Default | Allowed values |
|---|---|---|
Config.AppearanceSystem | 'auto' | auto · illenium-appearance · 17mov_CharacterSystem · rcore_clothing · qs-appearance · tgiann-clothing · crm-appearance · fivem-appearance · qb-clothing · esx_skin · custom · none |
Config.TattooSystem | 'auto' | auto · natives · illenium-appearance · rcore_tattoos · custom |
Clothing itself is read from GTA natives and works with any appearance script or none. The appearance selector is only used for the face editor the implant clinic opens and for "outfit changed" hints.
natives works on every server for tattoos. If your tattoo script is in the list
(illenium-appearance, rcore_tattoos), you can pick it instead.
Voice
| Key | Default | Allowed values |
|---|---|---|
Config.VoiceSystem | 'auto' | auto · pma-voice · saltychat · yaca-voice · tokovoip_script · enhanced · native · custom |
Auto order: pma-voice → saltychat → yaca-voice → tokovoip_script → native.
Only pma-voice supports the audible voice changer. On every other system the changer still fools the scan and still links crimes to the same device — people nearby just hear the wearer's normal voice. Details: Voice & Voice Changer.
Interaction and feedback
| Key | Default | Allowed values |
|---|---|---|
Config.NotifySystem | 'auto' | auto · ox_lib · qbx · qb · esx · okokNotify · lation_ui · native · custom |
Config.TextUISystem | 'native' | native · auto · ox_lib · jg-textui · esx_textui · qb-core · okokTextUI · lation_ui · cd_drawtextui · custom |
Config.ProgressSystem | 'auto' | auto · ox_lib · qb · esx · lation_ui · nui · custom · none |
Config.TargetSystem | 'auto' | auto · sleepless_interact · ox_target · qb-target · interact · custom · none |
Config.EmoteSystem | 'auto' | auto · rpemotes-reborn · rpemotes · scully_emotemenu · dpemotes · native · custom · none |
The progress bar is used for surgery, printing and device setup. It is never used for the scan itself — the scan has its own HUD.
The target selector is only used when Config.StartMode = 'target', and for the
clinic NPC.
Death, police, MDT, evidence
| Key | Default | Allowed values |
|---|---|---|
Config.DeathSystem | 'auto' | auto · qb-ambulancejob · qbx_medical · esx_ambulancejob · wasabi_ambulance_v2 · wasabi_ambulance · ars_ambulancejob · ars_ambulance · osp_ambulance · brutal_ambulancejob · ak47_ambulancejob · ak47_qb_ambulancejob · randol_medical · visn_are · native · custom · none |
Config.PoliceSystem | 'auto' | auto · qb-policejob · qbx_police · esx_policejob · wasabi_police · wasabi_police_v2 · ak47_policejob · ak47_qb_policejob · custom · none |
Config.MDTSystem | 'auto' | auto · lb-tablet · tk_mdt · redutzu-mdt · drx_mdt · origen_police · wasabi_mdt · ps-mdt · custom · none |
Config.EvidenceSystem | 'auto' | auto · evidences · kartik-evidence · wasabi_evidence · custom · none |
native on the death selector means our own detection plus the movement rule — it
always runs underneath whichever script is selected. The police selector never blocks
anything; it only tells the proof log who cuffed, robbed, searched or escorted whom.
Capture and HUD
| Key | Default | Allowed values |
|---|---|---|
Config.ScreenshotSystem | 'auto' | auto · builtin · screencapture · screenshot-basic · none |
Config.HudSystem | 'auto' | auto · jg-hud · 17mov_Hud · 0r-hud-v3 · mHud · qb-hud · qbx_hud · esx_hud · ps-hud · custom · none |
Config.NametagSystem | 'none' | none · cxc_gamertag · zeno-rpchatid · custom |
Config.WeatherSyncSystem | 'auto' | auto · qbx_weathersync · qb-weathersync · Renewed-Weathersync · cd_easytime · vSync · weathersync · custom · none |
'auto' on screenshots tries builtin first (needs nothing), then screencapture,
then screenshot-basic.
Config.NametagSystem defaults to 'none': hiding a masked player's floating name is
opt-in, because it changes how your whole server reads at a glance.
The boot summary
After boot the server prints what every server-side bridge resolved to:
[5code-recognition] Integrations: framework=qbx inventory=ox_inventory voice=pma-voice appearance=illenium-appearance tattoos=illenium-appearance death=qbx_medical police=qbx_police mdt=none evidence=none target=none textui=native hud=jg-hud screenshot=builtinThat line is the first thing to read when an integration "does not work". If a system
shows as none and you expected it, either the resource is not started, or it is
started after us and did not re-resolve, or you pinned a name that does not match
the folder.
With Config.Debug = true the summary adds a second line with the two job
whitelists, because a mistyped job name is otherwise invisible:
[5code-recognition] Jobs: police={police} (duty required) hint={police} (duty not required) acceptTypes={leo}recognition:selftest also names any job in those lists that your framework does
not have (see Police jobs).
Client bridges print the selector they resolved to F8 only when
Config.Debug = true. They print the "…but <x> is not started" warning to F8
whatever Config.Debug is set to — see
Troubleshooting. Each player's voice provider
is reported to the server and shown in recognition:status.
Standalone
With no framework at all, every bridge falls back to a native or standalone branch and the whole loop still works. One setting decides what a "character" is:
ServerConfig.Standalone = {
CharacterKey = 'license', -- 'license' | 'license2' | 'fivem' | 'custom'
}'custom' calls Hooks.GetCustomCharacterId in bridge/hooks.lua. There is one
character per key, so a standalone server has one character per player.
Jobs work the same way: without a framework nobody is police unless you wire
Hooks.GetCustomJob.
Adding a system that is not listed
Set the selector to 'custom' and fill the 'custom' branch in the matching
bridge/*.lua file. The core only ever calls the small set of functions that branch
defines, so you never need access to the protected code.
Full walkthrough with the function list per bridge: Writing a Custom Adapter.