Usage — Bus Driver Job for FiveM | Quasar Store | Quasar Store
Documentation
Usage
How the FiveM Bus Driver Job works: the job panel, driving routes and stops, adding routes and buses, NPC and player passengers, pay and crash penalties, levels, leaderboards and the full config reference.
Bus Driver Job has one window, and the dispatcher at the depot opens it: walk up and press E, or use your third eye when Config.Target is on. The camera cuts to the dispatcher, framed on the left half of the screen, and the panel takes the right half. Your own character is hidden from your view while you talk, so it never stands in the shot.
Part
What it shows
Dispatcher card
Who you are talking to and their greeting — Config.PedName and Config.PedGreeting. Leave either empty to hide it.
Level
Your level, the experience toward the next one, and a tooltip with your current pay bonus and crash protection — exactly what the server will apply.
Level Bonus
Routes
A carousel of every route: picture, name, description, number of stops, level required, pay and experience.
Your Bus
The bus picker. Locked buses are drawn dimmed with the level they need, so drivers can see what the next level unlocks.
Start route / Abandon route
The footer. While you are on a route it offers to abandon it instead, with a confirmation, and keeps the panel open so you can pick another.
Statistics
The daily, season and all-time leaderboards. Hidden when Config.EnableLeaderboard is off.
Guide
A driver's guide: how the job works, step by step, and a few tips.
The panel opens for everyone, so anybody can browse routes and statistics. The job is checked when a route is started — by the panel, and again by the server.
A route is one run from the depot, through every stop in order, and back to the depot. Routes are driven solo: a bus has one driver.
Take a route
Pick a route and a bus and press Start route. The server checks your job, your level against the route and the bus, and that you have no route open. The screen fades, a bus appears in the first free bay and you are seated at the wheel, with the keys and the uniform on. A tracker shows the stops served and any crash penalty.
Drive to the stop
The next stop is marked on the map with a GPS route. Stops are served in order, so there is only ever one to head for. Within 10 m, at the wheel of your bus, the prompt Stop Bus appears — press E.
Let the passengers on and off
The bus is held on the handbrake and the camera swings out to the stop. Passengers riding with you get off first, then the people waiting queue alongside the bus and climb in through the front door, one at a time. When the last door closes the camera comes back and the next stop is marked.
Reach the terminus
The last stop empties the bus instead of filling it. Once everybody is off you are told to take the bus back to the depot.
Hand the bus back
Drive to the hand-back point (Config.DeliverBusCoords) and press E within 5 m. You step out, the bus is taken away, the uniform comes off and the route is paid.
Every step that is worth money is confirmed by the server before it counts:
Step
What the server checks
Starting
The job (unless Config.RequireJob is off), no route already open, and the level stored for you against the route's and the bus's levelRequired.
Serving a stop
It is the next stop in order, you are within Config.StopReachDistance (25 m) of it, and you are in the driver's seat of a bus of the model this run was approved for.
Handing back
Every stop is served, you are within Config.DeliverReachDistance (20 m) of the hand-back point, the run has not been paid already, and you still hold the job.
Abandoning a route — from the panel, by losing the job, or by disconnecting — removes the bus and its passengers and pays nothing. A partial run is never paid.
A route is one entry in Config.Tasks. Copy an existing one, give it a new taskOrder and list its stops in the order they must be served:
lua
Config.Tasks = {
-- ...the shipped routes...
{
taskOrder = 5, -- unique id, never reuse one
name = "Vinewood Loop",
img = "bus_driver_2.png", -- a shipped picture, or a full https:// URL
description = "Tourists and late shoppers between Vinewood and the boulevard.",
recommendedPlayers = { 1 },
levelRequired = 5,
experience = 650,
money = 750,
longRide = false, -- true packs more passengers on at every stop
route = {
[1] = vector3(303.53, -766.33, 29.31),
[2] = vector3(-529.46, -718.97, 33.08),
[3] = vector3(-1011.6, -307.85, 37.87),
},
},
}
Field
What it does
taskOrder
The route's id. Routes are found by this number, not by their place in the list, so it must be unique.
name · description
What the card shows.
img
The cover picture: one of the shipped bus_driver_1.png, bus_driver_2.png, bus_driver_3.png, or a full https:// image URL. A name that does not exist falls back to a picture mark.
recommendedPlayers
Kept for the card. Not enforced — routes are driven solo.
levelRequired
The lowest level that may take the route. Checked by the server.
money · experience
What finishing the route is worth, before the bus multiplier, the level bonus and the crash penalty.
longRide
Optional. true adds Config.PassengersPerStop.longRideBonus to the people waiting at every stop — for long hauls.
route
The stops, as vector3 positions, in the order they must be served. The last one is the terminus.
The buses a driver can pick from live in Config.Vehicles. Levelling into a bigger bus is the reward: its multiplier applies to the whole route's pay.
Bus
Model
Unlocks at
Pay multiplier
Bus
bus
Level 1
×1.00
Dashound Coach
coach
Level 6
×1.18
Airport Bus
airbus
Level 14
×1.35
lua
Config.Vehicles = {
{ model = 'bus', label = 'Bus', img = 'bus.png', levelRequired = 1, moneyMultiplier = 1.0 },
{ model = 'coach', label = 'Dashound Coach', img = 'coach.png', levelRequired = 6, moneyMultiplier = 1.18 },
{ model = 'airbus', label = 'Airport Bus', img = 'airbus.png', levelRequired = 14, moneyMultiplier = 1.35 },
-- Any spawn name that exists on your server works, base game or add-on.-- img takes a shipped picture or a full https:// image URL:-- { model = 'pbus2', label = 'Festival Bus', img = 'https://example.com/pbus2.png', levelRequired = 20, moneyMultiplier = 1.5 },
}
There is no seat count to fill in. How many passengers a bus carries is read off the model when it spawns — every seat except the one by the front door, which is kept clear as the doorway — so swapping a model needs no bookkeeping. The level is checked again by the server when the route starts, so the picker is a convenience, not the security boundary.
The bus appears in the first free bay of Config.VehicleSpawnCoords. A bay counts as blocked when any vehicle stands in the box the bus would fill — 2.5 m either side of the bay and 6.5 m ahead and behind, along the bay's heading. When every bay is blocked the driver is told the parking lot is full instead of having a bus dropped on top of a car.
lua
Config.VehicleSpawnCoords = {
[1] = vector4(839.7751, -1934.2310, 28.9909, 353.2833),
[2] = vector4(835.6471, -1933.7159, 28.9580, 355.7019),
}
Config.DeliverBusCoords = vector3(847.8856, -1952.8138, 28.99) -- where the route is handed in
Config.SpawnInsideVehicle = true-- seat the driver straight away
Config.SpawnFade = { enabled = true, outTime = 400, holdTime = 200, inTime = 700 }
Config.Fuel = false-- true fills the tank on spawn
Config.FuelExport = exports['LegacyFuel']
Keep bays side by side and more than 2.5 m apart across their heading — the shipped two are 4.16 m apart. Placed nose to tail they need a good 13 m, the length of a bus. Config.SpawnFade hides the jump into the driver's seat behind a short fade; set enabled = false for a hard cut.
The server keeps the count aboard and decides both halves of every stop from it: some of the riders get off, then the people waiting get on — never more than the room the bus has left. Anyone who cannot fit, or who fails to reach the door after two tries, walks off down the street instead of being dropped into a seat.
lua
Config.PassengersPerStop = {
minBoard = 1, -- fewest people waiting at a stop
maxBoard = 3, -- most people waiting at a stop
maxAlight = 2, -- most that get off at any one stop
longRideBonus = 1, -- added to both board numbers on a longRide route
}
Keep these numbers small. On a GTA bus only the front door works, so every passenger boards and alights through it one at a time — about three seconds a head, with the bus held at the stop for all of it. Six people boarding is a twenty-second stop; two or three is the few seconds it should be.
When another player sits in your bus while you are on a route, they are charged Config.MultiplayerTicketPrice ($20) and you are paid the same amount, in one server-side step — neither side can be charged without the other being paid. Both get a notification, and the fare counts toward your earnings on the leaderboard.
You must be on a route, at the wheel of the bus that route spawned.
The same passenger is charged by the same driver at most once per Config.TicketCooldown (180 seconds), so hopping between seats never bills twice.
The fare is paid from cash. A passenger who cannot cover it is told so and stepped out of the bus.
A route is paid once, when the bus is handed back, from the route's money in the config. The crash penalty comes off first, then the bus multiplier and the level's pay bonus are applied to what is left:
The pay never drops below zero — a wrecked route pays nothing rather than costing money. Experience is always the route's full experience. With qs-job-management running the payout is handed to it; otherwise it goes into the driver's cash.
A hit that takes more than a scrape off the bus while you are in it is reported to the server, which counts it at most once every three seconds and up to Config.MaxCrashesPerRoute (20) per run. Each one costs Config.CrashMonetaryPayment ($10), reduced by your crash protection. You are told what each crash cost, and the tracker keeps the running total.
Levelling never stops. The experience for the next level is BaseExperience × GrowthFactor^(level − 1) — 1,000 then 10% more each level. Every level adds PayBonus (0.5%) to the pay and CrashProtection (1%) off each crash, and both stop growing at Config.MaxBonusLevel (60), so a veteran driver can never drive for free money.
Level
Total XP to reach
Pay bonus
Crash protection
Unlocks
1
0
+0.5%
1%
Cityline Route, Bus
2
1,000
+1%
2%
Uptown Express
3
2,100
+1.5%
3%
Grand Avenue Route
4
3,310
+2%
4%
Interstate Express
6
6,105
+3%
6%
Dashound Coach
14
24,518
+7%
14%
Airport Bus
20
51,151
+10%
20%
—
60
2,757,986
+30%
60%
The bonus cap
A level-up is announced the moment it happens. The figures above are for the shipped config and shift with Config.LevelExperience.
The Statistics button in the job panel opens three rankings. Each lists place, player name, experience and earnings — route pay plus ticket fares — and highlights your own row. A search box finds a driver, and each timed board shows when it ends, what the top three will be paid and who won last time.
Board
Ranks by
Resets
Top three paid
All-Time
Total experience
Never
—
Season
Experience this month
00:00 on the 1st of every month
$5,000 · $3,500 · $2,000
Daily
Experience today
00:00 every day
$500 · $350 · $200
Times are the server's clock. At a reset the top three are paid in cash on the spot; a winner who is offline has the prize banked and paid when they next log in. If the server was down over midnight or a month boundary, the missed reset runs as soon as it starts again — and never twice. The boards refresh every Config.UpdateLeaderboard minutes (1), show up to Config.MaxLeaderboardPlayers drivers (100), and only list drivers with experience in that period.
lua
Config.LeaderBoardRewards = {
Daily = { [1] = 500, [2] = 350, [3] = 200 },
Season = { [1] = 5000, [2] = 3500, [3] = 2000 },
}
-- Which name the boards show for a player:-- 'character' → the character's first and last name-- 'cfx' → the FiveM account name-- 'both' → "Character Name (FiveM Name)"
Config.PlayerNameSource = 'character'
The FiveM name only exists while somebody is connected, so with 'cfx' or 'both' an offline driver's row falls back to their character name and is never left blank. Other players' identifiers never leave the server: each player is only told their own place.
The Guide button shows one walkthrough of the job — an intro, six steps and four tips. Every line comes from config/translations.lua (GUIDE_INTRO, GUIDE_STEP_1 to GUIDE_STEP_6, GUIDE_TIP_1 to GUIDE_TIP_4), so you can reword it to match your server's rules. To drop a line, delete its key from your language and from en — a key missing from one language falls back to English.
With Config.Clothing = true, the driver changes into a uniform when a route starts and back into their own clothes when it ends — completed, abandoned or lost with the job. The outfit is set at the top of client/clothing.lua, one table for male characters and one for female:
Uncomment any other slot — decals, ears, mask, bags, glasses, vest, watches, bracelets — to include it. On ESX the outfit goes through esx_skin and skinchanger; on QBCore and Qbox through the qb-clothing events. Set Config.QuasarInventory = true if you run qs-inventory, so the inventory is locked while the clothes change. With Config.Clothing = false nobody changes clothes, and on-duty tracking keeps working.
"Bus Station", sprite 513. Shown only to players who may drive, and redrawn when their job changes.
Dispatcher
Config.StartJob.ped
Position and heading (vector4) and ped model, s_m_m_lsmetro_01 by default. Frozen, invincible, and removed when the resource stops.
Floating marker
Config.PedMarker
The blue cone over the dispatcher's head: shape, height, colour, size, gentle bob and how far away it shows.
Prompts
Config.DrawText3D · Config.Keys.InteractKey
3D "[E]" text at the dispatcher, the stops and the hand-back point, on top of the hint in the corner. The key is control 38, E.
Route blip
Config.RouteBlip
The blip and GPS line on the next stop while a route runs.
Moving the depot means moving three things together: the dispatcher (Config.StartJob.ped.coords), the spawn bays (Config.VehicleSpawnCoords) and the hand-back point (Config.DeliverBusCoords). The blip and the marker follow the dispatcher on their own. The dialogue camera is fixed by design and only frames the dispatcher when the player is within 6 m of them.
Every option in config/config.lua, by section, with its shipped value. Restart the resource after changing any of them.
1. General — job, interaction, interface and money
Option
Default
What it does
Config.Framework
auto
Detected from the running core. Leave the line as it is.
Config.Vehiclekeys
auto
Detected from the running key script, 'none' when there is none.
Config.RequireJob
true
Whether starting a route needs a job. false lets anyone drive.
Config.busdriverjob
{ ['bus_driver'] = true }
The jobs allowed to drive. On ESX each is registered in the database on start.
Config.Target
false
true puts a third-eye option on the dispatcher instead of the key prompt.
Config.TargetScript
'ox'
'ox' for ox_target, 'qb' for qb-target.
Config.DrawText3D
true
Draws the "[E] …" prompts in the world.
Config.Keys.InteractKey
38 (E)
The key for the dispatcher, the stops and the hand-back. Any FiveM control id.
Config.PlayerNameSource
'character'
The name on the leaderboards: 'character', 'cfx' or 'both'.
Config.PedName · Config.PedGreeting
'Dolores Kemp' · a greeting
The dispatcher card in the panel. Empty hides that part.
Config.DefaultNotifications
true
false sends notifications to SendTextMessage for your own system.
Config.CurrencyPosition
'prefix'
'prefix' → $500, 'suffix' → 500 zł. The symbol is CURRENCY_TYPE in translations.
Config.QuasarInventory
false
Locks qs-inventory during the outfit change.
Config.Clothing
true
The driver uniform while on a route.
Config.QuasarInventoryQuests
false
Creates the three bus driver quests in qs-inventory and reports progress.
2. World — blip, dispatcher, buses and bays
Option
Default
What it does
Config.EnableBlip
true
The depot blip on the map.
Config.Blip
3. Routes — tasks and reach distances
Option
Default
What it does
Config.Tasks
four routes
The routes in the panel. See Adding a route above.
Config.StopReachDistance
4. Levels — the curve and the perks
Option
Default
What it does
Config.LevelExperience.BaseExperience
1000
Experience needed to leave level 1.
Config.LevelExperience.GrowthFactor
5. Passengers — stops, fares and crashes
Option
Default
What it does
Config.PassengersPerStop
1 – 3 board, 2 alight, +1
minBoard, maxBoard, maxAlight and the longRideBonus for long routes.
6. Leaderboard
Option
Default
What it does
Config.EnableLeaderboard
true
false hides the Statistics button and stops the resets and prizes.
Config.UpdateLeaderboard
7. Marker — the cone over the dispatcher
lua
Config.PedMarker = {
enabled = true, -- false hides it completelytype = 0, -- 0 is the upside-down cone; any FiveM marker id
height = 1.2, -- metres above the dispatcher's head
distance = 25.0, -- how close you have to be to see it
bob = true, -- drifts gently up and down
size = { x = 0.25, y = 0.25, z = 0.18 },
color = { r = 59, g = 130, b = 246, a = 170 }, -- 0–255 each
}
8. Debug, webhooks and language
Option
Default
What it does
Config.Debug
false
Traces what the script does in the server console and F8. Leave it off on a live server.
Config.Webhooks
Bus Station, 513, 1.0, 12, 2
text, sprite, size, color, display — see the blip list.
Config.StartJob.ped
the depot, s_m_m_lsmetro_01
The dispatcher's coords (vector4) and model.
Config.Vehicles
bus · coach · airbus
The bus picker: model, label, img, levelRequired, moneyMultiplier. The first entry is the fallback.
Config.VehicleSpawnCoords
two bays
The bays the bus can appear in (vector4). The first free one is used.
Config.DeliverBusCoords
the depot
Where the bus is handed back for the route to pay (vector3).
Config.SpawnInsideVehicle
true
Seats the driver in the bus instead of beside it.
Config.SpawnFade
on, 400 / 200 / 700 ms
The fade that hides the spawn: enabled, outTime, holdTime, inTime.
Config.Fuel · Config.FuelExport
false · exports['LegacyFuel']
Fills the tank to 100 on spawn through the export's SetFuel.
Config.RouteBlip
sprite 1, size 1.0, color 3
The blip on the next stop.
25.0
How close to a stop the server accepts the driver, in metres. Keep it wider than the 10 m prompt so lag never costs a stop.
Config.DeliverReachDistance
20.0
The same for the hand-back point.
1.1
How much more each level needs than the last.
Config.LevelExperience.PayBonus
0.5
Percent added to the route pay per level.
Config.LevelExperience.CrashProtection
1
Percent taken off each crash penalty per level, never above 100.
Config.MaxBonusLevel
60
The level the two perks stop growing at. Levelling itself is not capped.
Config.MultiplayerTicketPrice
20
What a player passenger is charged, and the driver paid. 0 makes rides free.
Config.TicketCooldown
180
Seconds before the same driver can charge the same passenger again.
Config.CrashMonetaryPayment
10
Money taken off the payout per crash, before crash protection.
Config.MaxCrashesPerRoute
20
The most crashes one run can be penalised for.
1
Minutes between refreshes.
Config.MaxLeaderboardPlayers
100
Drivers per board. Higher costs query time on every refresh.