XyraLScripts
Installation guide

XS-Mechanic

A mechanic shop you build in game. Draw the walls, drop the bays, bind it to a job — and the parts list comes off the car itself, so there is no per-vehicle config to write.

01

Requirements

Short list:

  • ox_lib
  • oxmysql
  • Qbox (qbx_core) or QBCore (qb-core)

Any one of ox_inventory, qb-inventory, qs-inventory, codem-inventory, core_inventory or ps-inventory works. ox_target or qb-target are used when present; without either you get a marker and a key prompt.

No ESX. Banking and billing resources are optional and detected — see below.

02

Installation

  1. Drop the folder into your resources.
  2. Add ensure XS-Mechanic after ox_lib and oxmysql.
  3. Paste the block for your inventory from items/ — ox_inventory.lua or qb_core.lua — and copy the 37 images from inventory_images/.
  4. Make a job for the shop in your framework.
  5. Give yourself the builder ace: add_ace group.admin xs.mechanic allow.
  6. In game, run /mechanic.

The database sets itself up on first start. sql/xs_mechanic.sql is there if you would rather run it by hand.

On ox_inventory the client = { export = ... } lines in the item block are not optional. ox_inventory ignores CreateUseableItem and only calls an export named in the item definition, so without them using a part does nothing at all — silently — and it looks like the resource is broken.

03

Ownership is the job

A player owns a shop because an admin built it over an interior, bound it to a job, and gave them that job. There is no buying, selling or transferring shops.

Several shops means several jobs, each sealed off from the others: a mechanic at one shop cannot see another shop's orders, stock or money.

Grades decide who can set prices, hire and fire. A boss cannot promote above their own grade, or fire themselves.

04

Building a shop

/mechanic opens a free camera. Fly to the interior you want and place what the shop needs:

  • Boundary — fly the walls dropping points. That shape is what "at the shop" means for every check in the resource.
  • Tuning bay — where work happens. Fitting anything needs the mechanic stood on one.
  • Storage — the shop's shelf. Without one the shop reads the mechanic's own pockets instead, so a one-room self-service shop still works.
  • Bench — turns scrap into parts.
  • Desk — the laptop prop. Invoices, orders, staff, money.
  • Dyno — optional; the Dyno app is hidden at shops without one.

Nothing in config.lua is a coordinate. The resource ships empty and nothing works until you build a shop.

05

Work orders and billing

A customer in a bay picks what they want on their own car and sends it over with a note. It lands on the tablet of whoever is working, and the mechanic who connects to that car sees it.

Parts are never billed from the tuning screen. They go on the order, the order gets fitted, and the order gets billed — once, from the Orders app.

Billing asks who is paying and offers three answers: the registered owner (listed first, and billable even when they are offline), anyone standing close enough, or a server ID typed in by hand.

If you already run an invoice resource, point this at it. Config.Bridges.billing finds okokBilling, esx_billing or qb-phone on its own, and Config.Invoices.provider.event takes anything else — one server event carrying the society, shop, mechanic, customer, amount, label, plate and invoice id. The row is still written to xs_mechanic_invoices either way, because the shop's own screens read it.

06

Fitting parts

Fitting happens at the car, on a bay, out of the driver's seat. There are three ways in and they all end in the same place:

  • Use the part. It looks for a work order on that plate and fits the line it belongs to.
  • Press Fit on the line in the Orders app. It finds the car in front of you, so the laptop at the desk can fit things too.
  • Use a part with nothing written down. It asks what the part should go on, narrowed to the slots that part is actually for, read off the car.

With an order on the car the choice narrows to what was ordered: level 3 ordered means level 2 is listed and cannot be picked. Slots the order says nothing about stay open.

07

Stock and the bench

Each kind of work uses up a part. Config.Stock.categoryItems maps a category to its part and Config.Stock.slotItems overrides that for slots that deserve their own — armour, suspension and turbo. Everything else on the performance side takes the generic performance part.

A part counts whether it is on the shelf or in the mechanic's pockets, and the shelf is always spent first so nobody loses parts they brought with them. Config.Stock.useFrom turns either half off.

The shelf is 500 slots and four tonnes by default. A bench that makes ten at a time fills a small one in an afternoon — Config.Stock.storage is the dial.

Turn Config.Stock.require off and nothing is ever consumed, which is how the resource behaves without stock at all.

08

Servicing and tuning

Nine parts wear out: oil, filter, plugs, clutch, pads, tyres, suspension and two for electrics. Each one has a lifespan in kilometres and a handling field it degrades. The odometer is built in — there is no second resource to install.

Wear is worked out server side from reported distance, never sent by the client.

Custom tuning is the things GTA has no mod slot for: engine swaps with their own audio, drivetrain conversions, turbos, brake kits, gearboxes and drift tunes. Each carries its own part. handlingOverwrites decides whether a package replaces a handling value or adds to it.

These defaults are tuned against vanilla vehicles. An addon car with an inflated handling file can come out slower after a swap, because the package overwrites a field the addon had inflated to compensate for something else. Blacklist the vehicle or fix its handling.

09

Before going live

  • Build a shop first. Everything else is hidden until one exists.
  • The tablet is an item. Players need it in their inventory, and Config.Tablet.checkSeconds decides how often that is re-checked while the panel is open.
  • Pricing is fixed, a share of the vehicle's value, or both — per category, and editable per shop from the laptop.
  • Persistence splits in two: anything lib.getVehicleProperties carries goes to your framework's own player_vehicles.mods, so every garage already re-applies it. Odometer, servicing, performance packages and stance live in xs_mechanic_vehicles and are pushed to clients as a state bag.
10

Troubleshooting

Using a part does nothing

On ox_inventory, the client = { export = ... } line is missing from that item's definition. ox_inventory only calls an export named in the item itself, so the use is silently dropped.

/mechanic does nothing

The ace is not granted. Run add_ace group.admin xs.mechanic allow, or put your framework's admin groups in Config.Admin.groups.

Fit is greyed out on a part I just made

Make sure you are on 1.0.0 or later. Before that, crafting did not tell the open panels, so they kept showing the old stock count.

The apps for tuning or the dyno are missing

They are hidden at a shop with no tuning bay or no dyno placed. Build the point and they appear.

Nothing can be fitted

Fitting needs the mechanic stood on a tuning bay, out of the car, inside the shop boundary. A shop with no bay placed is not held to the bay rule — there would be nowhere to stand.

An addon car shows no options

The options are read off the vehicle. If the model genuinely has no mod slots, there is nothing to list. Check it has a modkit in its vehicles.meta.

11

Updating

  1. Back up the database first.
  2. Keep a copy of your edited config.lua.
  3. Check recent commits for SQL changes before replacing files.
  4. Replace the resource folder, merge your config back, restart.
12

Support

Bugs and questions go to the Discord. Include your server's console output — the resource prints the reason when it refuses to do something, and that line is usually the whole answer.

XS-Mechanic on GitHub