Core keys
Config.Debug = true draws every sound point’s audible radius as a ring on the ground. It is by far the fastest way to work out why someone can’t hear anything.Framework detection
Config.Framework = 'auto' probes in this order and takes the first resource that is running:
qbx_core→qbxox_core→oxes_extended→esxqb-core→qb- nothing →
standalone
qbx_core is checked before qb-core because Qbox servers often ship a qb-core compatibility shim, and ox_core before es_extended for the same reason.
Forcing a framework whose resource isn’t running logs a warning and falls back to standalone rather than erroring out.
What actually changes per framework:
- Jobs are read for job-gated booths and for admin jobs. Standalone always reports no job, so job rules never pass there.
- Gangs are QBCore and Qbox only. On ESX, ox_core and standalone, gang rules never pass.
- Identifiers work everywhere. On standalone the identifier is the player’s
license:.
Audio backend
Two engines can play the audio. Both are driven by the same authoritative server state — the queue, permissions, sync clock and every value below behave identically either way. Only the playback layer changes.Config.XSound tunes the xsound path:
spatial = true gives you real stereo positioning, but the falloff curve is xsound’s rather than the one set in Config.Audio.defaultFalloff. Set spatial = false if you want the three curves, multi-sound-point “loudest wins” and per-booth tuning to behave exactly as documented below — at the cost of stereo panning.xsound while the server is already running is picked up automatically — anything currently playing is stopped first so the two engines never overlap.
Audio
Config.Audio sets the defaults every booth inherits unless it overrides them.
Volume for a booth is recomputed continuously as the falloff curve against the loudest sound point you’re inside, multiplied by the DJ’s master volume, the booth’s ceiling, vehicle muffle, indoor boost and the listener’s own volume slider — then smoothed so it never pops.
Three faders stack: the DJ’s master volume, each listener’s personal slider, and the booth’s
maxVolume ceiling. Any of them at zero is silence.Effects
Config.Effects sets light and laser caps, draw distance, particle assets and beat reactivity. config/effects.lua holds Config.EffectDefaults and eight presets: classic club, rave, chill lounge, festival, strobe storm, smoke and lasers, blackout, and neon synth.
Beat-reactive pulsing is real analysis for direct media. For YouTube it cannot be — the audio lives in a cross-origin frame that can’t be analysed — so the pulse is synthesised from a 120 BPM envelope. The lights still move, they just aren’t literally following the track.
Props
Config.BoothModels and Config.SpeakerModels each offer eight props to the in-game creator. Add your own model names to either list and they show up in the picker.
Security limits
Config.Security holds the caps, URL policy, allow and deny lists, auto-ban toggle, logging and rate limits.
The Discord webhook URL is not in
Config.Security. It is the server-only nexdev_djsystem_webhook convar — see Installation.Interface defaults
Config.UI sets the default accent colour, scale, anchor, blur and compact mode. Each player can override all of them from the settings tab, and their choice is persisted locally.
The usable item
Off by default. Turn onConfig.Item.enabled and, with ox_inventory running, Config.Item.name (default dj_controller) becomes a usable item that opens the panel at the nearest booth the player is allowed to use.
If ox_inventory isn’t started, the item is skipped with a console warning rather than erroring.
Config.Item.boothItem and Config.Item.consumeOnPlace are reserved keys. Nothing reads them in 1.0.0.Locales
locales/en.json holds every string the script can display, as flat dotted keys. Config.Locale picks the file — 'fr' loads locales/fr.json. Only English ships.
Adding a translation
- Copy
locales/en.jsontolocales/<language>.json. - Translate the values. Leave the keys alone.
- Set
Config.Localeto that name and restart.
Set
Config.Locale = 'auto' to use ox_lib’s language instead: the ox:locale convar on the server, and each player’s own ox_lib language setting on the client. That’s the only way to give different players different languages — Config.Locale is server-wide.locales/ folder degrades labels and never breaks a feature.

