Everything framework- or third-party-specific in Taxi Job sits in a few small files left open for editing — client/framework/, server/framework/, client/vehiclekeys/, client/clothing.lua and client/target.lua — and the rest of the script only ever calls those. Some layers are detected from what is running; the rest are a switch in config/config.lua.
Layer
Supported
Chosen by
Without it
Framework
es_extended · qb-core · qbx_core
Auto
Required — the job does not load.
Target
ox_target · qb-target
Config.Target
Press E beside the dispatcher.
Vehicle keys
Eleven key systems
Auto
The cab is driven without keys being handed over.
Fuel
Any resource with SetFuel
Config.Fuel
The cab spawns with the game's default fuel.
3D prompts
qs-textui
Auto
The game's own 3D text.
Notifications
Built in, or any notify resource
Config.DefaultNotifications
—
Dispatch
qs-dispatch, or any
Config.DispatchExport
Reported illegal stops alert nobody.
Uniform
esx_skin + skinchanger · qb-clothing
Config.Clothing
Drivers keep their own clothes.
Quests
qs-inventory
Auto
No taxi quests.
Job money
qs-job-management
Auto
Fares are paid to the driver in cash.
Phone
qs-smartphone and the Taxi Job phone app
Auto
No ride requests by phone.
Every optional integration degrades quietly. A missing resource makes its feature stand down — nothing errors, and the rest of the job carries on.
With Config.DefaultNotifications on, Taxi Job draws its own notifications, coloured by type and with a sound. Turn it off to send every message to your own notification resource instead, through SendTextMessage in config/config.lua:
lua
Config.DefaultNotifications = false-- type is 'info', 'success', 'warning' or 'error'functionSendTextMessage(msg, type)
exports['okokNotify']:Alert('Taxi', msg, 5000, type)
end
The shipped function fills in info, error and success one by one; a single call that passes the type straight through, like the one above, also covers the warnings about hard braking and queasy passengers.
The "press E" prompts at the dispatcher, the pickup, the stop and the drop-off are always the job's own, merged into one hint so two prompts never fight for the same corner. Config.DrawText3D = true replaces them with floating text over each point — drawn by qs-textui when it is running, and by the game's own text otherwise.
With a target script switched on, the dispatcher gets a single Start working option instead of the key prompt. It opens the same panel whether the player is on shift or not — the panel decides whether to offer Start shift or Clock off.
lua
Config.Target = true
Config.TargetScript = "ox"-- "ox" for ox_target, "qb" for qb-target
The option is added in client/target.lua, which is open for editing if your target resource is called differently.
The key system is detected when the client loads, from the first of these it finds running. The cab's keys are handed over when it spawns and taken back when the shift ends:
Run only one of them, and start it before qs-taxijob. On QBCore and Qbox the cab also fires vehiclekeys:client:SetOwner on spawn, which most QB key scripts listen for on their own.
Config.Fuel = true
Config.FuelExport = exports['LegacyFuel'] -- any resource with a SetFuel(vehicle, level) export
The tank is filled to 100 when the cab spawns. Any fuel script with a SetFuel(vehicle, level) export works — point Config.FuelExport at yours, for example exports['ps-fuel'] or exports['cdn-fuel'].
When an illegal stop is reported, Config.DispatchExport is called on the driver's client. It is empty by default — fill it in with your dispatch resource:
lua
Config.DispatchExport = function()
exports['qs-dispatch']:SuspiciousActivity()
end
It runs at the moment the driver is actually reported — after the hand-off scene — not when the offer is accepted, so the call reaches the police from where the deal happened.
With Config.Clothing on, drivers change into a uniform when they clock on and back into their own clothes when they clock off. The outfit is set at the top of client/clothing.lua, one table for male and one for female characters:
esx_skin and skinchanger; the saved skin is reloaded on clock-off.
QBCore / Qbox
qb-clothing; the player's own skin is restored with qb-clothes:loadPlayerSkin.
Running illenium-appearance on QBCore? Its reload line is already in client/clothing.lua, commented out beside the qb-clothing one. With Config.QuasarInventory on, qs-inventory is locked while the outfit changes.
With qs-inventory running, every driver is given three taxi quests when they log in:
Quest
Advances on
Taxi Progress (level_up_taxi)
Every level gained.
Complete taxi rides (complete_rides)
Every NPC fare handed in.
Drive real passengers (complete_multiplayer_rides)
Every player fare completed.
The quests are defined in server/missions.lua, open for editing — titles, descriptions and rewards. Every call to the inventory is protected, so a quest resource that is still starting never costs a driver their fare.
Illegal fares are paid as the black_money item on QBCore and Qbox. Stock QBCore ships markedbills instead, so add a black_money item to your inventory's item list. Until you do, illegal fares are refused with This item does not exist: black_money, and the console names the missing item once. On ESX they go to the black_money account.
With qs-job-management running, every legal fare and every player fare is paid into the taxi job's money there instead of the driver's pocket — the company earns, and pays its drivers through its own salaries. Illegal fares still go straight to the driver as black money. Nothing to configure: it is picked up as soon as the resource is running.
The Taxi Job phone app for Quasar Smartphone lets players see who is driving and book a ride by phone. It uses the same records and the same server-side flow as the job itself: the driver gets a phone notification and an in-game request, a request no driver answers expires after two minutes, and ratings left through the app go on the same reputation as ratings left in the cab — a driver has one reputation, not two.
The exports the app relies on are listed in Commands and Exports, along with the duty exports a scoreboard reads.
Everything the job asks of the framework — the job check, money, identifiers, names, spawning the cab — goes through client/framework/esx.lua or qb.lua and their twins in server/framework/. Running a renamed core?
Map the name
Add your resource to the frameworks list at the top of config/config.lua, mapped to the framework it is based on:
In the matching client and server framework files, change the export the core object is read from — exports['qb-core']:GetCoreObject() or exports['es_extended']:getSharedObject() — to your resource's name.
Restart
Restart the server — not only the resource — so the framework is detected from a clean start.
Eleven translations ship in config/translations.lua: English (en), Spanish (es), Italian (it), French (fr), Portuguese (pt), German (de), Russian (ru), Turkish (tr), Dutch (nl), Simplified Chinese (cn) and Traditional Chinese (zh-tw). Pick one at the top of that file:
lua
Config.Language = "es"
English is the fallback for every key, so a line another language has not translated yet shows in English rather than as a raw key. To add a language, copy the en block, give it a new code and translate the text between the quotes. The currency symbol is the CURRENCY_TYPE key, placed before or after the amount by Config.CurrencyPosition.