The QBox garage that pays for itself the first time you don't get duped.
Valet · Live Impound Auctions · Sub-owners · Plate Change · Boss Menu · Admin Tools
Most garage scripts ship the same 5 features and call it done. tx_garage v2 ships the 5 features other scripts skip — and it ships them with a documented security audit so your players can't dupe vehicles, money, or transfers.
| Standard QBox garages | tx_garage v2 | |
|---|---|---|
| Store / retrieve / persistent damage | ✅ | ✅ |
| Job & gang garages with grade gates | ✅ | ✅ |
| Police impound | partial | ✅ full + occupancy guard |
| Valet NPC delivery with anti-stuck pathfinding | ❌ | ✅ |
| Live auction house with anti-snipe + escrow | ❌ | ✅ |
| Transfer-with-price + accept/reject dialog | ❌ | ✅ |
| Sub-owners (key sharing, up to 4) | ❌ | ✅ |
| Plate change in-game | ❌ | ✅ |
| Boss menu with society ledger | rare | ✅ |
| Admin commands (ACE-gated) | ❌ | ✅ 5 commands |
| Discord webhooks for big events | ❌ | ✅ |
| Mileage tracking (tamper-resistant, monotonic) | ❌ | ✅ |
| Vehicle search bar in NUI | ❌ | ✅ |
| Live ticking auction timers | ❌ | ✅ |
| Documented security audit | ❌ | ✅ 11 fixes |
| Idle performance | 0.01–0.20ms | 0.00ms |
A real NPC drives your stored vehicle to your current location. No teleport cheese, no visual cuts.
- Anti-stuck pathfinding — primary spawn + 4 fallback offsets; if all fail, the player is automatically refunded
- Distance-based pricing — base fee + per-km surcharge from the nearest garage
- Fuel deduction — the valet uses fuel on the way (configurable %)
- Cancel for a configurable refund (default 50%)
- Database log for every call → analytics + abuse detection
- Per-player cooldown (default 10 min)
Vehicles unclaimed past your grace period auto-promote to a public lot. Players bid live with ticking countdowns, anti-snipe extension, and bid escrow.
- Optimistic concurrency — concurrent bids from two players never both pass; the loser is automatically refunded with no money lost
- Anti-snipe — bids in the final minute extend the auction by another minute (durable across server restarts)
- Configurable payout split — 50% original owner / 30% society sink / 20% government tax (defaults; tune per server)
- "You are leading" banner without leaking bidder identity to other players
- Watcher list — get notified ~5 min before close
- Discord webhook posts for big-money auction starts and wins
Standard scripts let any player force-transfer a vehicle to anyone. That's a grief vector (transfer junker → call cops to impound them for it). v2 fixes it with a real consent flow.
- Caller fills target server ID + sale price
- Target gets an
lib.alertDialogwith 30 seconds to accept or reject - On accept: target pays, seller receives, ownership flips atomically
- Claw-back if the seller transferred to someone else first — buyer is refunded
- 5-meter proximity gate
Add up to 4 sub-owners per vehicle. They can retrieve, store, and call valet, but cannot transfer, change plate, or remove other sub-owners. Owner-only mutations stay owner-only.
- Proximity-gated add (5m default)
- Database-backed (
tx_garage_sub_ownersJSON column onplayer_vehicles) - Visible in the sub-owner manager modal with player display names
- Configurable cost (default $5,000) and 24h cooldown per vehicle
- Format-validated server-side: 2–8 chars, A–Z 0–9
- Uniqueness enforced — collision → reject
- ox_lib input dialog (no browser prompt — premium feel)
Bosses on job garages see a Society balance chip with deposit / withdraw against a transparent SQL ledger. No society-money handwaving.
- Auction society cuts auto-deposit to the configured account
- Full ledger (
tx_garage_society_log) with action / amount / note / timestamp - Withdraw is balance-checked against the ledger, not in-memory state
| Command | What it does |
|---|---|
/tx_spawnveh <model> |
Spawn an admin vehicle |
/tx_delveh |
Delete the vehicle you're in or aiming at |
/tx_tpveh <plate> |
Teleport to a player's vehicle by plate |
/tx_impound <plate> |
Force a vehicle to impound |
/tx_release <plate> |
Release from impound to stored |
ACE permissions in server.cfg:
add_ace group.admin tx_garage.admin allow- Per-class CSS gradients for vehicle previews (super, sports, suv, motorcycle, truck, sedan, compact) — zero asset shipping, every card visually distinct
- Live search bar filters as you type
- Focus trap + ESC + Tab cycling for keyboard users
- All DOM via
textContent/appendChild— strict CSP, no innerHTML - Bundled fonts (Bebas Neue / Outfit / JetBrains Mono — offline, escrow-compatible)
v2.0 was refactored from v1 to close production-grade dupes and grief paths. Every fix is documented in the codebase:
| ID | Issue | Fix |
|---|---|---|
| C1 | Concurrent-bid race could let two players both pay | Optimistic concurrency: WHERE current_bid = expectedPrev |
| C2 | Vehicle transfer happened without target consent | Pending request table + accept dialog + atomic flip with claw-back |
| C3 | giveKey worked from any distance |
5m proximity gate |
| C4 | Store-without-state-check could clone vehicles | WHERE state='out' on every UPDATE; affectedRows checked |
| C5 | Client deleted vehicle before server confirmed | lib.callback.await round-trip; entity only deleted on ok=true |
| C6 | Cops could impound moving / occupied vehicles | Speed threshold + occupancy check |
| C7 | TIMESTAMPDIFF DAY had a 1-day rounding edge band | Switched to SECOND throughout |
| H1 | Private rent charged on every retrieve | tx_garage_rent_paid_at column with N-day cooldown |
| H2 | NUI tamper could "heal" a wreck on store | Health values clamped against previous DB values; mileage monotonic |
| H3 | Re-promote of duplicate plate threw on unique constraint | Unique-plate constraint dropped on tx_garage_auctions |
| H4 | Auction money split was hardcoded | Configurable Config.Auction.payoutSplit |
| Required | Why |
|---|---|
qbx_core |
Framework |
ox_lib |
Notifications, callbacks, dialogs |
oxmysql |
Database driver |
| Recommended | Why |
|---|---|
ox_target |
Zone-based interaction (or qb-target) |
ox_fuel |
Fuel persistence + valet deduction |
qbx_vehiclekeys |
Auto-key handoff on retrieve |
Note: v2.0 is QBox-native. For QBCore/ESX support, use v1.x (legacy branch).
# 1. Drop the resource into your server-data
resources/[tx]/tx_garage/
# 2. Import the schema (idempotent — re-runnable, only ADDS columns + tables)
mysql -u root your_db < INSTALL.sql
# 3. Add ACE permissions in server.cfg
add_ace group.admin tx_garage.admin allow
add_ace group.mod tx_garage.mod allow
# 4. Ensure the resource (after qbx_core, ox_lib, oxmysql, ox_target)
ensure tx_garage
# 5. Customize config.lua → Garages, Valet/Auction economics, payout split, webhooks
# 6. (Optional) Set Discord webhook URLs in Config.Webhooks for big-money posts
# 7. Restart your server. Done.Upgrading from v1.x? Run INSTALL.sql — it's idempotent and only ADDS columns. Your existing vehicles, auctions, and bids survive. Re-edit your config.lua (the shape changed for QBox-native).
| Metric | Value |
|---|---|
| Idle resmon (NUI closed) | 0.00ms |
| Active resmon (NUI open) | <0.10ms |
| Auction processing | server-side, dynamic interval (sleeps until next ends_at or 5min) |
| Memory footprint | ~2MB |
The auction tick is adaptive — when no auctions are open, the loop sleeps for 5 minutes between checks. When the next close is in 30 seconds, it sleeps for 30 seconds. No idle servers running useless queries.
Out of the box: English · Spanish.
Drop a new file at locales/<code>.lua and set Config.Locale = '<code>'. PRs welcome.
Does it work with QBCore or ESX? v2.0 is QBox-native for cleaner code and lower price ceiling. For QBCore/ESX, use the v1.x legacy branch (still maintained for security fixes).
Will it conflict with qbx_garages / other garage scripts?
Disable the existing garage. tx_garage uses its own tx_garage_* columns on player_vehicles, so your data is preserved if you switch back.
What happens if a player wins an auction but disconnects before close? Bids are debited at place-time (escrow). If they're offline at close, the atomic ownership flip still happens — money was already taken. Premium-tier behavior.
Can players abuse valet for teleportation? No. The valet drives with normal AI on actual roads. There are 4 fallback spawn offsets if the primary fails; if all 4 fail, the player is auto-refunded and can try again from a different spot.
Does it work with NoPixel-style multi-character?
Yes. Uses citizenid everywhere, never Steam ID.
Is it escrow-protected?
Yes. config.lua, locales/*.lua, shared/utils.lua, INSTALL.sql, README.md, and LICENSE are escrow-ignored — buyers can edit those freely. Core logic is locked per Tebex policy.
Can I disable individual systems?
Yes — every system has a Config.<System>.enabled toggle: Valet, Auction, PlateChange, SubOwners, Transfer, Webhooks, and individual admin commands.
How do I tune the auction money split?
Config.Auction.payoutSplit = { originalOwner = 0.50, society = 0.30, government = 0.20 } — must sum to 1.0. Three example presets in the comments.
- Discord — join the support server
- Tebex tickets — open from your purchase receipt
- Custom features — priority for premium-tier buyers
Breaking: QBox-native (drops QBCore/ESX bridge — use v1.x for those).
Security audit — 11 fixes: C1 auction concurrent-bid race, C2 transfer-without-consent, C3 give-key proximity, C4 store-state dupe, C5 premature client delete, C6 occupied-vehicle impound, C7 TIMESTAMPDIFF rounding, H1 private-rent charge-loop, H2 health-value tamper, H3 unique-plate-constraint crash, H4 hardcoded payout split.
Features: Sub-owners, plate change, transfer-with-price + consent, boss menu, 5 admin commands, Discord webhooks, mileage tracking, anti-snipe, vehicle search, live ticking auction timers, "you are leading" banner, per-class CSS gradient previews, focus trap.
Performance: Dynamic auction tick (M2), onResourceStop cleanup (M1), textui interaction implemented (M3).
- Condition colors, favorite vehicles, auction watchlist
- Core garage, valet, auction, multi-framework bridge
Made with ❤️ in California by tx.
Buy on Tebex ·
Discord