Features
How every oxide-dealerships system works — the catalog, test drives, payments, financing, trade-ins, ownership, employees, coupons, and more.
The full tour of everything oxide-dealerships does — what players and shop owners see in-game, how each system behaves, and which settings change that behavior. For a line-by-line list of every setting, see Configuration. For the admin commands, see the Admin Guide.
Dealership Types
Every dealership on your server is one of three types. The type decides who runs it and where the money goes.
| Type | Who runs it | How it works |
|---|---|---|
| NPC-operated | The computer | Unlimited stock of every vehicle assigned to it, always charges the catalog price. Sale money accumulates in a balance no one can withdraw. The four shipped shops (cars, boats, aircraft, trucks) are all NPC-operated. |
| Player-owned | A specific character | The owner stocks vehicles, sets retail prices, hires staff, and keeps the profit in the shop's reserve balance — the shop's own bank account, separate from the owner's personal money. Only sells what the owner has actually put in stock. |
| For-sale plot | Nobody, yet | An empty dealership listed for players to buy. A player walks up, pays the listed price, and instantly becomes the owner. Set these up with /dealership createforsale. |
You can convert an NPC shop into a player-owned one at any time by assigning an owner with /dealership setowner.
How a player finds a dealership
- Each dealership shows a blip (map icon) at its location.
- Walking into the lot reveals a greeter — an NPC in the showroom that players interact with to browse, buy, or trade in a vehicle.
- Owners and staff also get a Manage Dealership option in the same spot to open the management tablet.
Catalog and 3D Preview
When a player interacts with the greeter and chooses Browse Catalog, a full-screen catalog opens listing every vehicle that dealership sells, grouped by category (Compacts, Sedans, SUVs, and so on).
Selecting a vehicle drops the player into a 3D preview scene — their character is hidden and a camera frames a spawned example of the car. From there they can:
- Rotate the vehicle by holding A / D to spin it left or right.
- Pick a paint color from preset swatches, or fine-tune a custom paint. The color they choose is applied to the car they actually receive at purchase or test drive.
- Test Drive or Buy straight from the preview.
The preview camera has a gentle, living sway so the showroom feels alive. If the player walks too far from the greeter while the scene is open, it closes automatically. The preview locations, preset colors, rotation speed, and camera sway all live under Config.CatalogScene in shared/config.lua — most owners never need to touch them.
Test Drives
A test drive spawns the chosen vehicle for the player to drive for a limited time, then cleans it up.
- The player picks Test Drive from the catalog or preview.
- The car spawns at the dealership's test-drive spawn point.
- An on-screen TEST DRIVE label shows, along with a countdown.
- When the timer runs out — or the player leaves the vehicle — the test drive ends and the car is removed.
Test drives are configured per dealership, in the database, not in a config file. For each shop you control whether test drives are enabled, the spawn location, a time limit in minutes, and whether the player is teleported back to the lot when time runs out (the test vehicle is always removed either way). Set all of this with /dealership testdrive or through the admin dashboard.
Test drives never charge the player and never send an email — they are a transient try-before-you-buy, not a transaction.
Buying a Vehicle
A purchase always ends the same way: the player is charged, the vehicle is registered to their character, and it spawns at the dealership's delivery point ready to drive. Along the way the confirmation screen lets the buyer:
- Choose a payment method — cash, bank, or any other method you have enabled.
- Apply a promo code — if you run coupons.
- Add a trade-in — hand over a car they own to knock money off the price.
- Finance instead of paying in full — put money down and pay the rest over time.
After a successful purchase the buyer receives an in-character email receipt (if emails are enabled and a phone resource is installed).
Buyers are never charged for a car they didn't receive
If anything fails partway through a purchase (no clear spawn space, registration error), the resource refunds the player automatically and shows a clear message.
At an NPC shop, every assigned model is always available at the catalog price. At a player-owned shop, the buyer can only purchase models the owner has actually stocked, at the owner's retail price — if a model just sold out, the buyer is told to try again.
Payment Methods
There are two kinds of payment method, defined in shared/config/payments.lua:
- Money methods (
type = 'money') — draw from a framework money account such ascashorbank. The normal way to buy a car. - Item methods (
type = 'item') — the price is paid in an inventory item (for example a VIP token), where one item equals one dollar of value.
Out of the box, Cash and Bank are enabled and accepted everywhere. The file ships commented-out examples for crypto, a VIP token, and casino chips.
Item payments are a one-way sink
When a buyer pays with an item method, the item is consumed and the car is granted as normal — but the shop's reserve balance is not credited and no employee commission is paid. This is intentional: item methods suit premium or VIP currencies where you want the value to leave the economy. Only money methods credit the shop and pay commission. The management tablet shows this to owners directly.
Per-shop overrides
By default a shop accepts every method flagged as a default (cash and bank). You can override which methods a specific dealership accepts from the admin dashboard or the owner's tablet. Finance always draws its down payment and recurring payments from the account set by Config.Payments.financeAccount (default bank), regardless of which checkout method the buyer picks.
Financing
Financing lets a buyer put money down and pay off the rest in scheduled installments. It is on by default and controlled entirely from shared/config/finance.lua.
Default terms
| Setting | Default | What it means |
|---|---|---|
Config.Finance.minDownPct | 10 | The down payment must be at least 10% of the price. |
Config.Finance.minPayments | 2 | The fewest installments a buyer can choose. |
Config.Finance.maxPayments | 24 | The most installments a buyer can choose. |
Config.Finance.paymentIntervalMinutes | 60 | One installment is collected every 60 minutes of real (server) time while the buyer is online. |
Config.Finance.missWhileOffline | false | By default a loan pauses while the buyer is offline — the due date pushes forward until they return. Set to true if payments that come due offline should count as missed. |
Config.Finance.baseInterestPct | 8 | The standard interest rate added to the financed amount. |
Config.Finance.maxMissedBeforeDefault | 3 | After this many missed payments the loan defaults. |
Lifecycle of a loan
Config.Finance.dueSoonNoticeSeconds, default 24 hours), the buyer gets a reminder when they log in.Config.Finance.missWhileOffline = true, in which case it counts as missed too.Players can view and manage their loans at any time with /myloans, which opens a panel listing every active contract. From there they can make a single payment or pay off the full balance early.
How the repossession price is calculated
A repossessed vehicle is re-listed for sale at 65% of the original financed amount (the principal — the price minus the down payment), controlled by Config.UsedPriceDiscount (default 0.65). It keeps the license plate it had when it was taken; its customizations carry over only when your framework's vehicle system shares them with the bridge (in most setups the used unit re-lists at factory specification).
Optional: credit scores with oxide-banking
If you run the optional oxide-banking resource and turn on Config.Finance.useOxideBanking, financing gets smarter:
- A buyer's credit score adjusts their interest rate and caps how many installments they can take. Better credit means a lower rate and longer terms; poor credit means a higher rate and shorter terms.
- A defaulted loan generates an invoice in
oxide-bankingfor the outstanding balance.
If oxide-banking is not installed, or the setting is off, financing uses the flat base rate for everyone and skips invoicing. Nothing breaks either way.
Trade-Ins
A trade-in lets a customer hand over a vehicle they own for value, either as cash or as credit toward a purchase. On by default, controlled from shared/config/tradein.lua.
Two ways to trade in
- At the greeter (self-serve) — the player picks Trade In Vehicle, chooses one of their owned cars, and the system makes an automatic offer. They can cash out for that amount (paid to cash or bank) or apply the value toward a car they are buying.
- At the sales desk (in person) — during a manual contract sale, a salesperson can add a trade-in and override the automatic offer to negotiate a custom allowance.
How the value is set
| Step | Default | Detail |
|---|---|---|
| Automatic offer | Config.TradeIn.independentRate = 0.45 | The greeter offers 45% of the vehicle's value. |
| Re-list price | Config.TradeIn.resaleRate = 0.65 | The traded car is re-listed for sale at 65% of its catalog price, so the shop turns a margin. |
Applying credit toward a purchase
- On a cash purchase, the trade value comes straight off the price. If the trade is worth more than the car, the difference is paid to the customer's bank account.
- On a financed purchase, the trade value reduces the down payment (the financed principal is unchanged), as long as
Config.TradeIn.allowFinanceCreditis on (default yes). Any excess is likewise paid to their bank. Combining a trade-in with financing works at the self-serve greeter only — the sales desk doesn't accept trade-ins on financed contracts.
When a customer trades in at a player-owned shop, that shop's reserve balance funds any cash payout. If the shop can't cover it, the trade is declined with a clear message.
Used Inventory
Used vehicles are pre-owned cars on a dealership's lot. They come from two places:
- Repossessions — a financed car that defaulted and was taken back.
- Trade-ins — a car a customer handed over.
A used car keeps its original license plate — it is genuinely the same vehicle, not a fresh copy. Its customizations carry over only when your framework's vehicle system shares them with the bridge; in most setups the used unit re-lists at factory specification.
Used cars appear in their own tab in the catalog and the management tablet. They are always paid for in full — used cars cannot be financed.
Ownership and the Management Tablet
The management tablet is the windowed dashboard an owner or employee opens at their lot to run the business. It styles itself like a small desktop operating system with apps along a dock.
Three ways to open it
- The Manage Dealership option on the greeter.
- A radial menu entry that appears while the player is standing inside the lot.
- The chat command, by default
/managedealership(set byConfig.Tablet.command).
The apps
| App | What it does |
|---|---|
| Overview | Reserve balance and lifetime sales at a glance. Lets the owner deposit money into the shop or withdraw profit to their own bank. Shows which payment methods the shop accepts. |
| Inventory | List models for sale, set retail prices, and order stock. Restocking deducts the wholesale cost from the shop's reserve — 70% of the catalog price by default (Config.Dealerships.WholesaleMultiplier). |
| Sales | A ledger of recent transactions with totals, averages, and a per-salesperson team breakdown. |
| Sales Desk | Sell a car to a nearby customer in person with a signed contract. |
| Employees | Hire, fire, and set commission rates for staff. |
| Promotions | Create shop-scoped promo codes — only shown when the server allows owner-created coupons. Hidden by default. |
| Displays | Toggle the slow turntable spin on showroom display cars — only when an admin has enabled owner-managed rotation for that shop. |
NPC shops have no inventory or employees — those apps only apply to player-owned shops. Stocking, pricing, hiring, firing, and commission changes are owner-only actions; employees see those apps read-only.
Employees and Commission
Owners of player-owned shops can put other players on the payroll to earn commission on every sale they close.
Roles
- Sales — represents the dealership and closes sales with customers.
- Manager — closes sales like a salesperson, sees every app in the tablet, and can toggle display rotation. Stocking, pricing, hiring, firing, and commission changes remain owner-only.
There is no base wage — an employee's pay is purely the commission they earn.
How hiring works
Hiring is a handshake: both the owner and the recruit must be standing inside the dealership lot at the same time (if the lot has no zone drawn yet, standing within a few meters of each other works instead). The owner sends an offer from the Employees app, and the recruit gets an on-screen offer of employment to accept or decline. This prevents hiring someone who isn't actually there.
How commission is paid
When a sale closes at a player-owned shop, the resource looks for an on-duty employee near the greeter and pays them their commission cut out of the shop's reserve.
- "Near" means within
Config.OnDutyRadiusmeters of the greeter (default 80). An employee standing across the map earns nothing on a walk-in sale. - An owner is never paid commission on walk-in sales. For sales the owner closes themselves at the sales desk,
Config.ManualSale.ownerEarnsCommission(defaultfalse) controls whether they earn the cut. - Commission is only paid on money sales — item-method sales pay no commission.
Manual sales pay the specific salesperson who closed the deal directly, with no proximity check needed.
Manual Contract Sales
The Sales Desk lets a salesperson sell a car to a nearby customer in person, with a printed contract the customer signs. It's the role-play alternative to buying from the greeter.
Config.ManualSale.buyerRadius meters (default 5).Guard rails
- A pending contract expires after 60 seconds if not signed (
Config.ManualSale.offerTimeoutSec). - A salesperson can only have one pending offer at a time (
Config.ManualSale.maxConcurrentPerSeller). - A salesperson-set finance interest rate is clamped between 0% and 30% (
Config.Finance.maxRatePct), so staff can't write predatory loans. - The signature must match the customer's character name, or the sale is rejected.
Coupons and Promo Codes
Coupons are discount codes a buyer types in at checkout. Controlled from shared/config/coupons.lua, on by default.
Who can create them
- Admins create either global codes (work at every dealership) or shop-scoped codes (work at one shop), from the admin dashboard.
- Shop owners can create shop-scoped codes from the Promotions app — but only if
Config.Coupons.allowOwnerCreatedis enabled. It defaults tofalse, which hides the Promotions app and rejects owner-created codes.
What a coupon can do
Each code can be a fixed amount off or a percentage off, and can carry any of these limits:
- A total usage cap (how many times it can ever be used).
- A per-player cap (how many times one character can use it).
- An expiry date.
- A restriction to specific vehicle models or categories.
- A toggle for whether it can be used on financed purchases.
Rules at checkout
- A code must be 3 to 32 characters long, using letters, numbers, dashes, or underscores.
- A discount can never drop the final price below
Config.Coupons.minFinalPrice(default1) — there is always at least a token charge. - A percentage discount is capped at
Config.Coupons.maxPercent(default100). - The discount comes out of the selling shop's sale revenue.
If a code is invalid, expired, out of uses, used up by that player, not valid at that shop, blocked for the chosen vehicle, or not allowed on finance, the buyer is told exactly why.
Showroom Displays and the Showcase HUD
Showroom displays
A dealership lot can have display vehicles parked on the floor as showpieces. Each display lives in a numbered slot. A slot can optionally rotate like a turntable, spinning slowly in place — and only spins while a player is nearby, so it doesn't waste performance on an empty lot.
Admins place, move, swap, and remove display slots with the /dealership addslot, removeslot, listslots, and rotateslot commands, or through the dashboard. The default rotation speed is 8 degrees per second (Config.Showroom.rotateSpeed). Admins can also hand rotation control to the shop's owner with /dealership ownerrotation.
The Showcase HUD
The Showcase HUD is a floating card that appears above a display vehicle when a player looks at it and holds a key. It shows the car's specs, price, and a financing teaser — a quick way to window-shop without opening the full catalog. It never grabs the mouse; it's a passive overlay.
| Setting | Default | Meaning |
|---|---|---|
Config.ShowcaseHud.enabled | true | Turn the whole feature on or off. |
Config.ShowcaseHud.holdKey | 19 | The key to hold. 19 is Left Alt (the same key ox_target uses). |
Config.ShowcaseHud.maxDistance | 8.0 | How far away (in meters) the card will still appear. |
The card grows as the player gets closer and shrinks as they back away, between the nearDist and farDist ranges. It only appears for showroom display vehicles, not ordinary cars parked nearby.
Job-Restricted Shops
You can lock a dealership's self-serve greeter to one or more jobs, so only players with the right job can browse, buy, or trade in there — useful for an emergency-services depot, a trucking company yard, or a faction-only lot.
Set the allowed jobs in-game with /dealership setjobs <shopId> <job1,job2,...>, or from the Access Control card in the dashboard's Finances panel. Leaving the list blank opens the shop to everyone.
- Restricted: the greeter (browsing, buying, and trading in by walking up), and the shop's map blip, which is hidden from players who don't qualify (it reappears immediately if their job changes to an allowed one).
- Not restricted: the sales desk and the management tablet — staff can still work and owners can still manage, regardless of their job.
In-Character Emails
On top of the instant on-screen notifications, the resource can send in-character emails to a player's phone for the "paperwork" moments of a transaction. The toast is the instant feedback; the email is the keepable record. Transient events like test drives never send mail.
Emails are delivered through the o-link phone bridge, so they require a phone resource that o-link supports. If no phone resource is installed, emails are silently skipped and the on-screen notifications still work normally — nothing errors.
| Switch | Default | Sends an email when... |
|---|---|---|
Config.Email.enabled | true | Master switch — all dealership emails. |
Config.Email.employment | true | A player is hired (welcome) or let go (separation notice). |
Config.Email.receipts | true | A purchase completes (a receipt) or a financing agreement is signed. |
Config.Email.financing | true | A payment is due soon, a payment is missed, a vehicle is repossessed, or a loan is paid off. |
Config.Email.sellerCommission | true | A salesperson closes a sale (a "sale closed" notice with their commission). |