Installation

How to install tDetector on your FiveM server.

Prerequisites

  • FiveM server with OneSync enabled (Infinity or Legacy)
  • tLib — provides settings persistence, move mode, dialog system, and layout discovery
  • Wraith ARS 2X (wk_wars2x) — tDetector reads whether a player's radar antenna is active via its export. Without it no detection occurs, but the script loads cleanly.

Install

Extract the resource

Drop the tDetector folder into your resources directory (e.g., alongside other [tScripts]).

Patch Wraith ARS 2X

tDetector reads radar-gun state through an export that isn't in Wraith by default. Add it once to your wk_wars2x install:

wk_wars2x/fxmanifest.lua — add one line:

client_export "DetectorExport"

wk_wars2x/cl_radar.lua — add anywhere at the top level:

function DetectorExport()
    return RADAR
end

Required for detection to work

Without this export tDetector loads cleanly but cannot detect any active radar guns. The export is read-only and does not change Wraith's behavior.

Add to server.cfg

Order matters — tLib must start before tDetector, and wk_wars2x should be running for detection to work.

title="server.cfg" ensure tLib ensure wk_wars2x ensure tDetector

Start the server

No further setup is required. Per-player settings (speed unit, layout, HUD position) are stored in KVP. The server creates data.json automatically on first start to store the sound configuration.


Configuration

Open shared/config.lua to change the resource name, default speed unit, access mode, or enable QBCore item support:

Config = {}

-- Every radar resource tDetector should listen for.
-- Each must expose a client export named IsRadarActive() → boolean.
Config.radarResources = {
    "wk_wars2x",
    "seeker_dual",
}

-- Default speed unit: 'mph' or 'kph'
-- Players can override this per-session from /tDet
Config.speedUnit = "mph"

-- Who can toggle the detector — "everyone", "ace", or "item"
Config.accessMode    = "everyone"
Config.acePermission = "tdetector.use"

-- QBCore item support (optional)
Config.useAsItem  = false
Config.qbItemName = "radardetector"

No config.lua restart needed for per-player settings

Speed unit, layout choice, and HUD position are all saved in player KVP via /tDet. You only need to edit shared/config.lua to change the server-wide default or point at a different radar resource.

config.lua restart required for access settings

Unlike per-player settings, Config.accessMode and Config.acePermission are read on resource start. Run restart tDetector after changing them.


Access control

Config.accessMode controls who can toggle the detector:

ModeBehavior
"everyone"Default. Anyone can run /tDet and use the toggle button.
"ace"Only players granted Config.acePermission can run /tDet at all. Everyone else gets a chat message and the dialog never opens.
"item"/tDet still opens for everyone — speed unit, HUD layout, and reposition all still work — but the toggle button is disabled. The detector can only be enabled/disabled through the QBCore item, which this mode turns on by itself (Config.useAsItem does not need to be set).

The "ace" check runs server-side on every /tDet invocation, so granting or revoking the permission takes effect immediately — no reconnect needed. "item" mode's toggle lock is decided client-side (it just reads Config.accessMode, a shared script) since it's a UI restriction, not a permission check.

To grant the ace permission in server.cfg:

add_ace group.mechanic tdetector.use allow
add_principal identifier.license:xxxxxxxx group.mechanic

(Swap group.mechanic and the permission name for whatever fits your server — Config.acePermission can be renamed to anything.)


QBCore item support (optional)

tDetector can be triggered as a useable inventory item instead of (or alongside) the /tDet toggle button.

Already using accessMode = "item"?

That mode enables the item hook by itself — skip straight to Add the item to QB shared items. Config.useAsItem below is only for running the item alongside an active /tDet command (accessMode "everyone" or "ace").

Enable item usage

In shared/config.lua set:

Config.useAsItem  = true
Config.qbItemName = "radardetector"  -- must match your items.lua entry

Add the item to QB shared items

In qb-core/shared/items.lua:

['radardetector'] = {
  ['name']        = 'radardetector',
  ['label']       = 'Radar Detector',
  ['weight']      = 3000,
  ['type']        = 'item',
  ['image']       = 'radardetector.png',
  ['unique']      = true,
  ['useable']     = true,
  ['shouldClose'] = true,
  ['combinable']  = nil,
  ['description'] = 'We are not liable for your reckless driving.',
},

Add the inventory image

Drop radardetector.png into qb-inventory/html/images/.

Restart

restart tDetector

Using the item while in a vehicle toggles the detector on or off — identical to pressing the button in /tDet.


File layout

fxmanifest.lua
config.lua
data.json
sv_version.lua
sv_admin.lua
sv_sync.lua
sv_item.lua
cl_hud.lua
cl_detector.lua
cl_settings.lua
ui.html
PathPurpose
data.jsonAuto-created on first start — stores sound key→file mappings and installed sounds
shared/config.luaRadar resource name, default speed unit, access mode, QB item config
server/sv_admin.luaLayout discovery, marketplace registration, sounds config persistence, /tDet access gate
server/sv_sync.luaBroadcasts active radar-gun list to all clients every second
server/sv_item.luaQBCore useable item handler (runs when Config.useAsItem = true or Config.accessMode = "item")
client/cl_hud.luaNUI toggle, move mode, layout switching, KVP persistence
client/cl_detector.luaDetection loop — finds the closest active radar gun each tick
client/cl_settings.lua/tDet settings dialog
client/ui/Built NUI assets (do not edit)
client/web/NUI source (SolidJS — build with bun run build)
layouts/HUD layout skins (auto-discovered)

Do not edit client/ui/

These are built NUI assets. The source lives in client/web/. To rebuild after modifying the SolidJS source, run bun run build from inside client/web/.