Skip to Content
Resourcesqb-recyclejob Reference

qb-recyclejob

qb-recyclejob is a warehouse loop. The player carries boxes to a drop point, receives crafting materials, and can sell those materials back to an NPC at a fixed price list. It is the usual source of metalscrap, plastic, copper, iron, aluminum, steel, and glass on a stock server.

It pairs naturally with qb-scrapyard, which produces the same material set from scrapping vehicles.

The manifest at the commit linked above declares version 2.2.0.

Dependencies and start order

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

From the implementation: qb-core, qb-inventory for the item box, qb-log for the ban log line, and a MySQL layer for the ban insert.

Start order: oxmysql, qb-core, qb-inventory, PolyZone, then qb-recyclejob.

Configuration

config.lua is a single table literal.

KeyDefaultMeaning
UseTargetfrom the UseTarget convarSet setr UseTarget true in server.cfg
OutsideLocationvector4(55.55, 6472.18, 31.43, 44.0)Entrance
InsideLocationvector4(1073.0, -3102.49, -39.0, 266.61)Warehouse interior
DutyLocationvector4(1048.7, -3100.62, -38.2, 88.02)Clock on and off
DropLocationvector4(1048.224, -3097.071, -38.999, 274.81)Where boxes are turned in
SellMaterialstrueAllow selling to the NPC
LimitedMaterialstrueEnforce a finite material stock
SellPedvector4(1049.84, -3094.08, -40.0, 178.84)Buyer NPC position
DrawPackageLocationBliptrueBlip on the current box
PickupActionDurationmath.random(4000, 6000)Evaluated once at load, so it is the same for every pickup until restart
DeliveryActionDuration5000Milliseconds
PickupBoxModel'prop_cs_cardbox_01'Carried prop
PickupLocations21 entriesBox spawn points. Each model field is also evaluated once at load
WarehouseObjects7 entriesBox pile props

PickupActionDuration and each model field use math.random at file load. They are fixed for the lifetime of the resource, not rolled per action. Restart the resource to reshuffle them.

Stock and pricing

Stock and the price list live in server.lua, not in config.lua. At this commit each material starts at 3000 units. Selling a material returns it to stock, and taking one removes it, so a busy server drains and refills the same pool.

With LimitedMaterials = false, stock is ignored entirely and materials are unlimited.

To retune the economy, edit the Sales and stock tables in server.lua. Editing config.lua will not change prices.

Server surface

HandlerKindArguments
qb-recyclejob:server:getPriceListcallbacknone, returns the sale price table
qb-recyclejob:server:getItemnet eventnone
qb-recyclejob:server:sellItemnet eventitem, amount

Distance checks and escalation

Both money and item paths go through one helper:

local function isClose(source, loc) -- reads the ped position on the server -- 'turnIn' compares against the drop location -- 'sell' compares against the sell location -- returns true under 5.0 units end

Position is read on the server, which is the right approach. On failure the helper increments a per-citizen counter and permanently bans at three strikes, writing to the bans table with bannedby = 'qb-recyclejob' and expire = 2147483647.

Two caveats:

  • The bans table is not created by this resource. Confirm it exists with the columns name, license, discord, ip, reason, expire, bannedby before enabling.
  • The counter in isClose uses uhohs[cid] = uhohs[cid] + 1 or 0, which errors on the first failure for a citizen with no existing entry, because the addition is evaluated before the or. The getItem handler works around this with its own nil check, the sell path does not.

sellItem takes amount from the client but clamps it: the helper reduces amount to what the player actually holds before pricing, and the price itself comes from the server-side table. A forged amount therefore cannot inflate the payout.

Troubleshooting

SymptomLikely cause
”Out of stock” for a common materialLimitedMaterials is true and the pool is drained. It refills as players sell back
Server Lua error when selling from far awayThe uhohs counter arithmetic, see above. Approach the sell point
Ban insert failsThe bans table is missing or has different columns
Every pickup takes the same timePickupActionDuration is rolled once at load. Restart to reshuffle
Price changes have no effectPrices are in server.lua, not config.lua
Materials never arriveAn item name in the receive table is missing from your shared items

Proposed manual smoke test

Not yet executed. On staging, with a database backup:

  1. Confirm the bans table exists before starting.
  2. Run one full loop: pick up a box, turn it in, confirm materials arrive.
  3. Sell materials at the NPC and confirm cash matches the server-side price list.
  4. Attempt to sell from outside 5 units and record whether a ban or an error results.
  5. Set LimitedMaterials = false and confirm stock is ignored.
  6. Clear any test bans afterwards.

Sources