Before You Begin#
Before installing Bus Driver Job, make sure your server meets the minimum requirements. Three things are mandatory — the database, ox_lib and a framework; everything else is optional.
Requirement | Status | Notes |
|---|---|---|
| Required | Database access. The schema installs itself. |
| Required | Server callbacks, and the scheduler that refreshes and resets the leaderboards. |
Framework | Required | ESX ( |
Target | Optional |
|
Vehicle keys | Optional | Hands the driver the keys of the bus. Eleven key systems are detected on their own. |
Clothing | Optional |
|
Fuel | Optional |
|
| Optional | Draws the [E] prompts as 3D text UI instead of plain text. |
Everything framework- or third-party-specific sits behind a small, open bridge file, and the resource picks the right one by looking at what is already running:
Layer | How it is chosen |
|---|---|
Framework | Detected: |
Vehicle keys | Detected: qs-vehiclekeys · qb-vehiclekeys · qbx_vehiclekeys · F_RealCarKeysSystem · fivecode_carkeys · glfp10_carkeys · mono_carkeys · ti_vehicleKeys · vehicles_keys · wasabi_carlock · xd_locksystem |
3D prompts | Detected: |
Route payouts | Detected: |
Target, fuel, qs-inventory | Switched on by hand in |
Every optional integration stands down quietly when its resource is missing — no key is handed out, the tank stays as it spawned, the prompt is drawn as plain text. Integrations has the details for each one.
github.comReleases · overextended/oxmysqlMySQL resource for FXServer.github.comReleases · overextended/ox_libA FiveM resource and script library for Lua and JS.Downloading Bus Driver Job#
After purchasing Bus Driver Job, the resource is automatically linked to your CFX Portal account.
Sign in to the CFX Portal using the same account used during checkout, open Granted Assets, and download Bus Driver Job.
After extracting the download, you should have the following folders:
[busjob]/
├── qs-busjob/
│ ├── config/ -- config.lua and translations.lua: what you edit
│ ├── client/ -- framework/, vehiclekeys/ and clothing.lua are open
│ ├── server/ -- framework/ and missions.lua are open
│ ├── web/build/ -- the interface, ready to run
│ └── fxmanifest.lua
└── [sql]/
└── qs-busdriver.sql -- optional: the same schema the resource builds itselfThe folder must be named
qs-busjob. The resource checks its own name on start: a renamed copy prints You have renamed the script! and freezes the server console. Every export is also called through that name —exports['qs-busjob'].
Installing the Resource#
Move the qs-busjob folder into your server's resources directory. It can live anywhere inside it, including a category folder:
resources/
└── [qs]/
└── qs-busjob/Once copied, open your server.cfg and make sure every dependency — and everything it should detect — starts before Bus Driver Job:
ensure oxmysql
ensure ox_lib
# Framework
ensure es_extended
# ensure qb-core
# ensure qbx_core
# Optional: target, keys, fuel, 3D prompts
ensure ox_target
ensure qs-vehiclekeys
ensure LegacyFuel
ensure qs-textui
ensure qs-busjobThe loading order matters. Detection only sees resources that are already started: a key script that starts later is never used, and a framework that starts later leaves the job with no framework at all — no dispatcher, no blip and no routes.
The Database#
There is no SQL file to import. Bus Driver Job creates its own tables on first start, all prefixed qs_busdriverjob, and adds any column an older install is missing:
Table | Holds |
|---|---|
| Each driver's level and experience, plus all-time, season and daily experience and earnings for the leaderboards. |
| One control row recording when the daily and season rankings last reset. |
| Leaderboard prizes banked for a winner who was offline at the reset, paid on their next login. |
| The last top three of each ranking, shown as the last winners in Statistics. |
On ESX it also registers every job listed in Config.busdriverjob in the jobs and job_grades tables, with one grade (0, driver). And it matches the collation of its identifier columns to your framework's — users.identifier on ESX, players.citizenid on QBCore — so the leaderboard works on MariaDB 11.4 and newer, where the default collation changed.
[sql]/qs-busdriver.sqlis only for preparing a database outside the server, or for reading what the resource is going to create. Every statement in it isIF NOT EXISTSorINSERT IGNORE, so importing it changes nothing and is safe to run twice.
Giving Players the Job#
Anyone can open the job panel and browse the statistics. Starting a route is what needs the job — by default bus_driver, and the depot blip is only shown to players who hold it.
Nothing to create — the first start registers bus_driver with grade 0. Hire someone from the game:
/setjob <server id> bus_driver 0QBCore keeps its jobs in a file rather than the database, so add the job to qb-core/shared/jobs.lua and restart the server:
['bus_driver'] = {
label = 'Bus Driver',
defaultDuty = true,
offDutyPay = false,
grades = {
['0'] = { name = 'Driver', payment = 10 },
},
},Then hire someone with /setjob <server id> bus_driver 0.
Add the job to qbx_core/shared/jobs.lua and restart the server:
['bus_driver'] = {
label = 'Bus Driver',
defaultDuty = true,
offDutyPay = false,
grades = {
[0] = { name = 'Driver', payment = 10 },
},
},Then hire someone with /setjob <server id> bus_driver 0.
To use a job you already have, or several, list them; to let anyone drive, turn the requirement off:
-- config/config.lua
Config.RequireJob = true -- false lets anyone take a route, without a job
Config.busdriverjob = {
['bus_driver'] = true,
-- ['bus'] = true, -- e.g. the bus job QBCore ships with
}Configuring the Resource#
Everything you normally change lives in one file, config/config.lua, split into numbered sections. The other open files are bridges you only touch to support something new:
File | Contents |
|---|---|
| The job, interaction, the dispatcher, the buses and bays, the routes, levels, passengers and fares, the leaderboard, the marker, debug and Discord webhooks. |
| The language ( |
| The driver uniform, male and female, at the top of the file. |
| One bridge per key system. |
| The ESX and QBCore bridges: money accounts, identifiers, job checks and spawning the bus. |
| The three optional qs-inventory quests. |
The values worth reviewing first:
Config.RequireJob = true -- false: anyone may take a route
Config.Target = false -- true: third-eye on the dispatcher instead of E
Config.TargetScript = 'ox' -- 'ox' or 'qb'
Config.Clothing = true -- driver uniform while on a route
-- Where the dispatcher stands, where buses appear, where they are handed back
Config.StartJob.ped.coords = vector4(846.8366, -1948.2135, 28.9644, 132.5054)
Config.VehicleSpawnCoords = { vector4(839.7751, -1934.2310, 28.9909, 353.2833), ... }
Config.DeliverBusCoords = vector3(847.8856, -1952.8138, 28.99)
Config.Fuel = false -- true to fill the tank on spawn
Config.FuelExport = exports['LegacyFuel'] -- your fuel resource
-- config/translations.lua
Config.Language = 'en' -- en · it · es · fr · pt · de · ru · tr · nl · cn · zh-twThe config is read when the resource starts, so apply changes with
restart qs-busjob. A restart ends every route in progress and removes its bus, so do it when nobody is driving. Every option is listed in the config reference.
Verifying the Installation#
After completing the installation, restart your server and read the console. On the first start you will see the lines for whatever the resource had to do — the ESX job, and the collation fix where your database needed it:
[qs-busjob] Registered the ESX job "bus_driver"
[qs-busjob] aligned 4 identifier column(s) to utf8mb4_uca1400_ai_ci, matching users.identifier.A red has not answered … after 10s line means the framework is not started before qs-busjob. Then join your server and drive the first loop:
Find the depot
A Bus Station blip marks the depot for anyone who can drive. The dispatcher stands under a floating blue marker: walk up and press E, or use your third eye if
Config.Targetis on. The camera cuts to the dispatcher and the job panel opens.Take a route
Pick Cityline Route, keep the Bus selected and press Start route. The screen fades and you are seated in a bus in the depot, in uniform, with the keys.
Serve the stops
Follow the GPS to the first stop, pull up beside it and press E. The bus is held while passengers get on and off, then the next stop is marked.
Hand the bus back
After the last stop, drive back to the depot and press E at the hand-back point. You step out, the bus is taken away and the pay arrives with a notification.
Something not behaving? Set
Config.Debug = trueand restart: the resource explains what it is doing in the server console and in F8, which shows how far it got before it stopped. Turn it off again on a live server.



