Commands#
Bus Driver Job registers no chat or console commands of its own: everything a player does starts at the dispatcher, and everything an admin sets lives in config/config.lua. The commands you will actually use while running it are these:
Command | Where | Description |
|---|---|---|
| In game | Your framework's command. Hires a player as a bus driver so they can start routes. |
| Console | Applies config changes. Ends every route in progress and removes its bus, passengers and dispatcher before they are spawned again. |
| server.cfg | Starts the job. It goes below its dependencies and everything it should detect. |
<id> is the player's server id — the number next to their name in the player list. To see what the job is doing while you test, set Config.Debug = true: it traces every step in the server console and in F8.
Client Exports#
For opening the job panel from your own scripts — a radial menu, a phone app, a second NPC at another depot.
Opening the job panel
-- client side
exports['qs-busjob']:openBusDriverMenu()
-- or from the server, for one player
TriggerClientEvent('qs-busdriverjob:openBusDriverMenu', source)Opens the same panel as the dispatcher: routes, the bus picker, statistics and the guide. The camera only cuts to the dispatcher when the player is standing within 6 m of them; anywhere else the panel opens on its own. Starting a route still needs the job.
There is deliberately no export that opens the leaderboard on its own — the statistics are a view inside this panel, so open the panel instead.
Showing a notification
-- server side: show a notification in the bus job's own style
TriggerClientEvent('qs-busdriverjob:sendNotification', source, 'notify', 'success', 'Shift bonus paid')
-- type: 'success' · 'error' · 'info' · 'warning'Goes through the same path as the job's own messages, so it follows Config.DefaultNotifications and your SendTextMessage.
Server Exports#
How another resource asks about bus drivers — a scoreboard counting who is on duty, a jail or hospital script checking whether a player has a bus out on the road.
IsPlayerOnMission
local driving = exports['qs-busjob']:IsPlayerOnMission(source) -- true / falseTrue while the server holds an open route for that player. It reads the same record the stop checks and the payout are decided from, so it can never disagree with what the server will actually let the player do. This is the one to use when the answer matters.
getOnDutyCount
local drivers = exports['qs-busjob']:getOnDutyCount() -- numberHow many players are on duty as bus drivers right now — from the moment a route starts until it is completed or abandoned. This is what qs-scoreboard reads.
isPlayerOnDuty
local onDuty = exports['qs-busjob']:isPlayerOnDuty(source) -- true / falseKept for scripts already calling it. It mirrors the on-duty flag the player's client reports, so it can lag a moment behind; prefer IsPlayerOnMission for anything that has to be right.
Internal Events#
For reference when reading logs or writing anti-cheat rules. These are what the job's own client sends; each is checked by the server against its own record before anything changes, so there is no reason to trigger them from another resource.
Event | Sent when | The server checks |
|---|---|---|
| Start route is pressed. | The job, no open route, the stored level against the route and the bus. |
| E is pressed at a stop. | Next stop in order, distance, driver's seat, approved bus model. |
| The bus has spawned. | An open route; the seat count is clamped to 1–40. |
| The bus takes a hit. | An open route, one every 3 seconds, the per-route cap. |
| A player sits in the bus. | Open route, same vehicle, driver at the wheel, approved model, cooldown, passenger's cash. |
| E is pressed at the hand-back point. | Every stop served, distance, not paid already, the job. |
| A route is abandoned, or its bus never spawned. | Drops the route. Nothing is paid. |
| The uniform goes on or comes off. | Stored as reported — it only feeds the two duty exports. |
About the Refusals#
When the server refuses to start a route it answers with a translation key, not a sentence — NOTIFY_NOT_BUS_DRIVER, NOTIFY_ALREADY_ON_MISSION, NOT_ENOUGH_LEVEL or NOTIFY_VEHICLE_LOCKED — and the player reads it in their own language. A stop or hand-back that fails a check is simply not counted: the prompt stays until the driver is where the server needs them. Common Errors lists what every key means.



