Cipher Dispatch
Multi-department live dispatch, responder tracking and provider-based integration for Qbox and QBCore.
Requirements
Required
ox_libqbx_coreorqb-core
Optional
pma-voicefor TAC channel joining- Cipher MDT or another MDT identity provider
- A compatible phone resource for bidirectional emergency calls
Current release is v0.1.0.
Installation
- Drop the
cipher-dispatchfolder into your resources directory. - Start it after
ox_liband your framework. - Add the line below to
server.cfg. - Review departments, controls and integrations in
config.lua. - Restart and test one configured job from each department you use.
ensure cipher-dispatch
Integration Studio is ACE-protected:
add_ace group.admin cipher.dispatch.integrations allow
Its custom presets persist in data/integrations.json. The studio cannot overwrite built-in call types.
Departments
Each entry in Config.Departments controls framework jobs, mutual-aid visibility, GTA blip color, vehicle-category sprites, allowed statuses, UI identity and alert tone. Police, EMS and Fire stay visually distinct even when all three share one incident.
A responder only joins the network when their framework job matches a configured department and its duty rules. Test the exact job names used by your framework.
Controls
- F6 — open the dispatch console
- F5 — panic alert
- Y — respond to the active quick-overlay call
- U — hide or show the quick overlay
- I — join the assigned incident TAC channel when pma-voice is enabled
These are defaults. Players can rebind registered controls through GTA's key binding settings.
Calls and units
Calls support P1, P2 and P3 priority, multiple departments, timers, notes, GPS routing, responding units, operational groups and restart recovery. Vehicle-aware tracking distinguishes foot, patrol vehicle, motorcycle, bicycle, boat, helicopter and plane.
Automatic status detection can move assigned responders to En Route and On Scene using distance thresholds and hysteresis. Delta synchronization sends changed unit state instead of replacing the full network every tick.
Other server resources can create a call:
local callId, call = exports['cipher-dispatch']:CreateCall({
type = 'fire',
title = 'Commercial Structure Fire',
description = 'Multiple callers report smoke from the roof.',
priority = 1,
departments = { 'fire', 'ems', 'police' },
coords = vector3(215.4, -810.2, 30.7),
street = 'San Andreas Avenue',
caller = 'Automatic Alarm'
})Callsigns and MDT integration
Dispatch resolves identity in this order: a registered MDT provider, framework metadata, the saved Dispatch profile, then a generated fallback. Callsign identifies the radio unit; badge identifies the responder personally.
exports['cipher-dispatch']:RegisterIdentityProvider('my-mdt', function(source)
return exports['my-mdt']:GetDispatchIdentity(source)
end)The provider returns { callsign, badge?, unitType? }. Cipher MDT support is included, and export-based MDTs can also be configured through Config.MdtIdentityAdapters.
Provider API
External resources integrate through providers and exports instead of database access.
exports['cipher-dispatch']:RegisterProvider('phone', 'my-phone', {
sendStatus = function(call, status) end,
sendMessage = function(call, message) end,
})MDT adapters consume cipher-dispatch:provider:mdt:callCreated and cipher-dispatch:provider:mdt:callClosed. Phone adapters submit emergency data through SubmitPhoneEmergency and can listen for the caller-update hook.
Useful lifecycle exports include GetCall, GetActiveCalls, UpdateCall, AddCallNote and LinkMdtRecord.
Operational radio
Every incident receives an operation ID and TAC channel. Assigned responders can join through pma-voice when that integration is enabled. Automatic channel switching is disabled by default so Dispatch does not pull players away from an existing radio channel unexpectedly.
Troubleshooting
The responder is missing
Confirm the exact framework job appears under the intended department and the player satisfies its duty rules.
The callsign is not imported
Confirm the MDT provider or adapter returns a non-empty callsign. Check the MDT resource starts before Dispatch if the adapter registers during startup.
Respond does not set GPS
The call needs valid coordinates and the responder must be authorized for one of its departments.
TAC join does nothing
Confirm pma-voice is started and the voice provider is enabled. Leave this integration off when another radio script owns channel membership.
Updating
- Back up
config.luaanddata/integrations.json. - Read the release notes for config or provider changes.
- Replace the whole resource folder.
- Merge your configuration, restart and test call creation, response, GPS, status and identity sync.
Support
Include your framework, job name, MDT or phone resource, the full client and server errors, and the steps that caused the problem.