QBX Installation
QBX-specific setup for oxide-dispatch on a QBX (qbx_core) server.
QBX-specific setup for oxide-dispatch on a QBX (qbx_core) server.
Requirements
qbx_coreox_liboxmysqlo-linkoxide-dispatchoxide-police(recommended for full police duty and officer state)
Run the Oxide Dispatch SQL from oxide-dispatch/sql before starting the resource.
Startup Order
Start dependencies before Oxide Dispatch:
ensure ox_lib
ensure oxmysql
ensure qbx_core
ensure o-link
ensure oxide-dispatchIf Oxide Police is installed, start Dispatch before Police:
ensure oxide-dispatch
ensure oxide-policeQBX Jobs
QBX jobs live in qbx_core/shared/jobs.lua. Every job name used by an Oxide Police department must also exist there.
QBX requires all top-level keys in qbx_core/shared/jobs.lua to be lowercase. qbx_core/server/groups.lua prints jobs.lua contains a job name with capital letters: <name> at boot for any capitalized key and still loads the job, but AddPlayerToJob calls jobName:lower() before writing to player_groups. The result is a mismatch: the in-memory jobs table indexes by Police while the player record indexes by police. Any code that hardcodes the capitalized form (including Config.ResponderGroups) silently filters that player out of every broadcast. Always define jobs as ['police'], ['bcso'], ['sasp'] — never ['Police'] or ['LSPD'].
Job-name matching is case-sensitive — list each job under Config.ResponderGroups using the exact lowercase key it has in qbx_core/shared/jobs.lua.
QBX runs natively through o-link
Player loading, jobs, money, and inventory are handled by o-link natively for QBX. No QBX-specific compatibility block exists in Config.Compatibility — there is nothing to toggle.
Legacy QB alert compatibility
QBX robbery resources still emit the legacy QBCore event police:server:policeAlert, and qbx_ambulancejob emits hospital:server:ambulanceAlert / hospital:server:emergencyAlert. The qb-core shim (a small built-in translator that catches those old alert events and turns them into Oxide Dispatch alerts) in shared/config/compat.lua handles all of them. You do not install qb-core for this — the shim activates because qbx_core declares provide 'qb-core' in its manifest, which makes the server report qb-core as started. (If you run a modified qbx_core fork that removed that provide line, the shim will stay off.)
Config.Compatibility['qb-core'] = {
enabled = true,
serverPoliceAlert = true,
-- ...
}The shim accepts both the legacy (text, camId, playerSource) signature and a structured table:
TriggerEvent('police:server:policeAlert', message, nil, playerSource)TriggerEvent('police:server:policeAlert', {
title = 'Truck Robbery',
message = 'Armored truck robbery in progress',
coords = { x = coords.x, y = coords.y, z = coords.z },
code = '10-90',
jobs = 'police',
source_type = 'system',
source_name = 'Truck Robbery',
})When a robbery script calls the legacy event with source as 0, pass the player source as the third argument so the shim can use that player's position when no explicit alert coordinates are provided — otherwise the alert has no location and is dropped (it simply never appears for police). Alternatively, author your robbery scripts to call olink.dispatch.CreateAlert directly through o-link.
QBX robbery notes
If you use the legacy police-alert event from QBX robbery resources, update them to forward the player source. Common patches:
qbx_truckrobbery: send a server-side alert table with coordinates.qbx_jewelery: pass the triggering player source intopolice:server:policeAlert.qbx_houserobbery: pass the triggering player source into delayedpolice:server:policeAlertcalls.
Without these patches, the shim has no player to tie the alert to, so the alert is silently dropped — police never see it. Forwarding the player source lets Oxide Dispatch place the alert at that player's position when the legacy resource does not pass coordinates directly.
qbx_truckrobbery
In qbx_truckrobbery/config/server.lua, replace the default police loop that triggers police:client:policeAlert and qb-phone:client:addPoliceAlert with a server-side dispatch alert:
alertPolice = function(src, coords)
local msg = locale('info.alert_desc')
local alertData = {
title = locale('info.alert_title'),
message = msg,
description = msg,
coords = { x = coords.x, y = coords.y, z = coords.z },
code = '10-90',
jobs = 'police',
source_type = 'system',
source_name = 'Truck Robbery',
}
if GetResourceState('oxide-dispatch') == 'started' then
TriggerEvent('police:server:policeAlert', alertData)
return
end
TriggerEvent('police:server:policeAlert', alertData, nil, src)
endThe last line is a fallback: if oxide-dispatch is ever stopped, the alert still goes out with the triggering player's source attached, so whatever else handles the event can place it at the player's position.
qbx_jewelery
In qbx_jewelery/server/main.lua, make fireAlarm accept the triggering player source and forward it to the legacy alert event:
local function fireAlarm(playerSource)
if alarmFired then return end
TriggerEvent('police:server:policeAlert', locale('notify.police'), 1, playerSource)
TriggerEvent('qb-scoreboard:server:SetActivityBusy', 'jewellery', true)
TriggerClientEvent('qbx_jewelery:client:alarm', -1)
alarmFired = true
endThen call it from the cabinet completion event with:
fireAlarm(source)qbx_houserobbery
In qbx_houserobbery/server/main.lua, make policeAlert accept the triggering player source and forward it after the configured delay:
local function policeAlert(text, interiorId, playerSource)
SetTimeout(sharedConfig.interiors[interiorId].callCopsTimeout, function()
TriggerEvent('police:server:policeAlert', text, nil, playerSource)
end)
endThen call it after successful entry with:
policeAlert(locale('notify.police_alert'), house.interior, playerSource)Resource Conflicts
Disable qbx_police when Oxide Police is installed. Legacy qbx_police also registers police alert, duty, radial, and interaction behavior that conflicts with Oxide Police and Oxide Dispatch.
Testing Checklist
- SQL has been run.
o-linkstarts before Oxide Dispatch.- Oxide Dispatch starts before Oxide Police.
qbx_policeis disabled if Oxide Police is installed.- Truck robbery creates an Oxide Dispatch alert with coordinates.
- Jewelry robbery creates an Oxide Dispatch alert after a cabinet is hit.
- House robbery creates an Oxide Dispatch alert after the configured delay.
/911 robbery in progressfrom a citizen reaches on-duty police./panicfrom an on-duty officer reaches colleagues.- Press
Gon a popup — accepts the alert and drops a waypoint. - Alerts are received only by configured police jobs.