shared/config.lua
Owner options in shared/config.lua — what each value does.
Edit shared/config.lua only. Framework bridge code lives in client/edit.lua and server/edit.lua.
Comments in the Lua file match this page. Nested feature packs also have dedicated guides:
Framework & locale
Which core to use. "auto" detects qbx_core → qb-core → es_extended. Force "qbcore" | "qbox" | "esx" | "custom" when needed (custom = you fill the edit.lua bridges yourself).
Config.Framework = "auto"If you renamed the core resource, set it here. Leave false for defaults (qb-core / qbx_core / es_extended).
Config.CustomFrameworkName = falseUI and notification language. Bundled: en · es · pt · de · fr · pl. Copy locales/en.json to add more, translate values, then set this (or set ox:locale).
Config.Locale = 'en'How track length / distance chips appear in the tablet. Stored lengths stay in meters; this only changes labels. "mi" = miles · "km" = kilometres.
Config.DistanceUnit = 'mi'Integrations & tablet
Register the Racing custom app on lb-phone / lb-tablet. Requires those resources started before gs_racing.
Config.EnableLBPhone = false
Config.EnableLBTablet = falseOpen GS Racing via NUI without lb-* (item + optional command). Recommended when lb is not installed.
Config.EnableStandaloneTablet = trueInventory item that opens the standalone GS Racing. Must match an item registered in your inventory (see Localization & items).
Config.TabletItemName = 'racing_tablet'Chat command that opens GS Racing (no slash in this value). Set false to disable the command; item / lb apps still work.
Config.TabletCommand = false -- e.g. 'racingtablet'Cover camera (standalone)
In-world freecam for track cover photos on standalone GS Racing only. Requires screenshot-basic. Uploads go through server-only Config.PhotoUpload in server/edit.lua.
lb-tablet: when GS Racing is opened through lb-tablet, cover photos use lb-tablet’s gallery entirely — Config.CoverCamera is not used (no freecam button, no URL-only fallback in that host). Disable freecam for standalone with enabled = false; the UI then shows only the photo URL input.
Config.CoverCamera = {
enabled = true, -- false = URL paste only on standalone
maxDistance = 90.0,
moveSpeed = 0.12,
fastMultiplier = 3.0,
minFov = 20.0,
maxFov = 90.0,
defaultFov = 60.0,
encoding = 'jpg',
quality = 0.7,
}| Key | Meaning |
|---|---|
enabled | false hides Take photo on standalone (URL input only). Does not affect lb-tablet gallery. |
| Freecam fields | Distance, move speed, FOV, screenshot encoding/quality |
Controls while framing: Rockstar instructional button bar (same pattern as security cams). Enter or left-click captures; Backspace/Esc cancels. Capture uses screenshot-basic so the image is never sent through a client net event.
Database seed
Auto-import the default track pack from sql/tracks.sql on resource start. Only runs when gs_racing_tracks is empty — safe to leave on after the first import.
Config.AutoImportDefaultRaces = trueVehicles & classes
Racing families and their class ladders (not GTA native vehicle classes). Used for host filters, scan UI, and join validation.
| Key | Meaning |
|---|---|
label | Full name in UI |
short | Chip / filter label |
classes | Allowed class codes for that kind |
Config.VehicleKinds = {
CAR = { label = 'Cars & Trucks', short = 'Cars', classes = { 'X', 'S', 'A', 'B', 'C', 'D' } },
MOTORCYCLE = { ... },
BOAT = { ... },
AIRCRAFT = { ... },
}Default kind when a track does not specify one.
Config.DefaultVehicleKind = 'CAR'Config.Vehicles maps spawn hashes to race metadata:
| Field | Meaning |
|---|---|
class | Racing class (must exist under that kind’s ladder) |
kind | CAR | MOTORCYCLE | BOAT | AIRCRAFT |
name / brand | Optional scan UI labels |
model | Optional spawn name override |
The shipped list is large. Add addon cars the same way, or override lookup with ResolveVehicleClass in server/edit.lua.
Config.Vehicles = {
[`adder`] = { class = 'S', kind = 'CAR', name = 'Adder', brand = 'Truffade' },
}Minimum checkpoints and approximate length (meters) required to save a track in the builder.
Config.MinCheckpoints = 3
Config.MinTrackLength = 200.0Lap limits for circuit / drift hosting UI.
Config.MinLaps = 1
Config.MaxLaps = 10Permissions
Minimum racing rep to create tracks. Admins, TrackCreatorWhitelist, and gs_racing_creators rows bypass this.
Config.TrackCreateMinRep = 100Identifiers always allowed to create tracks (citizenid on QB/Qbox, identifier on ESX).
Config.TrackCreatorWhitelist = {
-- 'CITIZENID_or_ESX_identifier',
}Identifiers treated as racing admins (verify tracks, manage creators, force tools), in addition to ACE / framework admin.
Config.AdminIdentifiers = {
-- 'CITIZENID_or_ESX_identifier',
}ACE permission (not a group name) that grants racing admin. Use 'admin' or 'command' (QBCore’s group.admin grants command). Also accepts framework admin/god/mod (and ESX admin/superadmin).
Config.AdminAce = 'admin'When true, only verified tracks (or the creator’s own drafts) can be hosted. When false, any non-deleted track can be hosted.
Config.RequireVerifiedTrackToHost = falseSee also Economy & permissions.
Race economy & pacing
How the prize pot is split among finishers.
| Value | Meaning |
|---|---|
EVEN | Equal split |
NORMAL | Place-weighted |
TOP | Heavy top bias |
TOP3 | Uses Top3Shares for 1st / 2nd / 3rd |
Config.PrizeDistribution = 'TOP3'
Config.Top3Shares = { 0.55, 0.30, 0.15 } -- renormalized if fewer finishersSeconds of countdown after start is triggered, before GO.
Config.CountdownDuration = 30When countdown remaining hits this many seconds, freeze vehicles on the grid.
Config.FreezeAtRemaining = 10Collision phasing (ghosting) after GO so the pack can sort without pile-ups. Full behaviour: Tracks & races → Phasing.
| Option | Meaning |
|---|---|
PhasingEnabled | Master on/off for new races |
PhasingDuration | Seconds from GO (0 = entire race). Stored on each race as phasing_seconds |
PhasingMode | Reserved selector: ALL | COMPETITION | NORMAL (currently all racers phase when enabled) |
Config.PhasingEnabled = true
Config.PhasingDuration = 30
Config.PhasingMode = 'ALL'Minimum joined racers before a player host can start. Auto events use Config.AutoEvents.minParticipants instead.
Config.MinParticipantsToStart = 1After the first finisher, remaining racers have this long (ms) before forced DNF.
Config.DnfGraceMs = 120000 -- 2 minutesHost UI caps and defaults for money.
| Option | Meaning |
|---|---|
MaxEntryFee | Hard cap on entry fee in the host sheet |
MaxHostContribution | Hard cap on starting pot (bank seed into the purse) |
DefaultEntryFee | Suggested entry fee when opening host UI |
DefaultHostContribution | Suggested starting pot (0 = none). Charged from host bank; refunded if cancelled before payout |
Config.MaxEntryFee = 100000
Config.MaxHostContribution = 500000
Config.DefaultEntryFee = 500
Config.DefaultHostContribution = 0Refund behaviour.
Config.JoinRefundOnCancel = true -- lobby cancelled
Config.RefundEntryOnDisconnect = true -- disconnect while JOINED / RACINGHard race timeout from GO (ms). Forces DNF + finalize for anyone still out.
Config.RaceTimeoutMs = 45 * 60 * 1000 -- 45 minutesWhen only one racer remains, idle this long (ms) between checkpoint hits before DNF (anti-AFK on empty grids).
Config.SoloCheckpointIdleMs = 60000Reputation & skill bonuses
Racing reputation stored in gs_racing_profiles.
| Key | Meaning |
|---|---|
finish | Awarded for finishing |
win | Awarded for 1st |
participate | On join; clawed back if they leave lobby / disconnect-leave |
placeBonus | Extra rep for 1st / 2nd / 3rd |
Config.Rep = {
finish = 5,
win = 25,
participate = 2,
placeBonus = { 15, 10, 5 },
}System-funded podium prize bonus % from racing rep (not taken from the pot). Highest matching tier wins. Export: GetSkillWinBonusPercent.
Config.SkillWinBonusTiers = {
{ minRep = 100, bonus = 5 },
{ minRep = 400, bonus = 10 },
{ minRep = 1000, bonus = 15 },
{ minRep = 2000, bonus = 20 },
}Seasonal standings
Wipes season standings (racing_rep / wins / races_completed) on a schedule. When enabled, Standings UI shows the next season start. Narrative: Economy & permissions → Seasonal standings.
| Option | Meaning |
|---|---|
enabled | Master toggle (default off) |
interval | Season length — one of days, months, or years |
wipeTrackTimes | Also wipe course timesheets (gs_racing_results) |
announce | Fire OnRacingAnnouncement (kind = 'season') on wipe |
Config.SeasonalStandings = {
enabled = false,
interval = { months = 3 },
wipeTrackTimes = false,
announce = true,
}First resource start with enabled = true auto-stores the season anchor in gs_racing_meta (no wipe). Later boundaries apply on resource start / every minute. Force wipe: /racingseasonwipe (admin).
Meetups
Scheduled car-meet zones that grant racing skill/rep while players hang out. Narrative + examples: Meetups & drift.
| Option | Meaning |
|---|---|
enabled | Master toggle |
durationMinutes | How long each meetup window lasts |
requireVehicle | Must be in a vehicle to earn ticks |
tickSeconds | Interval between skill ticks while inside the zone |
skillPerTick | Rep / skill granted per tick |
maxSkillPerWindow | Cap skill earned per meetup window |
maxZDelta | Max vertical distance from zone Z (blocks floors above/below) |
announceMeetups | Call OnRacingAnnouncement when a meetup starts (false = never) |
locations | Zones: id, label, coords, radius |
schedule | Real-clock slots: hour, minute, locationId |
Config.Meetups = {
enabled = true,
durationMinutes = 60,
requireVehicle = false,
tickSeconds = 60,
skillPerTick = 1,
maxSkillPerWindow = 30,
maxZDelta = 5.0,
announceMeetups = true,
locations = { { id = 'lsia', label = 'LSIA Meet', coords = vector3(...), radius = 150 } },
schedule = { { hour = 0, minute = 0, locationId = 'lsia' } },
}Auto events
System-hosted races (source = AUTO) created on a schedule. Full purse math and weights: Auto events.
Approximate seed:
seed ≈ (seedFlat + seedPerKm × raceKm) × typeMult × classMult × jitter
| Option | Meaning |
|---|---|
enabled | Master toggle |
announceNewRaces | Call OnRacingAnnouncement when auto races are created (false = never) |
minParticipants | Cancel + refund if under this after starts_at |
maxParticipants | Max grid size per auto race: false/nil = unlimited, number = fixed, { min, max } = random range |
cancelIfUnderMinMs | Wait this long after starts_at before cancel-under-min |
joinWindowMinutes | Lobby opens this many minutes before starts_at |
seedFlat / seedPerKm | System purse seed base + per race-km |
minSeedPot / maxSeedPot | Clamp seed |
seedJitter | ± random variance so identical courses vary |
typePotMult / classPotMult | Purse multipliers by track type / class (OPEN = any-class) |
entryFeeFlat / entryFeePerKm / min / max | Auto entry fee formula |
entryFeeClassMult | Entry fee class multipliers |
participation | Flat system bonuses (not from pot): finish / DNF |
targetLengthMinutes | Prefer tracks that roughly fit this race length |
maxPerGeneration | Max races inserted per schedule tick |
maxActive | Cap live AUTO races (0 = no cap) |
minStartSeparationMeters | Min 2D distance from any live race start (0 = off) |
minLaps / maxLaps | Lap range for CIRCUIT autos |
classWeights | Weighted class picks (ANY = open class) |
allowedTypes / allowedKinds | What can auto-generate (empty/omit = all) |
kindWeights / typeWeights | Optional pick weights |
firstStartOffsetMinutes | First race starts this many minutes after generation |
startJitterMinutes | ± jitter on start times |
schedule | nil = every hour on the hour; or custom generation slots |
Config.AutoEvents = {
enabled = true,
minParticipants = 1,
maxParticipants = { min = 6, max = 16 }, -- false = unlimited
joinWindowMinutes = 10,
maxActive = 4,
minStartSeparationMeters = 150,
schedule = nil,
-- ... see config.lua / Auto events page for full table
}Discord
Master toggle for Discord race announcement posts. The webhook URL is server-only — set Config.DiscordWebhook in server/edit.lua. Setup: Discord webhook.
Config.SendDiscordNotifications = falsePolice dispatch
Alert police when a hosted/auto race starts (server → dispatch pack only; never shown to racers). Override OnPoliceRaceDispatch in server/edit.lua for custom packs.
| Option | Meaning |
|---|---|
enabled | Master toggle |
resource | 'auto' = first started pack, or force ps-dispatch / cd_dispatch / cd_dispatch3d / qs-dispatch / rcore_dispatch / core_dispatch / lb-tablet |
when | 'countdown' | 'go' | 'both' |
chance | 0–100 roll per alert |
minParticipants | Skip dispatch below this grid size |
jobs | Job names or QB job.type values that should receive the alert |
priority | lb-tablet only: high | medium | low |
mdt / mdts | Optional lb-tablet MDT target(s); else uses jobs |
code / title / message | Alert text (message supports %s track, %d count, %s kind) |
blip | Map blip: sprite, color, scale, length (minutes), flash, radius |
coordsOffset | Randomize blip away from exact start (meters) |
Config.Dispatch = {
enabled = true,
resource = 'auto',
when = 'countdown',
chance = 100,
minParticipants = 1,
jobs = { 'police', 'leo', 'sheriff' },
priority = 'medium',
code = '10-94',
title = 'Street Racing',
message = 'Illegal street race starting near %s — %d vehicles (%s).',
blip = { sprite = 227, color = 1, scale = 1.25, length = 5, flash = true, radius = 5 },
coordsOffset = 35.0,
}Client feel / join markers
| Option | Meaning |
|---|---|
JoinProximity | Draw join markers (and world card) for open races within this distance (m) |
JoinInteractDistance | Must be this close (m) to press join / host start |
JoinKeybind | Control index to join (default 38 = E / pickup) |
HostStartKeybind | Control index for host to start at the circle (default 47 = G) |
JoinCircleRadius | Visual join circle radius (m) |
JoinWorldCard | Floating DUI race-info card at start points (true / false; replaces DrawText3D when on) |
CheckpointWorldLabels | Floating DUI CP/countdown labels; suppresses native chevron/flag icons when on |
LobbyLeaveDistance | Auto-leave lobby if you wander this far (m) from start |
LobbyLeaveGraceMs | Grace (ms) after joining before leave-distance applies |
Control labels resolve from the player’s binds. Indices: FiveM controls.
Config.JoinProximity = 60.0
Config.JoinInteractDistance = 15.0
Config.JoinKeybind = 38
Config.HostStartKeybind = 47
Config.JoinCircleRadius = 8.0
Config.JoinWorldCard = true -- false = classic 3D text labels
Config.CheckpointWorldLabels = true -- false = no floating CP distance cards
Config.LobbyLeaveDistance = 50.0
Config.LobbyLeaveGraceMs = 4000The world card is a single on/off switch for server owners. When enabled, it shows track, vehicle, prize, timer, and participant count at the nearest joinable start within JoinProximity. See Tracks & races → Joining.
CheckpointWorldLabels shows distance cards above the next few race checkpoints (with a stem line to the gate). Native checkpoint tubes/rings still draw as usual.
Checkpoints
Defaults used when a kind entry does not override them.
| Option | Meaning |
|---|---|
CheckpointRadius | Visual / sizing radius (m) |
CheckpointProximity | Distance (m) to count a hit |
Config.CheckpointRadius = 15.0
Config.CheckpointProximity = 8.0Per-kind visuals + hit sizing. style = 'cylinder' = ground tube; style = 'ring' = aerial gate (aircraft).
| Field | Meaning |
|---|---|
arrowType / finishType | Native checkpoint type ids |
radius / proximity | Size + hit distance for that kind |
height / zOffset / zSlack | Vertical placement / tolerance |
spherical | Full 3D hit (aircraft); not a flat ground disk |
Config.CheckpointByKind = {
CAR = { style = 'cylinder', radius = 15.0, proximity = 8.0, ... },
AIRCRAFT = { style = 'ring', spherical = true, radius = 40.0, proximity = 32.0, ... },
}Audio toggles.
Config.CheckpointSoundEnabled = true -- hit checkpoint
Config.FinishSoundEnabled = true -- finish line
Config.RaceAudioEnabled = true -- Arena War / stunt frontend cuesMap blips.
Config.StartBlip = { sprite = 315, color = 5, scale = 0.85, label = 'Race Start' }
Config.CheckpointBlip = { sprite = 1, color = 27, scale = 0.7, route = true } -- route = GPS lineTrack creator controls & props
Control indices for the in-world builder. World prompts use {place} / {finish} / {undo} / {prop} / {cycle} tokens. Props: hold ObjectPlacingFirstKey + PointPlacingKey to open the 3D gizmo.
Config.PointPlacingKey = 38 -- place checkpoint
Config.PointAndObjectDeletingKey = 36 -- undo / delete
Config.FinishPlacingKey = 47 -- place finish
Config.ObjectPlacingFirstKey = 21 -- hold + place for gizmo
Config.ObjectDistanceIncreaseKey = 172
Config.ObjectDistanceDecreaseKey = 173
Config.ObjectRotationFirstKey = 174
Config.ObjectRotationSecondKey = 175
Config.ObjectChangingKey = 19 -- cycle propProps the builder can place. kinds limits which track vehicle kinds see the prop (omit = all kinds). Plain strings still work and are available for every kind.
Config.PlaceableObjects = {
{ model = 'prop_mp_cone_02', label = 'Traffic Cone', kinds = { 'CAR', 'MOTORCYCLE', 'AIRCRAFT' } },
{ model = 'prop_dock_bouy_1', label = 'Dock Buoy (Small)', kinds = { 'BOAT' } },
}Drift scoring
Client feel for DRIFT race mode (finish order by score, not lap time). More context: Meetups & drift.
| Option | Meaning |
|---|---|
minSpeedMs | Min speed (m/s) to count as drifting |
minAngle / maxAngle | Slip angle window (degrees) |
scorePerSecond | Base points per second while drifting |
comboStep | Mult gain per second while drifting |
comboGoodBonus | Extra mult/sec scaled by angle quality |
comboHandbrakeBonus | Extra mult/sec with handbrake |
maxCombo | Mult cap |
crashResetMs | Reset combo after impact |
centerGraceMs | Keep chain briefly while centered (direction swap) |
Config.Drift = {
minSpeedMs = 8.0,
minAngle = 12.0,
maxAngle = 90.0,
scorePerSecond = 100,
comboStep = 0.35,
comboGoodBonus = 0.55,
comboHandbrakeBonus = 0.25,
maxCombo = 12.0,
crashResetMs = 800,
centerGraceMs = 2000,
}