Dispatch
Dispatch system exports, hooks, and compatibility mode.
The dispatch system is a built-in subsystem of vx_mdt with its own set of server exports, event hooks, and a compatibility layer for third-party dispatch resources.
Dispatch exports are controlled by a separate dispatch.exportAllowlist in config (independent from the core exportAllowlist).
Lifecycle
createDispatchCall(data)
Create a new dispatch call. When coords are provided, a map blip is automatically created for on-duty officers.
---@param data { dep_type: string, call_type: string, title: string, description?: string, location_text?: string, priority?: number, metadata?: table, coords?: vector3, radio_frequency?: number, author_name?: string, author_identifier?: string, blip?: table|false, fields?: table[] }
---@return { id: number }|{ error: string }
local result = exports.vx_mdt:createDispatchCall({
dep_type = "law",
call_type = "10-31",
title = "Robbery in Progress",
description = "Armed robbery at Fleeca Bank",
location_text = "Fleeca Bank, Route 68",
priority = 1,
coords = vector3(311.6, -278.6, 54.2),
blip = {
sprite = 161, -- GTA blip sprite (default from config)
colour = 1, -- GTA blip colour (default from config)
scale = 0.8, -- blip scale (default from config)
duration = 60, -- seconds before auto-removing (0 = until call ends)
flash = true, -- flash the blip (default: auto for P0/P1)
text = "Robbery", -- blip label (default: call title)
offset = 50, -- random offset in world units (0 = exact, default from config)
radius = 100, -- radius circle overlay in world units (0 = none, default from config)
radius_colour = 1, -- radius circle colour (default: blip colour)
radius_alpha = 128, -- radius circle transparency 0-255 (default from config)
},
fields = {
{ type = "plate", value = "ABC123" },
{ type = "vehicle", value = "Sultan", data = "ABC123" },
{ type = "color", value = "Red", data = "27" },
{ type = "speed", value = "142" },
{ type = "person", value = "John Smith", data = "ABC12345" },
{ label = "WEAPON", value = "AK-47" },
},
})The blip parameter is optional:
- Omit: uses config defaults, blip appears at call coords
- Table: override specific blip properties (all fields optional)
false: suppress the blip for this call entirely
The fields parameter adds structured data fields visible on the dispatch notification and in the MDT call detail. Each field entry can use a pre-defined type (with auto-populated label/icon and interactive behavior) or a custom label+value pair.
Pre-defined types:
| Type | Label | Behavior |
|---|---|---|
plate | PLATE | Clickable in MDT, opens vehicle record |
vehicle | VEHICLE | Clickable if data contains the plate |
color | COLOR | Renders a hex color swatch (set data to the GTA color index) |
person | SUSPECT | Clickable if data contains the citizen identifier |
speed | SPEED | Color-coded by threshold, appends "km/h" |
Custom fields use label + value directly: { label = "WEAPON", value = "AK-47" }
All fields support an optional icon (Iconify name) and data (navigation target or color index).
updateDispatchCall(callId, data)
Update fields on an active dispatch call.
---@param callId number Dispatch call ID
---@param data table Fields to update
exports.vx_mdt:updateDispatchCall(callId, {
priority = 2,
description = "Suspects fleeing on foot",
})completeDispatchCall(callId)
Mark a dispatch call as completed.
---@param callId number Dispatch call ID
exports.vx_mdt:completeDispatchCall(callId)cancelDispatchCall(callId)
Cancel a dispatch call.
---@param callId number Dispatch call ID
exports.vx_mdt:cancelDispatchCall(callId)Assignment
attachDispatchCall(callId, source)
Attach an officer to a dispatch call.
---@param callId number Dispatch call ID
---@param source number Player server ID
exports.vx_mdt:attachDispatchCall(callId, source)detachDispatchCall(callId, source)
Detach an officer from a dispatch call.
---@param callId number Dispatch call ID
---@param source number Player server ID
exports.vx_mdt:detachDispatchCall(callId, source)addDispatchCallUpdate(callId, content, author)
Add a status update to a dispatch call.
---@param callId number Dispatch call ID
---@param content string Update text
---@param author string Author name
exports.vx_mdt:addDispatchCallUpdate(callId, "Suspects in custody", "Officer Smith")Query
getDispatchCall(callId)
Get a dispatch call by ID.
---@param callId number Dispatch call ID
---@return table|nil Dispatch call or nil
local call = exports.vx_mdt:getDispatchCall(callId)getActiveDispatchCalls(depType?)
Get all active dispatch calls, optionally filtered by department type.
---@param depType? string Optional: "law", "ems", or "judge"
---@return table[] Array of active dispatch calls
local calls = exports.vx_mdt:getActiveDispatchCalls("law")Hooks
Subscribe to dispatch events for real-time integrations.
onDispatch(event, handler)
Register a listener for dispatch events. Returns a table with the listener ID for cleanup.
---@param event "created"|"updated"|"deleted"|"attached"|"detached"|"completed"|"cancelled"
---@param handler function Callback receiving event data
---@return { id: number }|{ error: string }
local result = exports.vx_mdt:onDispatch("created", function(call)
print("New dispatch call:", call.title)
end)
local listenerId = result.idoffDispatch(listenerId)
Unregister a dispatch event listener.
---@param listenerId number Listener ID from onDispatch
---@return {}|{ error: string }
exports.vx_mdt:offDispatch(listenerId)Auto-Detection
Auto-detection listens for GTA game events and automatically creates dispatch calls; no third-party dispatch resource required. Enabled by default; set dispatch.autoDetection.enabled = false to opt out.
dispatch = {
autoDetection = {
enabled = true,
events = {
gunshot = {
enabled = true,
cooldown = 15,
priority = 2,
weaponBlacklist = {
"weapon_stungun",
"weapon_flaregun",
"weapon_flare",
"weapon_snowball",
"weapon_ball",
"weapon_firework",
"weapon_fireextinguisher",
"weapon_petrolcan",
"weapon_hazardcan",
},
},
fight = { enabled = true, cooldown = 30, priority = 3 },
carjacking = { enabled = true, cooldown = 20, priority = 1 },
vehicleTheft = { enabled = true, cooldown = 30, priority = 2 },
explosion = { enabled = true, cooldown = 20, priority = 1 },
speeding = { enabled = true, cooldown = 45, speedThreshold = 130, priority = 3 },
},
},
fields = {
plate = true,
vehicleColor = true,
speed = true,
heading = true,
suspect = true,
owner = true,
},
},Structured Fields
Auto-detected calls attach structured data fields to the notification card and MDT detail view. Each field can be individually toggled via autoDetection.fields:
| Field | Description |
|---|---|
plate | Vehicle plate number |
vehicleColor | Vehicle color with hex swatch (uses GTA color index) |
speed | Vehicle speed in km/h (speeding events only) |
heading | Compass heading (N, NE, E, SE, etc.) |
suspect | Suspect sex description |
owner | Registered vehicle owner name (looked up from the database by plate, cached for 120 seconds) |
When owner is enabled and the vehicle plate matches a registered vehicle, the owner's name is automatically resolved and displayed as a clickable link to their profile in the MDT.
Detected Events
| Event | Game Trigger | Title | Default Priority |
|---|---|---|---|
gunshot | CEventGunShot | Shots Fired / Drive-By Shooting | 2 |
fight | CEventShockingSeenMeleeAction | Fight In Progress | 3 |
carjacking | CEventPedJackingMyVehicle | Carjacking In Progress | 1 |
vehicleTheft | CEventShockingCarAlarm | Vehicle Theft | 2 |
explosion | CEventExplosionHeard | Explosion Reported | 1 |
speeding | Multiple driving events | Speeding Vehicle | 3 |
Each event can be individually enabled/disabled and has its own cooldown. The speeding event has an additional speedThreshold (km/h): only vehicles exceeding this speed trigger a call.
On-duty LEO/EMS players are automatically exempt and will never trigger auto-detected calls. Silenced weapons, aircraft, unarmed hits, and any weapons listed in autoDetection.events.gunshot.weaponBlacklist (stun gun, flare gun, fireworks, etc. by default) are filtered out. Server-side rate limiting prevents abuse (max 5 events per 15 seconds per player).
Suppression Hooks
Each auto-detection event can be silenced under custom conditions, for example when a player is inside a paintball minigame or a scripted cutscene. Suppressors run before the cooldown timer, so suppressed events don't burn the cooldown window.
Two registration paths feed the same internal list:
1. Config callback (server owner)
Add a suppress function to any event under dispatch.autoDetection.events. Return true to drop the event, return false/nil to allow it.
dispatch = {
autoDetection = {
events = {
gunshot = {
enabled = true,
cooldown = 15,
priority = 2,
weaponBlacklist = { ... },
suppress = function(ctx)
if exports["pug-paintball"]:IsInPaintball() then
return true
end
end,
},
},
},
},2. Runtime export (third-party resource)
Resources can self-register a suppressor without editing vx_mdt files, useful for closed-source minigame scripts or custom integrations:
CreateThread(function()
exports.vx_mdt:registerAutoDetectSuppressor("gunshot", function(ctx)
return exports["pug-paintball"]:IsInPaintball()
end)
end)Returns true on success, false if the event key is unknown or arguments are invalid. Registrations are cleared when vx_mdt restarts; re-register on resource start.
Context payload
The ctx argument shape varies per event:
| Event | ctx fields |
|---|---|
gunshot | ped, coords, weapon, vehicle? |
fight | ped, coords |
carjacking | ped, coords, vehicle |
vehicleTheft | ped, coords, vehicle |
explosion | ped, coords |
speeding | ped, coords, vehicle, speed (km/h, int) |
Suppressors are wrapped in pcall: a broken hook logs a warning via lib.print.warn instead of crashing the handler. Multiple runtime suppressors per event stack: if any returns true, the event is dropped.
Compatibility Mode
Set dispatch.dispatchCompat in config to the name of your third-party dispatch resource to intercept its calls and route them into vx_mdt automatically.
Supported values: "cd_dispatch", "cd_dispatch3d", "ps-dispatch", "rcore_dispatch", "fd_dispatch", or "" (disabled).
dispatch = {
dispatchCompat = "cd_dispatch",
},When compatibility mode is enabled, you do not need to remove the third-party dispatch resource. vx_mdt intercepts its events and exports transparently.