Skip to Content
Resourcesqb-garbagejob Reference

qb-garbagejob

qb-garbagejob is a route-based job. The player pays a truck deposit, the server generates a randomized route, and each completed stop accrues pay. The deposit is returned only if the whole route is finished.

The distinguishing feature compared with the other jobs in this set is that route state and accrued pay live on the server, keyed by citizenid, rather than being reported by the client at the end.

The manifest at the commit linked above declares version 1.5.0.

The README at this commit describes the rework: randomized stop count and stops, server-side reward tracking, an optional crypto stick find, and per-bag pay.

Dependencies and start order

From the manifest: @qb-core/shared/locale.lua and locales as shared scripts, the PolyZone client files, client.lua, and server.lua.

From the implementation: qb-core for the core object, commands and player methods, and qb-inventory for the crypto stick reward.

Start order: qb-core, qb-inventory, PolyZone, then qb-garbagejob.

Configuration

KeyDefaultMeaning
Config.UseTargetfrom the UseTarget convarSet setr UseTarget true in server.cfg
Config.Jobname'garbage'The job name checked against
Config.TruckPrice250Bank deposit charged at shift start, refunded on full completion
Config.GiveCryptoSticktrueEnable the optional find
Config.CryptoStickChance75See the note below, this is a threshold, not a percentage
Config.MinStops5Lower bound on route length
Config.MinBagsPerStop2Lower bound on bags at a stop
Config.MaxBagsPerStop5Upper bound on bags at a stop
Config.BagLowerWorth50Lower bound of pay per bag
Config.BagUpperWorth100Upper bound of pay per bag
Config.UsePreconfiguredRoutesfalseUse the fixed route list instead of randomizing
Config.PedstableJob NPCs
Config.LocationstableTrashcan stops and depot
Config.Vehicle'trash2'Truck model

Config.CryptoStickChance is compared as math.random(100) >= Config.CryptoStickChance, so the default of 75 means roughly a 26 percent chance, not 75 percent. Lowering the number makes the find more likely, which is the opposite of what the name suggests.

The maximum stop count is math.random(Config.MinStops, #Config.Locations['trashcan']), so it is bounded by how many trashcan locations you configured.

Server surface

HandlerKindArgumentsReturns
qb-garbagejob:server:NewShiftcallbackcontinueshouldContinue, nextStop, bagNum, totalNumberOfStops
qb-garbagejob:server:NextStopcallbackcurrentStop, currentStopNum, currLocationshouldContinue, newStop, newBagAmount
qb-garbagejob:server:EndShiftcallbacknonestatus boolean
qb-garbagejob:server:payDepositnet eventnone
qb-garbagejob:server:PayShiftnet eventcontinue

Route state

NewShift builds the route and stores it in a server-side Routes table keyed by citizenid:

Routes[CitizenId] = { stops = allStops, currentStop = 1, started = true, currentDistance = 0, depositPay = Config.TruckPrice, actualPay = 0, stopsCompleted = 0, totalNumberOfStops = #allStops }

NextStop verifies the player’s supplied currLocation against the configured coordinates of currentStop and only advances when the distance is 20 or less. Pay accrues on the server from Config.BagLowerWorth and Config.BagUpperWorth, not from anything the client sends.

currLocation is still a client-supplied value, so the distance check proves the client claims to be near the stop rather than that it is. Reading the ped position on the server, as qb-busjob does, would close that gap.

Payout

PayShift pays depositPay + actualPay into the bank with the reason garbage-payslip, then clears the route. depositPay is zeroed when stopsCompleted is below totalNumberOfStops, or when the player chose to continue with another route, so quitting early forfeits the deposit.

Note that the deposit charge and the shift start are two separate calls. NewShift checks the player can pay, but the money is only removed by the separate payDeposit event. A client that starts a shift without firing payDeposit gets a route for free and is still refunded Config.TruckPrice at the end. If that matters, move the charge into the NewShift callback.

Admin command

/cleargarbroutes [id]

Registered through QBCore.Commands.Add with the admin permission, it clears the stored route for the given player ID. At this commit the handler calls GetPlayer(tonumber(args[1])) without a nil check, so running it against an offline or invalid ID raises a server-side Lua error. See Commands and key mappings for how permissions on these commands work.

Troubleshooting

SymptomLikely cause
”Not enough money” at shift startBank balance below Config.TruckPrice
Deposit never refundedstopsCompleted was below the route length, which is the intended behaviour for quitting early
Crypto sticks appear constantly or neverConfig.CryptoStickChance is a threshold, see the note above
Route never advancesThe client’s reported location was more than 20 units from the configured stop
Server error on /cleargarbroutesThe target ID is not an online player
Route survives a disconnectRoutes is keyed by citizenid and has no playerDropped cleanup at this commit. Use the admin command to clear it

Proposed manual smoke test

Not yet executed. On staging:

  1. Start a shift with insufficient bank funds and confirm the refusal.
  2. Complete a full route and confirm the deposit is refunded on top of the per-bag pay.
  3. Quit mid route and confirm only the accrued pay arrives.
  4. Disconnect mid route, reconnect, and confirm what happens to the stored route.
  5. Run /cleargarbroutes against an online ID and confirm the count reported.

Sources