For the complete documentation index, see llms.txt. This page is also available as Markdown.

Configuration

Everything is configured from the config/ folder. The files are open (not escrow-locked), so you can edit them freely.

File
What it holds

config/config.lua

The main file — framework, locale, economy multipliers, prompts, commands, admins, clothing, notifications

config/data/regions.lua

Region rewards, region definitions, XP curve, job NPC, blips, daily missions

config/data/notifications.lua

Notification type per message key (text itself lives in locales/)

config/data/map_baseline.lua

Terrain heights under each site, used to spot map / MLO conflicts — nothing to configure

config/data/job12_sites.json

Region 12 drop-offs added in game with /j12site — written by the editor, no need to edit by hand

config/economy.lua

Optional money/XP model derived from work volume

config/keybinds.lua

Machine control keys (crane, pump, tower crane)

config/coordinate.lua

Shared coordinates

config/jobs/*.lua

Per-region job settings

config/systems/*.lua

Feature systems (tutorial, rental, leaderboard, crane, pump...)

config/secrets/discord.lua

Server-only — your Discord webhook URLs and bot token

config/bridges/*.lua

Framework bridges — nothing to configure

config/gate/*.lua

Internals: auto-detection and command gating — nothing to configure

config/gate/auto_detect.lua and config/blueprint_loader.lua are marked "nothing to configure here" in the source. They resolve the auto values and load blueprints. Leave them alone.


Core Settings

-- Framework: auto | qb | oldqb | qbox | esx | oldesx | vrp | vrp2 | tmc | standalone
-- 'auto' detects it from the running resources; a value set by hand always wins.
-- 'qbox' uses the 'qb' bridge (qbx_core compat layer).
Config.Framework          = 'auto'

-- Inventory: auto | qb_inventory | esx_inventory | ox_inventory
--            | codem-inventory | qs_inventory | tgiann-inventory
Config.Inventory          = "auto"

-- Path for craft/reward item icons. 'auto' = derived from the selected inventory.
Config.InventoryImagePath = "auto"

Config.SQL                = "oxmysql"

-- Server default only — players pick their own language in the menu.
Config.Locale             = 'en'

-- CurrencySymbol is what the UI prints next to an amount.
-- MoneyAccount is the framework account the money is added to (bank / cash).
Config.CurrencySymbol     = "$"
Config.MoneyAccount       = "bank"

Config.ServerName         = "TWORST"
Config.ExampleProfilePicture = "https://.../LogoNEW.png"

The detection order is fixed in config/gate/auto_detect.lua: qbx_core → qb-core → es_extended → vrp → standalone for frameworks, and third-party inventories (ox_inventory, qs-inventory, codem-inventory, tgiann-inventory) before qb-inventory, because qb-inventory is often installed next to the one actually in use. Each detection prints what it picked to the console.


Economy Multipliers

Two global dials, both at the top of config.lua:

Setting
Effect

Config.RewardMultiplier

Multiplies money, xp, bonusExtraMoney and bonusExtraXP for every region at load time. 1.5 = 50% richer server-wide.

Config.DepositMultiplier

Multiplies every rental deposit in config/systems/vehicle_rental.lua. Set 0 to switch deposits off entirely.


Interaction Prompt

Value
What players see

'badge'

Our world-space badge with an icon — default

'text'

Plain 3D text, no badge

'oxlib'

ox_lib TextUI in the screen corner — matches the rest of your server

'ox-target'

Hands interaction over to ox_target

'qb-target'

Hands interaction over to qb-target

'auto'

Uses ox_target / qb-target if either is installed, otherwise falls back to 'badge'

For the three built-in styles (badge, text, oxlib) focus, distance and the E key behave identically — the only thing that changes is where the prompt is drawn. Pick on looks alone.

Tuning

The rest of config/systems/interaction.lua is fine-tuning — geometry, fonts and cadence — and rarely needs touching:

Config.Interaction.badge, .pin, .label, .anim, .scale and .machine control the size, offset and animation of the badge itself.

label.asciiFold = 'tr' folds the Turkish letters GTA's in-game font cannot render (ı İ ğ Ğ ş Ş) down to ASCII. The NUI is a browser and is unaffected.


Release Profile

When true, these are force-disabled no matter what they say elsewhere: Debug, DebugCommands, DebugZoneDraw, DebugZones, DebugTowerScenery, RopeProbe, Profiler, FastTest, SoloTest — and the per-region test trims are zeroed, so every region plays at full size.

Setting
What it does

Config.Debug

Diagnostic logs + per-frame measurement loops (animcontrols, rental). false on a live server.

Config.DebugCommands

Registers the debug command set. Release blocker.

Config.DebugZoneDraw

Draws zone polygons — ~75 µs/frame. Only to check a boundary.

Config.SoloTest

Relaxes crew/vehicle caps so one person can test.

Config.FastTest

Auto-spawns vehicles and skips the whole rental flow. Dev only.

Config.Profiler

Event/network profiler, writes profiler_logs/*.json.


Lobby & Crew

Commands

Rename these freely. Debug commands never go through this table.

Reward Split by Rank

Extra percentage for the highest-scoring crew members, by crew size. Applied to money and XP after the job split and damage deductions.

Reconnection

A disconnected player gets their lobby seat, task progress and reward share back within the window. If the owner drops, ownership transfers to another member.


Regions & Rewards

Regions moved out of config.lua — they now live in config/data/regions.lua.

Rewards — the single source

All money and XP live in one table, keyed by regionID:

Key
Meaning

money

Paid to the crew that finishes the job

xp

Experience earned

onlineJobExtraAwards

1 = apply the bonuses below

bonusExtraMoney / bonusExtraXP

Added per crew member

Config.RewardMultiplier is applied to this whole table as it loads, and config/economy.lua can overwrite it entirely when enabled.

Region 9 — a small crew only builds its share of the site, so the region card shows your crew's share of the reward, and that is exactly what gets paid.

Region Definitions

TL() resolves a locale key at load time with a fallback. Set both regionName and regionNameKey when you add a region: the resolved name freezes to the server's language, while the key is what each player's client resolves in their language.


Levels

70 levels are defined in config/data/regions.lua. Each region can require a minimum level via regionMinimumLevel.


Job NPC & Blips

In config/data/regions.lua:

Set job to a framework job name to restrict the script to that job, or leave 'all'. missionBlips styles the in-job task markers, and missionBlips.vehicleBlips styles the rental vehicle marker.

Restricting the job to a framework job

Works on QBCore and ESX alike; both job shapes are read. This is separate from Config.Job.job, which controls who sees the NPC and blip in the first place.


Languages

14 languages ship with the script:

English (en)

Türkçe (tr)

Deutsch (de)

Español (es)

Français (fr)

Magyar (hu)

日本語 (ja)

Nederlands (nl)

Português (pt)

Română (ro)

Русский (ru)

Svenska (sv)

Slovenščina (sl)

中文 (zh)

Config.Locale sets the server default only — every player picks their own from the menu.

Adding your own language

  1. Copy locales/en.lua to locales/<code>.lua

  2. Translate the values (leave the keys alone)

  3. Optionally add a display name so the menu shows it properly:

A code with no entry in Config.LanguageNames is simply shown uppercased.


Notifications

Text and type

The wording lives in locales/*.lua. config/data/notifications.lua only maps each key to a type:

Edit wording in the locale files, not here. This file is only for changing whether a message shows as info, success or error.

Burst filter

One player action often fires several notifications at once. Two rules keep the screen readable:

error and success always pass. Keyed notifications (progress counters, which update in place) skip the filter entirely. Set enabled = false to turn the whole thing off.

Config.NotifyFilter is the function implementing this — replace it if you want different rules.

Sending through your own notification script

Point this at your own notify export to route every message through your server's notification system.


Changing Room

New in the HQ: players change into work clothes inside a marked room rather than instantly on job start.

Key
Meaning

required

true = the player must change before the job starts; false = optional

points / zMin / zMax

The room polygon and its height range

anchor

Where the player is placed for the change animation

blip

Map marker for the room

anim

The changing animation and its fade timings

The room is part of the tw-builder-map HQ interior. If you move the HQ, move these coordinates with it.


Clothing

The outfit comes from Config.JobClothes and is applied through skinchanger / esx_skin events plus Config.RefreshSkin. If your clothing script differs, edit Config.RefreshSkin to match your own call.


Discord Logging

minGapMs, maxQueue and maxRetries are the rate limiter — they keep a busy server from flooding Discord.

Webhook URLs — config/secrets/discord.lua

The URLs live in a server-only file, one channel per category:

An empty category falls back to default. If default is empty too, that category is simply off — and leaving everything empty is a perfectly valid setup: no URL means no request is ever made, and /builderadmin → Logs reads the same event stream from server memory either way.

You can also set these as convars in server.cfg instead — see Installation → Step 8. Use set, never setr.


Admins

Config.Admins gates both /builderadmin and the /tw_bp site builder — checked at the door and again on every write event. Run /cranesiteid in-game to print your own identifier.

See Interface for what the panel and the site builder actually do.

ACE permissions

New in v1.0.1 — an ACE permission is checked first, before the identifier list:

Grant it in server.cfg:


Vehicle Keys & Fuel

Key and fuel systems are auto-detected. Edit these functions if you run something unusual.


Job Hooks

Use these to plug the job into your own systems — a licence check before starting, a stat update on finish, and so on. Returning false from startJobFunction blocks the start.


World & Performance

ZoneExitGraceMs matters more than it looks: too short and a player walking the site boundary keeps tearing the scene down and rebuilding it.

Performance tuning lives in config/systems/perf_lod.lua and config/systems/perf_budget.lua.


Feature Systems

Everything under config/systems/:

File
Feature

interaction.lua

Prompt geometry, fonts and scan cadence (style is set in config.lua)

tutorial.lua

Training field, modules, per-job-type suggestions

vehicle_rental.lua

Rental lot, stock, deposit, damage penalty

leaderboard.lua

Top earners / most jobs, row limit

tower_crane.lua

Tower crane, cabin, ropes, scenery

vehicle_crane.lua

Mobile crane

pump.lua

Concrete pump

excavator.lua

Excavator

vehicle_anim_controls.lua

Arm and tipper controls for the excavator, tipper and mixer — custom models, bucket bone

rigger.lua / sling_profiles.lua

Rigging and sling behaviour

plank_stages.lua, panelwall.lua, job7.lua, job8.lua, job9.lua

Per-job mechanics

sound.lua / dui.lua

Site audio and prop screens

perf_lod.lua / perf_budget.lua

LOD levels and frame budget — these back the in-game Sync menu

Tutorial

Players practise the machines a region needs on a dedicated field before they work it.

Vehicle Rental

Each vehicle type has its own parking spot, stock and deposit in Config.RentalVehicles. Every deposit is then scaled by Config.DepositMultiplier.

Rental mode

rentalMode in config/systems/vehicle_rental.lua decides how vehicles are handed out:

Value
Behaviour

'spawn_point'

Vehicles wait in their bays on the company lot — default

'npc'

Players rent from the rental clerk NPC. Vehicles no longer wait on the lot — they spawn when rented. The clerk's map blip only shows while you are in a job.

The rental menu shows a photo of every vehicle. Vehicles you can't rent show a short reason — "Not used in this job", "Not needed yet".

Custom excavator / tipper / mixer

Arm and tipper controls live in config/systems/vehicle_anim_controls.lua. The bucket bone can be set by name or index — run /excbones in-game to find it. Full guide: docs/CUSTOM_EXCAVATOR.txt in the package.

Leaderboard

When disabled, the tab is hidden from the menu entirely.

Static Machines

Scenery machines that stand on a site but are never driven. They are listed in the region's UI info so players know what is waiting for them.


Economy Model (Optional)

config/economy.lua can derive money and XP from the work volume of each region instead of hand-written constants:

A long job earns more; a hard job (crane/machine work) earns more per second.


UI Theme

Change this one value to match your server's colours. Accept / deny colours, key caps, medals and reward colours stay as they are, so a reskin cannot break them.


UI Positions

These are only defaults — players move the HUD themselves from Settings → UI Move, and their layout is saved per player.

Last updated