How Integrations Work#
Everything that depends on another resource — framework, inventory, billing, housing, garages, voice — sits behind a small bridge file in client/custom/ or server/custom/. One config value picks which bridge is active; every other file in the folder stands aside. These folders are open for editing.
Layer | Config value | Supported |
|---|---|---|
Framework |
|
|
Garages / vehicles |
|
|
Housing |
|
|
Inventory |
|
|
Billing |
| See Billing below. |
Voice |
|
|
Anticheat |
| Fiveguard |
The three automatic values look at which resources are already started — qb-core first, then es_extended; qs-housing first, then qb-houses. To pin one by hand, replace the expression with a plain value:
Config.Framework = 'qb' -- instead of the auto-detection
Config.VehicleGarages = 'qb-core'
Config.Housing = 'qs-housing'Frameworks#
Names come from the character's first and last name, jobs and grades from xPlayer, licences from user_licenses and vehicles from owned_vehicles. The MDT item is registered as an ESX usable item.
Names come from charinfo, licences from metadata.licences and vehicles from player_vehicles. The framework's own duty toggle (QBCore:Client:SetDuty) switches the dispatch on and off.
Qbox runs through the QBCore bridge using qbx_core's QBCore compatibility layer. Make sure it is enabled, and set Config.Framework = 'qb' and Config.VehicleGarages = 'qb-core' by hand.
To use another duty script, call the ToggleDuty export from it — client/custom/framework/esx.lua has an example handler you can copy.
Inventory#
The inventory bridge is used for one thing: removing Config.Penitencial.IlegalItems from a player sent to prison. On esx-default it also removes matching weapons from the loadout. With none, nothing is taken and the server prints a warning each time. The MDT item itself is registered through the framework, so it works with any inventory.
Billing#
The billing bridge sends speed-camera fines and fills the bills list of a citizen's MDT profile. Every bill is issued to society_police.
Config.Billing | Resource | Notes |
|---|---|---|
| Default. Full support. | |
| Full support. | |
| Bills list read from the | |
| Jaksam Billing UI | Full support. |
| codeM Billing | Full support. |
| TGG Billing | Bills list and creation through its exports. |
| Partial. Prefer another billing script, or set |
Without any billing script, set Config.showBillsInMDT = false and, in Config.VelocityRadar, sendDirectTheBill = false with account = 'bank' so speed cameras take the fine from the bank instead.
Housing and Garages#
The housing bridge lists the properties a citizen owns in their MDT profile, with a button that sets a waypoint to the door. qs-housing and qb-houses read their own tables; default shows "Cannot find houses".
The garage bridge powers Find Plate and the vehicles list of a profile, reading Config.vehiclesTable — owned_vehicles on ESX, player_vehicles on QBCore. If your garage script keeps vehicles elsewhere, change that value or edit server/custom/vehicles/.
Voice and Radio#
With Config.Dispatch.EnabledRadios = true, dragging a unit between TAC groups in the panel moves their radio to that group's channel.
Set Config.voice = 'pma-voice'. Each default channel and group channel in Config.Dispatch is also locked to its job, so only that department can join it.
Set Config.voice = 'saltychat'. Units are moved between channels the same way; channel locking is left to SaltyChat itself.
Fiveguard#
Watching CCTV moves the player's camera far from their body, which Fiveguard would flag as a freecam. When a Fiveguard resource named Config.FiveguardName is running, the script grants a temporary freecam bypass while the camera is open and removes it on exit. Set the value to the exact folder name of your Fiveguard resource.
Config.FiveguardName = 'fiveguard'Discord Logs#
Two different webhooks are used:
Where | What it does |
|---|---|
| Storage for the screenshots attached to calls. Use a private channel. |
| A log of every police and EMS call as an embed, with its photo. |
-- server/custom/events/onCallEvent.lua
local PoliceWebhookURL = 'https://discord.com/api/webhooks/...'
local AmbulanceWebhookURL = 'https://discord.com/api/webhooks/...'While the call webhooks are empty, the console prints a reminder on every call. Paste a URL, or delete the warning lines in that file if you do not want call logs. To log calls of other jobs, add your own check in OnCallEvent with the SendWebhook export — see Commands and Exports.
Adding a Backend#
Supporting a billing, inventory, housing or voice script that is not listed is one file:
Copy the closest bridge
Duplicate the most similar file in the matching folder — for example
server/custom/billing/esx_billing.lua— and give it your script's name. For billing, copy its client file inclient/custom/billing/as well.Change the guard and the calls
The first line of every bridge says which value activates it. Set your own name there, then replace the exports or queries inside with your script's:
lua if Config.Billing ~= 'my-billing' then return end function CreateBill(source, label, amount) exports['my-billing']:CreateInvoice(source, 'society_police', label, amount) endSelect it
Set
Config.Billing = 'my-billing'and restart the resource.
Languages#
Five translations ship in locales/: English (en), Spanish (es), French (fr), German (de) and Portuguese (pt). They cover the whole interface: dispatch, MDT, cameras and jail. Choose one with Config.Language.
To translate into another language, copy locales/en.lua to a new file, change the code on its first line, translate the values, and set Config.Language to that code. The same file holds texts you may want to brand, such as DEPARTMENT_NAME and POLICE_LOGO_URL. Keep every %s in SPEED_LIMIT_MESSAGE.



