Pepper Racing
Racing tablet with a legal club and an underground scene – starting grid with start lights, race control, protests, ghosts, crews, seasons and a track editor for ESX, QBCore and Qbox.
Overview
Pepper Racing brings motorsport roleplay to your server: players open the racing tablet (item racing_tablet) and
race either in the bright Pepper Racing Club (legal, bank account, race control, protests) or in the dark
Underground (alias, dirty money, secret meetup, police alerts). Every race starts with a real starting grid and start
lights, an automatic steward penalizes shortcuts, and race control – an RP role – can hand out penalties, make
announcements and wave the red flag. Players build tracks themselves in the editor – tracks by non-admins go through
track approval first.
Features
- 6 modes: sprint, circuit (1–50 laps), elimination, drag, drift, time trial
- Two worlds in one tablet: bright club ↔ dark neon underground, switch at the top of the tablet
- Starting grid with up to 16 slots (by rating, sign-up or random), marker + GPS, 90 s to get there
- Start lights: 5 red lights with a random hold (F1) or a christmas tree with jump-start detection (drag)
- Steward: corridor detection (warning → 5 s time penalty), checkpoint order, server-side plausibility checks
- Race control as an RP role: live map, timing, time penalties, disqualification, red flag, announcements, incident log
- Protests (club): 120 s protest window, provisional → official result, prize money and rating only after that
- Live HUD: timing tower, delta to your best, sector times purple/green/yellow, mini map, tires, drift meter – freely movable
- Ghost (your personal best or the track record) and ideal line of the record lap
- Tire wear + pit stops on circuits with 3+ laps: compounds, blowouts, timing stop, speed limit, crew as pit team, mandatory stop – all configurable and optional per race (pit stop 2.0 from the next version, already in the code), photo finish below 0.1 s
- Performance classes D/C/B/A/S/X calculated from vehicle stats incl. tuning (PI 100–999)
- Underground: district + time instead of a location, meetup revealed via GPS 2 min before the start, scene heat per district, police alerts, street rep
- Underground career: jobs (courier run, speed-camera hunt, drift zone, shake the tail, rival duel) and 6 street rep tiers that unlock bets, pink slips and hard jobs (
config/missions.lua,Config.StreetRep) - Betting (pari-mutuel with live odds) and pink slips (can be enabled by the server owner, off by default)
- Crews/teams, racer rating (Elo) with 6 ranks, seasons with rewards, knockout tournaments and championships
- In-game track editor with record mode, pit lane, camera preview and track approval
- Broadcast overlay for streamers and commentators, Discord webhooks, 3 server exports
- German & English with German motorsport terms, open config, locales and bridges
Requirements
| Dependency | Required/optional | Used for | Link |
|---|---|---|---|
| FiveM server build ≥ 7290 | required | declared in fxmanifest.lua as /server:7290 |
https://runtime.fivem.net/artifacts/fivem/build_server_windows/master/ |
| OneSync | required | starting grid, race steward, spectators | https://docs.fivem.net/docs/scripting-reference/onesync/ |
| ESX Legacy, QBCore or Qbox | required (one of them) | money, jobs, identifiers, vehicle ownership – Config.Framework = 'auto' detects it |
https://github.com/esx-framework/esx_core |
| ox_lib | required | UI building blocks, callbacks | https://github.com/overextended/ox_lib |
| oxmysql | required | database (MySQL/MariaDB) | https://github.com/overextended/oxmysql |
| Inventory: ox_inventory, qb-inventory (also ps-/lj-inventory) or the default ESX inventory | required (one of them) | items racing_tablet, race_license, race_usb |
https://github.com/overextended/ox_inventory |
| Dispatch (ps-dispatch, cd_dispatch, qs-dispatch, rcore_dispatch, core_dispatch) | optional | police alert for underground races – without one the built-in alert is used | – |
| Vehicle keys (qbx_vehiclekeys, qb-vehiclekeys, wasabi_carlock, MrNewbVehicleKeys) | optional | handing over keys for pink slips (bridge/server/vehicles.lua) |
– |
Installation
- Download the resource from the Cfx.re Portal (Granted Assets)
- Extract it to
resources/[pepper]/pepper_racing– do not rename - Add the items (see below)
- Database: tables are created automatically on first start. Without CREATE permission, import
install/pepper_racing.sqlfirst - Check
config/config.lua(language, permissions, money) andconfig/server.luafor webhooks and pink slips - Add to
server.cfgafter the dependencies:
ensure oxmysql
ensure ox_lib
ensure es_extended # or qb-core / qbx_core
ensure ox_inventory # or your inventory
ensure pepper_racing
- Start the server – the console shows
Pepper Racing … started (framework: …, tracks: 4, season: …)– on first start the script installs 4 default tracks - Build your own tracks in-game in the editor (tablet → Tracks → New track)
Items
| Item | Purpose |
|---|---|
racing_tablet |
opens the racing tablet (usable) |
race_license |
"race director license" – default permission to create races |
race_usb |
"underground stick" – optional underground access (Config.Illegal.AccessItem) |
| Inventory | File | Where |
|---|---|---|
| ox_inventory (ESX, QBCore, Qbox) | install/ox_items_en.lua (EN) or install/ox_items.lua (DE) |
entries into ox_inventory/data/items.lua before the last } |
| qb-inventory / ps- / lj-inventory | install/qb_items.lua |
entries into qb-core/shared/items.lua (QBShared.Items) |
| default ESX inventory | install/esx_items.sql |
import into the database |
With ox_inventory the tablet needs server = { export = 'pepper_racing.racing_tablet' } – it is already in the item files.
The item images are included in install/images/ (racing_tablet.png, race_license.png, race_usb.png) – copy them into your inventory's image folder.
First test
- As admin give yourself the
racing_tabletitem (e.g. via your inventory admin menu) and use it - Under Tracks check that the 4 default tracks were installed (Sandy Shores Short Loop, Grand Senora Loop, two drag strips)
- Under Create set up a sprint or circuit race starting "now" and sign up with the vehicle you're sitting in
- Drive to the marked grid slot, wait for the start lights and finish the race – the result shows up in the tablet
Configuration
| File | Contents |
|---|---|
config/config.lua |
language, framework, item, permissions, races, grid, lights, steward, protests, money, betting, underground, police, rating, season, crews, events, ghost, tires, drift, editor, HUD |
config/vehicles.lua |
fixed classes per model, blocked models and GTA vehicle classes |
config/server.lua |
webhooks, pink slips, sponsor bonus, admin ACE (never sent to clients) |
Key options:
| Option | Default | Description |
|---|---|---|
Config.Locale |
'de' |
language (de / en) |
Config.Framework |
'auto' |
auto, esx, qbcore, qbox, standalone |
Config.Item |
'racing_tablet' |
item that opens the tablet |
Config.Command |
false |
optional command (e.g. 'racing') – opens the tablet without the item |
Config.Races.MaxRacers |
16 |
max racers per race (2–16) |
Config.Grid.Order |
'rating' |
grid order: rating, signup, random |
Config.Grid.Teleport |
false |
put racers straight onto their slot |
Config.Steward.CutPenalty |
5 |
time penalty (s) for a shortcut |
Config.Protest.Window |
120 |
protest window (s) after the race |
Config.Economy.HouseCut |
0.05 |
share of the prize pot that is kept |
Config.DirtyMoney |
ESX black_money, QB/Qbox cash |
account for underground money per framework |
Config.Illegal.HiddenForJobs |
police, sheriff, state |
these jobs never see the underground |
Config.Police.Dispatch |
'auto' |
police alert: auto, builtin, an integration or false |
Config.Season.Days |
30 |
season length |
Config.Hud.Units |
'kmh' |
kmh or mph |
How a race works
- Create: tablet → Create: mode, track, laps, class limit, max racers, entry fee, prize split, options (collisions/phasing, ghost, ideal line, tires, betting, private with code), start time (now or in 2–30 min)
- Join: players join with the vehicle they are sitting in – the server checks class and block list
- Underground: the meetup is revealed via GPS 120 s before the start
- Starting grid: entry fees are charged, everyone gets a grid slot (90 s) – no-shows are DNS and get their fee back
- Start lights: 5 red lights, then "lights out" (drag: christmas tree, rolling before green = red light)
- Race: checkpoints in order, the steward watches for shortcuts, race control can step in; leaving the vehicle for more than 15 s = DNF
- Finish: after the first racer finishes, the others have 120 s; photo finish flag below 0.1 s
- Result: club – provisional, 120 s protest window, then official; underground – official right away. Prize money, bet payouts, rating, season points and street rep only come with the official result
Red flag, too few racers or a resource restart refund entry fees and bets immediately.
Track editor
| Key | Function |
|---|---|
E |
place checkpoint |
Backspace |
remove last checkpoint |
Mouse wheel / ← → |
change width (6–40 m) |
G |
grid slot at your current vehicle position (max. 16) |
H |
pit lane: entry → box → exit (circuits only) |
R |
record mode on/off (a checkpoint every 60 m) |
F |
camera preview |
Enter |
save |
X |
cancel |
Change keys in Config.Keys (GTA control IDs). Track types: circuit, sprint, drag (exactly 2 checkpoints, 2 grid slots,
max. 1000 m), drift. Area: club, underground or both.
Underground
- Access: job not in
Config.Illegal.HiddenForJobs, optionally the itemrace_usb - Races only show district and time, racers use their alias, money comes from
Config.DirtyMoney - Scene heat per district (0–100): every race +18, decays 1 per minute, warning "scene is being watched" from 60
- Police alert at the start: 15 % + heat × 0.6 % (max. 85 %), blip for 90 s
- Jobs (tab in the underground tablet): 3 offers with difficulty, reward in dirty money + scene rep, daily limit; values in
config/missions.lua - Street rep tiers (6 tiers,
Config.StreetRep) cap bets (BetLimit) and unlock pink slips from tier 3 – admins excepted
Pink slips
Off by default. With pink slips both racers bet their own vehicle – the winner gets the loser's vehicle permanently (ownership change in the database). Only enable it if it fits your server rules.
Enable in config/server.lua: ServerConfig.PinkSlips = { Enabled = true, Table = 'auto' } (owned_vehicles on ESX,
player_vehicles on QBCore/Qbox). Underground only, exactly 2 racers, no entry fee, the server checks ownership and
plate, both confirm twice. Keys are handed over via qbx_vehiclekeys, qb-vehiclekeys, wasabi_carlock or MrNewbVehicleKeys –
add your own system in bridge/server/vehicles.lua.
Dispatch and webhooks
Dispatch
Config.Police.Dispatch = 'auto' uses the first running integration: ps-dispatch, cd_dispatch, qs-dispatch,
rcore_dispatch, core_dispatch. Without one, every player with a job from Config.Police.Jobs gets a notification and a
blip. false disables alerts. Adjustable in bridge/server/dispatch.lua.
Webhooks
In config/server.lua ('' = off):
| Key | Content |
|---|---|
results |
official club results, track records, events, season end |
tracks |
submitted and reviewed tracks |
illegal |
underground results, police alerts, pink slips |
security |
steward suspicion reports |
Commands and permissions
Commands
| Command | Who | What |
|---|---|---|
Config.Command (off by default, e.g. 'racing') |
everyone | opens the tablet without the item |
/racingrep <ID> <+/-amount> · /racingrep <ID> set <value> |
admin | give or set scene rep (Config.StreetRep.AdminCommand) |
By default the tablet opens via the racing_tablet item.
Admin tasks (track approval, ending/starting seasons, locking tracks) live in the tablet's admin section.
Permissions
Permissions are checked again on every server call. Admin = ACE pepper_racing.admin or a group from
Config.AdminGroups (admin, superadmin, god) – admins have every permission.
| Permission | For | Default |
|---|---|---|
createRace |
create races and events | admin group or item race_license |
createTrack |
build tracks in the editor | admin group |
approveTrack |
track approval | admin group |
control |
race control for all races | admin group (organizers always control their own race) |
Each permission can be granted via ace, groups, jobs (job + minimum grade), items or everyone = true:
add_ace group.admin pepper_racing.admin allow
add_ace group.mod pepper_racing.control allow
add_ace group.mod pepper_racing.approveTrack allow
Exports and framework integration
Exports (server)
-- server, read-only
exports.pepper_racing:getProfile(src) -- public racer profile or nil
exports.pepper_racing:isRacing(src) -- true on the grid, during the lights or in a race
exports.pepper_racing:getActiveRaces() -- list of active races
Framework integration
bridge/server/{esx,qbcore,qbox,standalone}.lua provide money, job and identifier, bridge/server/inventory.lua items
(ox_inventory, qb-/ps-/lj-inventory, ESX), bridge/server/vehicles.lua vehicle ownership and keys,
bridge/server/dispatch.lua the police alert. All bridges are open.
Troubleshooting
| Problem | Solution |
|---|---|
| Tablet does not open | Item added? With ox_inventory server = { export = 'pepper_racing.racing_tablet' }; do not rename the folder |
| "Timing is still starting up" | Database not reachable – start oxmysql before pepper_racing, check the console |
| "No matching track" | No approved track for this mode yet – build or approve one |
| Underground missing | Job is in HiddenForJobs, or AccessItem is set and missing |
| Racer "did not start (DNS)" | Not on the grid slot within 90 s – raise Config.Grid.Time or set Teleport = true |
| Vehicle blocked / wrong class | config/vehicles.lua: BlockedModels, VehicleClasses |
| Pink slips cannot be selected | ServerConfig.PinkSlips.Enabled; the console warns if the vehicle table is missing |
| Police get no alert | Config.Police.Jobs, Config.Police.Dispatch; alerts are based on a chance |
FAQ
Are tracks included?
Yes, 4 tracks: Sandy Shores Short Loop, Grand Senora Loop (circuits), Sandy Shores Airfield Drag and LSIA Runway Drag. They are installed on first start as long as no track exists yet (install/default_tracks.json, disable with Config.Tracks.InstallDefaults = false). You build more tracks in the editor anywhere on the map.
Do I need addon vehicles?
No. Every vehicle – addon vehicles too – gets its class automatically from its own stats including tuning. Fixed classes go into Config.VehicleClasses (config/vehicles.lua).
The tablet doesn't open.
The item must be registered in your inventory – with ox_inventory including server = { export = 'pepper_racing.racing_tablet' }. Don't rename the folder, and start your framework and inventory before pepper_racing. Alternatively Config.Command = 'racing' opens the tablet without the item.
The message "Timing is still starting up" doesn't go away.
The database can't be reached: start oxmysql before pepper_racing and check the console. Without CREATE permission import install/pepper_racing.sql first.
Who can create races?
By default admins and everyone with the race director license item (race_license). Change it in Config.Permissions.createRace – e.g. for a job or with everyone = true for everyone.
Does race control have to be online?
No. The race steward works automatically, and without a decision the result becomes official after the protest window (Config.Protest.Window, 120 s).
What happens on a server restart mid-race?
Running races are aborted, entry fees and bets are refunded. Profiles, tracks, best times, ghosts, crews and seasons are stored in the database.
Are pink slips dangerous for my server economy?
Pink slips are off by default. When enabled, vehicles change owner for good – the server checks ownership and plate first, both drivers confirm twice, and they only exist in the underground, 1 vs 1, from street rep tier 3.
Can the police see the underground?
No. Jobs from Config.Illegal.HiddenForJobs (police, sheriff, state) don't see the underground at all. The police only learn about races through the police alert.
The underground entry fee is missing (QBCore/Qbox).
There Config.DirtyMoney uses regular cash (cash). Enter your own account or use dirty money as an item (Config.DirtyMoney.Item, e.g. markedbills).
How does the rating work?
Elo rating starting at 1000: beating stronger opponents earns more points. Races with at least 2 drivers count, time trials don't. At the end of a season the distance to 1000 is halved.
Can I show mph instead of km/h or change texts?
Config.Hud.Units = 'mph' switches the unit, Config.Locale = 'en' the language (then use the items from install/ox_items_en.lua). All texts are open in locales/de/*.json and locales/en/*.json.
How do I show a race on stream?
While a race is running, choose Spectate in the race view – the broadcast overlay shows a large timing tower and the lap counter, without the tablet.
How do I install an update?
Replace the pepper_racing folder and back up your changes to config/ and locales/ first. The server creates new tables (e.g. pepper_racing_missions) on start; what changed is listed in CHANGELOG.md.
Support
Open a ticket on Discord: https://discord.gg/6NaFJWKDYu (category "Script Support") – link your purchase with /verify first.
Permanently tested on the Pepper Scripts dev server.
Changelog
Current version: 1.2.0 (2026-10-25). All changes are listed on the updates page and in CHANGELOG.md inside the resource.
Found a mistake? Report it on Discord.