NR_Towing
A multi-framework towing job system (ESX, QBCore, QBX) with auto-detection, flatbed mechanics, roadside repair missions, leveling, dispatch queue, in-app store, and a custom React UI.
Features
- Flatbed tow truck - Functional flatbed with bed tilt, vehicle loading, and impound delivery
- Dispatch queue system - Clock in at HQ, join the dispatch queue, and receive tow calls with configurable delay
- Leveling & XP - Earn XP per completed job, level up to 25 with scaling XP requirements, and unlock new content
- Roadside repair jobs - Low-level players (1-5) receive repair calls with minigames for tires, spark plugs, and batteries
- In-app store - Purchase repair items (tires, spark plugs, batteries) with level-gated access
- 14 breakdown locations - Pre-configured breakdown spots across the map with NPC peds, vehicle damage states, and varied reasons
- Vehicle damage states - Breakdowns feature engine failure, open doors, burst tyres, and low engine health
- Custom React UI - Dashboard with home, rank/leaderboard, and store tabs
- Job HUD - Progress tracking with mission name, status text, reason, and countdown timer
- Minigames - Timed skill-check minigames for tire changes, spark plug replacements, and battery swaps
- Flexible interaction - Supports ox_target/qb-target or built-in Press E proximity interaction
- NR_Tablet integration - Opens via NR_Tablet export or standalone keybind (F4)
- External UI support - Auto-detects is_ui, falls back to ox_lib, or uses built-in NUI prompts and progress bars
- Customizable theme - Configurable accent color for the entire UI
- Locale support - All notifications, HUD text, and interaction prompts are fully translatable
- Leaderboard - View top players ranked by level and XP
Dependencies
| Resource | Description | Required |
|---|---|---|
| es_extended / qb-core / qbx_core | Core framework (auto-detected) | One of these |
| ox_lib | UI library (callbacks, notifications) | Yes |
| oxmysql | MySQL database (leveling, player data) | Yes |
| Inventory system | ox_inventory, qb-inventory, ps-inventory, lj-inventory, codem-inventory, core_inventory, origen_inventory, and more (auto-detected) | One of these |
| ox_target / qb-target | Target interaction for HQ ped | Optional |
| NR_Tablet | Opens towing UI via tablet app | Optional |
Installation
Step 1: Download
Download NR_Towing from your Tebex purchase and extract it to your resources folder:
server/
└── resources/
└── [echo]/
└── NR_Towing/
Step 2: Add Inventory Items
Add the following items to your inventory system. Choose the format that matches your setup:
ox_inventory — Add to ox_inventory/data/items.lua:
['tow_tire'] = {
label = 'Tire',
weight = 500,
stack = true,
},
['tow_sparkplug'] = {
label = 'Spark Plug Kit',
weight = 200,
stack = true,
},
['tow_battery'] = {
label = 'Replacement Battery',
weight = 800,
stack = true,
},
qb-core — Add to qb-core/shared/items.lua:
tow_tire = { name = 'tow_tire', label = 'Tire', weight = 500, type = 'item', image = 'tow_tire.png', unique = false, useable = false, shouldClose = false, description = 'A replacement tire for roadside repairs' },
tow_sparkplug = { name = 'tow_sparkplug', label = 'Spark Plug Kit', weight = 200, type = 'item', image = 'tow_sparkplug.png', unique = false, useable = false, shouldClose = false, description = 'A spark plug kit for engine repairs' },
tow_battery = { name = 'tow_battery', label = 'Replacement Battery', weight = 800, type = 'item', image = 'tow_battery.png', unique = false, useable = false, shouldClose = false, description = 'A replacement battery for dead vehicles' },
Don't forget to add corresponding images (tow_tire.png, tow_sparkplug.png, tow_battery.png) to your inventory's image directory.
Step 3: server.cfg
Add the resource to your server configuration. ox_lib and oxmysql must start before NR_Towing:
ensure ox_lib
ensure oxmysql
ensure ox_inventory
ensure NR_Towing
Step 4: Configure
Edit config.lua to customize the towing job (see Configuration section below).
Step 5: Restart
Restart your server to load the resource. The database table for player levels will be created automatically.
If using NR_Tablet integration (Config.UsingNRTablet = true), make sure NR_Tablet is started before NR_Towing. If not using NR_Tablet, the UI opens with F4 by default.
How It Works
1. Clocking In
Head to the Towing HQ (marked on the map with a blip). Interact with the HQ ped to open the towing app. From the duty screen, clock in to start your shift. A flatbed truck spawns at the designated spawn point.
2. Joining the Dispatch Queue
Once on duty, hit the dispatch button from the dashboard. You'll enter the dispatch queue and receive a tow call after the configured delay (default: 120 seconds).
3. Tow Jobs (Level 6+)
After reaching level 6, you receive full tow calls. Drive your flatbed to the breakdown location, load the vehicle, then deliver it to the impound lot:
- Drive to the breakdown location (marked with a blip)
- Load the broken-down vehicle onto your flatbed
- Drive to the impound lot and drop off the vehicle
- Receive payment ($500-$1500) and XP
4. Repair Jobs (Level 1-5)
New players start with roadside repair calls using a speedo van instead of a flatbed. Repair jobs include:
| Repair Type | Required Item | Description |
|---|---|---|
| Flat Tire | tow_tire x1 |
Replace a single burst tire with a timed minigame |
| 2 Flat Tires | tow_tire x2 |
Replace two burst tires with timed minigames |
| Bad Spark Plugs | tow_sparkplug x1 |
Open the hood and install new spark plugs |
| Dead Battery | tow_battery x1 |
Open the hood and replace the dead battery |
Each repair has a timed minigame (default: 10 seconds). Failing the minigame breaks the part and you must try again.
5. Leveling Up
Earn XP for each completed job. The XP formula scales with your level:
XP needed = currentLevel x XPPerLevel
-- Example: Level 1 = 100 XP, Level 5 = 500 XP, Level 10 = 1000 XP
The max level is 25 by default. View your rank and the leaderboard from the Rank tab in the app.
6. In-App Store
Purchase repair items from the store tab. Items have level requirements and are paid with cash or bank funds:
| Item | Price | Min Level |
|---|---|---|
| Tire | $50 | 1 |
| Spark Plug Kit | $75 | 1 |
| Replacement Battery | $100 | 1 |
Configuration
General Settings
Config.Debug = false -- Enable debug logging
Config.Theme = '#C4B702' -- UI accent color (hex)
Config.Keybind = 'F4' -- Key to open UI (when not using NR_Tablet)
Config.UsingNRTablet = true -- Open via NR_Tablet export
Config.UsingTarget = false -- Use ox_target for HQ ped interaction
Config.UsingExternalUI = false -- Use external UI (is_ui / ox_lib fallback)
HQ & Flatbed
Config.HQPed = {
model = 's_m_y_xmech_02',
coords = vec4(408.9579, -1623.0558, 29.2919, 229.1624),
scenario = 'WORLD_HUMAN_CLIPBOARD'
}
Config.HQBlip = {
coords = vec3(408.9579, -1623.0558, 29.2919),
sprite = 68,
color = 5,
scale = 0.8,
label = 'Towing HQ'
}
Config.ClockInDistance = 3.0 -- Proximity to go on duty
Config.FlatbedSpawn = vec4(401.7856, -1632.3269, 29.2919, 136.5435)
Config.FlatbedModel = 'flatbed3'
Tow Truck Settings
Config.Trucks = {
[`flatbed3`] = {
attachVehBone = 'misc_a', -- Bone for vehicle attachment
attachOffset = vector4(0.0, 1.0, 0.7, 0.0), -- Attachment offset
maxBedMovement = 0.18, -- Maximum bed tilt range
bedSpeed = 0.0005, -- Bed tilt speed
},
}
Config.KeepPressedToMoveBed = false -- Hold vs toggle bed movement
Rewards & Leveling
Config.RewardMin = 500 -- Minimum payout per tow job
Config.RewardMax = 1500 -- Maximum payout per tow job
Config.XPPerJob = 50 -- XP earned per completed job
Config.MaxLevel = 25 -- Highest achievable level
Config.XPPerLevel = 100 -- XP multiplier per level
Dispatch
Config.DispatchDelay = 120 -- Seconds before receiving a dispatch call
Config.DropoffLocation = vec4(401.7856, -1632.3269, 29.2919, 136.5435)
Repair System (Level 1-5)
Config.RepairMaxLevel = 5 -- Max level for repair-only jobs
Config.RepairVehicle = 'speedo' -- Vehicle given for repair calls
Config.MiniGameTimers = {
tire = 10, -- Seconds to complete tire minigame
sparkplugs = 10, -- Seconds to complete spark plug minigame
battery = 10, -- Seconds to complete battery minigame
}
Store Items
Config.StoreItems = {
{ item = 'tow_tire', label = 'Tire', price = 50, minLevel = 1 },
{ item = 'tow_sparkplug', label = 'Spark Plug Kit', price = 75, minLevel = 1 },
{ item = 'tow_battery', label = 'Replacement Battery', price = 100, minLevel = 1 },
}
Adding Breakdown Locations
Add new entries to the Config.Breakdowns table. Each breakdown supports optional ped, engine damage, open doors, and burst tyres:
Config.Breakdowns = {
[15] = {
vehicle = {
coords = vec4(x, y, z, heading),
model = "Vehicle Name",
hash = `vehiclehash`,
engineHealth = 200, -- Optional: lower = more damaged
doors = { [4] = true }, -- Optional: door indices to open
tyres = { [1] = true }, -- Optional: tyre indices to burst
},
ped = { -- Optional: NPC at breakdown
coords = vec4(x, y, z, heading),
model = "ped_model",
hash = `ped_model`,
scenario = "WORLD_HUMAN_SMOKING",
},
fullname = "Customer Name",
reason = 'Reason for call',
},
}
Adding Repair Types
Add new entries to Config.RepairTypes for custom roadside repair scenarios:
Config.RepairTypes = {
[5] = {
id = 'custom_repair',
label = 'Custom Repair',
reason = 'Custom issue',
item = 'your_item',
itemLabel = 'Your Item',
itemCount = 1,
progressDuration = 5000,
progressLabel = 'Repairing...',
engineHealth = 200, -- Optional
openHood = true, -- Optional
tyres = {}, -- Optional
},
}
Locale / Translations
All text is defined in locales.lua. You can translate or customize every notification, HUD message, and interaction prompt. Key locale strings include:
| Key | Default Value |
|---|---|
Locale.wentOnDuty |
You are now on duty. |
Locale.jobStarted |
Tow call received! Head to your flatbed. |
Locale.jobCompleted |
Tow job completed! Payment received. |
Locale.vehicleAttached |
Vehicle secured on the flatbed. |
Locale.hookTaken |
Hook taken. Attach it to a vehicle. |
Locale.leveledUp |
You reached Level %s! |
Locale.purchasedItem |
Purchased %s! |
File Structure
NR_Towing/
├── config.lua -- All configuration (editable)
├── locales.lua -- All text/translations (editable)
├── fxmanifest.lua -- Resource manifest
├── Escrowed/
│ ├── client/
│ │ └── main.lua -- Client logic (escrowed)
│ └── server/
│ └── main.lua -- Server logic (escrowed)
└── web/
├── src/ -- React source files
└── build/ -- Compiled UI (used by NUI)
Troubleshooting
UI not opening
- If using NR_Tablet (
Config.UsingNRTablet = true), ensure NR_Tablet is running and started before NR_Towing - If using keybind mode, check that
F4isn't conflicting with another resource - Make sure you are near the HQ ped (within
Config.ClockInDistance) - Check F8 console for errors
Flatbed not spawning
- Verify
Config.FlatbedModelis a valid vehicle model (default:flatbed3) - Check that the spawn coordinates aren't blocked by other vehicles or objects
- Ensure the vehicle model is loaded in your server's vehicle list
- Check server console for "Failed to spawn flatbed" errors
Hook/attach not working
- You must take the hook first before attaching it to a vehicle
- Make sure you are close enough to the target vehicle
- Verify the tow truck model is listed in
Config.Truckswith correct bone and offset values - Check that
attachVehBonematches your flatbed model's bone name
Repair items not working
- Ensure
tow_tire,tow_sparkplug, andtow_batteryare added to your inventory system - Item names must match exactly (case-sensitive) between config and inventory
- Check that you have the required quantity of items before starting a repair
- If the minigame fails, the part breaks and you need to try again
No dispatch calls received
- You must be on duty and in the dispatch queue
- Default dispatch delay is 120 seconds - wait for the timer
- Check that you don't already have an active job
Database errors
- Ensure
oxmysqlis started before NR_Towing in server.cfg - Check your database connection string in server.cfg
- The leveling table is created automatically on first start
Target interaction not showing
- If
Config.UsingTarget = true, ensure ox_target or qb-target is running - If
Config.UsingTarget = false, use the built-in Press E prompt instead - Verify the HQ ped is spawning at the configured coordinates
Support
For paid script support, open a ticket in our Discord server for priority assistance.