FiveM Vehicle Keys & Garages — Quasar Framework (qs-core) | Quasar Store | Quasar Store
Documentation
Vehicles
FiveM vehicle keys, lockpick hotwiring, 31 garages with 3D preview and a car dealership for Quasar Framework (qs-core). Works with ESX and QBCore scripts.
Quasar Framework (qs-core) ships a complete FiveM vehicle system for roleplay servers: vehicle keys with lock, unlock and hotwiring, 31 garages with a 3D preview, a car dealership with a showroom, and admin tools to spawn, repair and delete vehicles. Every owned car lives in one vehicles table, so the keys, the garages, the dealership and your own scripts all agree on who owns what — whether the rest of your server runs ESX, QBCore or Quasar Framework scripts.
Nothing here needs a single line of code to get running: the txAdmin recipe starts every resource, and everything you might want to change is in a Lua config.lua.
Resource
Folder
What it does
qs-corevehiclekeys
[core]
Keys per plate, lock and unlock, engine blocked without keys, hotwiring with a lockpick, /givekeys, /adminkeys.
qs-garage
[addons]
31 garages with map blips, a vehicle list with a turntable 3D preview, take out and store.
qs-vehicleshop
[addons]
Dealership with a salesman, category tabs, live preview and instant delivery.
qs-core
[core]
The vehicles table, /car and /dv, and the owned-vehicle exports used by everything above.
qb-vehiclekeys, LegacyFuel
[bridge]
Compatibility shims so QBCore and ESX scripts find the keys and fuel APIs they expect.
Lock or unlock the vehicle you are in, or the closest one within 5 m. Needs its keys.
G (hotwire)
Everyone
Hotwire the keyless vehicle you are driving. Needs a lockpick.
/givekeys [id]
Everyone
Give a copy of the keys of the vehicle you are sitting in.
E at a garage
Everyone
On foot: open the garage. Driving: store the vehicle.
E at the dealership
Everyone
Open the showroom.
/adminkeys [id]
Admins
Give keys of the vehicle you are sitting in to yourself or a player.
/car <model> / /dv
Admins
Spawn a vehicle with keys / delete the nearest vehicle.
U and G are FiveM key mappings: each player can rebind them in Settings → Key Bindings → FiveM. The E prompts use the game's context key and are not rebindable.
Keys belong to a plate. If you sit in the driver seat of a vehicle whose plate you have no keys for, the engine is held off and you cannot drive away — you need the keys, or a lockpick and steady hands. Passengers are never blocked.
You sit in the driver seat of a car registered to your character. Quasar Framework checks the vehicles table once per plate and hands you the keys automatically.
Garage
You take a vehicle out of a garage.
Dealership
Your new car is delivered.
Job vehicles
You take a car from the police or EMS garage, or start a delivery shift and get the van.
Hotwiring
You win the lockpick minigame.
Another player
They run /givekeys while sitting in the vehicle.
Admin
An admin runs /adminkeys, spawns the car with /car, or spawns it from the admin menu (F6 → Self → Spawn Vehicle).
Scripts
Any script calls GiveKeys, or triggers the QBCore-style vehiclekeys:client:SetOwner event (see For developers at the end of this page).
When you are the driver and have no keys, the engine is switched off and kept from starting on its own. A help prompt tells you what to do:
With a lockpick in your inventory: "Hold G to hotwire".
Without one: "You need keys to drive this. Get a lockpick to hotwire it".
As soon as you get the keys — from the owner check, a friend, an admin or a successful hotwire — the block is lifted within half a second and you can start the engine. Set Config.RequireKeysToDrive = false if you want anyone to drive any car.
Inside a vehicle, it acts on that vehicle. On foot, it acts on the closest vehicle within 5 m (Config.LockDistance).
You need the keys of that plate, otherwise you see "You don't have keys for this vehicle".
On foot your character clicks the key fob, the lights flash, and you get "Vehicle locked" or "Vehicle unlocked".
The new lock state is synced to every player on the server.
Keys also guard the vehicle's storage in qs-coreinventory: the trunk opens only if the vehicle is unlocked and you hold its keys, and the glovebox needs the keys. See Inventory, Items & Weapons.
Hotwiring is how you steal a car in Quasar Framework. You need to be the driver of a keyless vehicle and carry at least one lockpick (sold at the Hardware Store for $35).
Get in the driver seat
Sit in a car you have no keys for. The engine stays off and, with a lockpick on you, the prompt invites you to hotwire it.
Press G
The lockpick minigame opens. A pick sweeps around a ring: press SPACE while it is inside the highlighted zone to set the pin.
Beat every round
The default is 3 rounds (Config.HotwireRounds, from 1 to 6). Each round the zone gets smaller and the pick faster. One miss ends the attempt. ESC or Backspace cancels, and after 30 seconds the attempt fails on its own.
Drive away — or run
On success you get the keys, the engine starts and you see "The engine roars to life".
When the attempt fails (a miss, a cancel or the timeout):
One lockpick is removed from your inventory (Config.BreakLockpickOnFail) and you see "The lockpick snapped".
The vehicle's alarm goes off.
If qs-police is running, every police officer gets a "Vehicle break-in reported" alert at your position. Alerts are limited to one every 8 seconds per player, so spamming attempts does not flood the police.
Admins can give themselves or anyone the keys of the vehicle they are sitting in:
bash
/adminkeys # keys for you
/adminkeys 12 # keys for player 12
You must be sitting in the vehicle ("You are not in a vehicle" otherwise), and the target must be online ("No one nearby" otherwise). The command needs the command.adminkeys ACE, which add_ace group.admin command allow in the shipped server.cfg already grants. It does nothing from the server console. See Administration.
The key system is built for a low resmon. A single check runs every 500 ms — nothing runs every frame. Ownership is asked from the server once per plate per session, and lock changes are only sent when someone presses the key. Nothing is written to the database.
Players park and retrieve their cars at 31 garages spread across Los Santos, Blaine County and Paleto Bay. Each garage is marked on the map with a blue Garage blip, and opening one shows your cars in a cinematic 3D preview on a turntable.
Legion Square (legion_square), Pillbox Hill Garage (pillbox_hill_garage), Little Seoul Parking (little_seoul_parking), Centro Parking (centro_parking), Motel Parking (motel_parking)
Vinewood & Mirror Park
Vinewood West (vinewood_west), Vinewood Center (vinewood_center), Vinewood Small Park (vinewood_small_park), Laguna Parking (laguna_parking), Mirror Park Parking (mirror_park_parking)
West side & beaches
Spanish Ave Parking (spanish_ave_parking), San Andreas Beach (san_andreas_beach), Del Perro Private (del_perro_private)
South & East Los Santos
Elysian Parking (elysian_parking), Cypress Flats Parking (cypress_flats_parking), El Burro Parking (el_burro_parking), La Mesa Parking (la_mesa_parking), La Mesa Mechanics (la_mesa_mechanics), Big Ranch Station (big_ranch_station), Rancho Garage (rancho_garage)
Airport
Airport Los Santos (airport_los_santos), Airport Parking (airport_parking)
Blaine County
Penitentiary (penitentiary), The Motor Hotel (the_motor_hotel), Alamo Sea Parking (alamo_sea_parking), Sandy Shore Parking (sandy_shore_parking), Gran Senora Desert (gran_senora_desert), Grapeseed Parking (grapeseed_parking), Grapeseed Village Park (grapeseed_village_park)
Paleto Bay
Paleto Bay Parking (paleto_bay_parking), Small Paleto Park (small_paleto_park)
Every garage is public: there are no job or gang garages, and every player sees every blip. The id in brackets is what is saved in the garage column of the vehicles table.
every car of your character stored in this garage, whether it is currently in or out;
plus every car of yours that has no valid garage — a car you bought at the dealership and have not stored yet, or a car whose garage was removed or renamed in the config. These show up in every garage and can be taken out from any of them. Storing them anywhere gives them that garage as their new home.
Cars belong to your character, not your account: each character in multicharacter has its own garage contents.
Select a car and press Take out. The garage checks that:
The car belongs to your character.
It belongs to this garage, or to no valid garage.
It is not already out in the world.
The car then appears at the garage's spawn point with its plate, saved colours and mods, saved engine and body damage and saved fuel. It is cleaned, unlocked, you get the keys, and you are placed in the driver seat with "Vehicle taken out". The car is marked Out in the database.
The garage does not clear the spawn point before spawning, so keep spawn points where players do not usually park.
Drive into any garage point. Within 3 m you see "Press E to store this vehicle". Press E:
You must be the driver ("You must be in the driver seat" otherwise).
The car must be registered to your character. Having its keys is not enough: a friend's car, a hotwired car or a car spawned with /car is refused with "This is not your vehicle".
Any garage works, whichever garage the car came from. The garage you store it in becomes its home.
The car's current state is saved, the vehicle disappears and you see "Vehicle stored".
You can add garages in two places. garages.lua holds the 31 default garages in a one-line format and builds the id, label, blip and prompt position for you. config.lua takes the full format when you want your own id or a different blip.
Collect the three positions
Use the admin command /coords at each spot. It prints vec4(x, y, z, heading) in the F8 console and on screen.
Menu point: where players press E. Players also drive into this point to store.
Spawn point: where taken-out cars appear. Face the way the car should leave.
Preview point: where the 3D preview car stands. The camera sits 5.2 m in front of the car along this heading, so face the heading toward open space.
Add the garage
lua
-- [addons]/qs-garage/garages.lua, inside the `extra` table
{ name = 'Beach House Garage', menu = vec3(-1520.40, -430.10, 35.44), spawn = vec4(-1515.20, -425.80, 35.20, 230.0), preview = vec4(-1530.00, -440.00, 35.30, 140.0) },
The id is generated from the name: beach_house_garage. The blip is the standard blue Garage blip.
lua
-- [addons]/qs-garage/config.lua
Config.Garages = {
{
id = 'beach_house', -- unique, saved in vehicles.garage
label = 'Beach House Garage', -- title of the garage menu
coords = vec4(-1520.40, -430.10, 35.44, 0.0), -- menu point (heading unused)
spawn = vec4(-1515.20, -425.80, 35.20, 230.0), -- where cars appear
preview = vec4(-1530.00, -440.00, 35.30, 140.0), -- where the preview car stands
blip = { sprite = 357, color = 3, scale = 0.5, label = 'Garage' }, -- remove for no blip
},
}
Restart the garage
Run restart qs-garage in the server console (or restart the server). The list of valid garage ids is built when the resource starts.
The dealership sells cars straight to players. It sits at Premium Deluxe Motorsport in downtown Los Santos, marked with a Dealership blip, where a salesman waits with his clipboard.
Walk up to him. Within 2.5 m you see "Press E to browse the dealership". Press E.
Browse the showroom
Your character is frozen and the HUD hides. The camera moves to the showroom floor, where the first car of the first category turns on a platform. The menu shows the category tabs, the cars with their prices, and your cash and bank balances.
Preview
Click any car to swap the showroom car, with a short fade between them. Showroom cars carry the plate SHOWROOM and only you can see them.
Buy
Press Buy. The price comes from the server's catalogue, never from the player's game, and the server checks that you are still at the dealership.
Drive away
You see "Vehicle purchased! Plate: QS…", the showroom closes and your new car waits at the delivery point with a full tank, clean and unlocked. You get the keys and are placed in the driver seat.
Message
Why
"You cannot afford this vehicle"
No payment account has the full price.
"You are too far from the dealership"
The server found you more than 12.5 m from every dealership salesman.
"Purchase failed"
The model is not in the catalogue, you clicked Buy twice within 1.5 s, or no free plate was found.
Payment: the accounts in Config.PayAccounts are tried in order — bank first, then cash. The first account that holds the full price pays it all; a price is never split across accounts. The transaction is recorded with the reason vehicleshop:<model>.
Plate: QS followed by 5 random letters and digits (for example QS7K2XA), checked against the database so it is unique.
The car is saved as yours immediately, marked Out, with the garage legion (Config.DefaultGarage). legion is not one of the 31 garage ids, so until you park it the car shows up in every garage:
Drive it to any garage and store it from the driver seat. That garage becomes its home.
If you lose it before storing it (destroyed, server restart…), open any garage and take it out again.
Want new cars to belong to a specific garage instead? Set Config.DefaultGarage to one of the garage ids, for example 'pillbox_hill_garage'. New cars are then listed only in that garage.
Admins (anyone with the command.qs ACE) get a set of vehicle tools through commands and the admin menu on F6. See Administration for how to become an admin.
Tool
How
What it does
Spawn a car
/car <model>
Spawns the model where you stand, puts you in the driver seat, sets a QS + 4-digit plate and gives you the keys. Unknown models show "Invalid vehicle model."
Spawn a car (menu)
F6 → Self → Spawn Vehicle
Clears the way first: deletes the car you are in and any empty car within 3 m of you or of the spawn point, 3 m in front of you (cars with another player inside are left alone). Then spawns the model with a full tank, puts you in the driver seat and gives you the keys.
Delete a car
/dv
Deletes the car you are in, or the closest one within 5 m.
Delete a car (menu)
F6 → Self → Delete Vehicle
Deletes the car you are in, or the closest one within 6 m.
Repair
F6 → Self → Fix Vehicle
Fully repairs the car you are in: engine, body, deformation and dirt.
Clear the area
F6 → Self → Clear Area
Removes vehicles and objects within 30 m of you.
Keys
/adminkeys [id]
Keys of the car you are sitting in, for you or a player.
The [bridge] folder includes a LegacyFuel-compatible shim, so scripts and the HUD that read exports['LegacyFuel']:GetFuel(vehicle) work out of the box. While you drive, the engine burns fuel (more at high RPM), and at 0 the engine shuts off. Garages save the fuel level and restore it on take-out; dealership and admin-menu cars start with a full tank. The shim has no fuel pumps or jerry cans of its own. See Integrations for fuel scripts.
Server events qb-vehiclekeys:server:AcquireVehicleKeys and qb-vehiclekeys:server:GiveVehicleKeys, and the server export GiveKeys(source, plate).
QBCore scripts that hand out keys after a job, a rental or a heist therefore give real Quasar Framework keys. QBCore's player_vehicles table does not exist: owned cars are in vehicles, and exports['qs-core']:GetPlayerVehiclesQBShape(citizenid) returns them in the player_vehicles shape. QBCore garages or vehicle shops that run their own SQL on player_vehicles are not supported — use qs-garage and qs-vehicleshop.
The ESX bridge creates ESX's owned_vehicles table so scripts that expect it start cleanly, but Quasar Framework keeps owned cars in vehicles, and owned_vehicles stays empty. ESX garages or vehicle shops that run their own SQL on owned_vehicles are not supported — use qs-garage and qs-vehicleshop. ESX scripts that only spawn vehicles keep working; give the player keys with the GiveKeys export if the car should be drivable.
local plate = GetVehicleNumberPlateText(vehicle)
exports['qs-corevehiclekeys']:GiveKeys(plate)
if exports['qs-corevehiclekeys']:HasKeys(plate) then-- the local player can drive and lock this vehicleend
exports['qs-corevehiclekeys']:RemoveKeys(plate)
local all = exports['qs-corevehiclekeys']:GetKeys() -- { [plate] = true }
Plates are compared without trailing spaces. Keys are session-only.
Same event name as qb-vehiclekeys, so QBCore scripts already use it. qs-corevehiclekeys:client:give and qs-corevehiclekeys:client:remove (argument plate) are also available.
GetCitizenVehicles / GetOwnedVehicles (server)
lua
local cars = exports['qs-core']:GetCitizenVehicles(citizenid)
for _, car inipairs(cars) doprint(car.plate, car.model, car.garage, car.state, car.fuel)
end
Every row of vehicles owned by that character, with props already decoded. GetOwnedVehicles(citizenid) returns the same. GetGarageVehicles(citizenid, garage) filters by garage id.
GetVehicleByPlate / PlateExists (server)
lua
local car = exports['qs-core']:GetVehicleByPlate('QS7K2XA') -- row or nillocal taken = exports['qs-core']:PlateExists('QS7K2XA') -- boolean
CreateOwnedVehicle — give a player a car (server)
lua
local player = exports['qs-core']:GetPlayer(source)
exports['qs-core']:CreateOwnedVehicle({
citizenid = player.citizenid,
license = GetPlayerIdentifierByType(source, 'license'),
plate = 'QSGIFT1',
model = 'sultan',
garage = 'legion_square',
state = 1, -- 1 = parked in the garage
})
Defaults: garage = 'legion', state = 1, fuel = 100, engine and body = 1000.0, props = {}. Check the plate with PlateExists first: plates are unique.
UpdateOwnedVehicle / SetVehicleState (server)
lua
exports['qs-core']:UpdateOwnedVehicle(plate, { garage = 'legion_square', state = 1, fuel = 80, engine = 1000.0, body = 1000.0, props = {} })
exports['qs-core']:SetVehicleState(plate, 1, 'legion_square') -- garage is optional
UpdateOwnedVehicle writes all six fields at once, so always pass garage and state along with the values you want to keep (read them first with GetVehicleByPlate).
SpawnVehicle (server)
lua
local netId = exports['qs-core']:SpawnVehicle(source, 'sultan', vector4(x, y, z, heading), true)
Creates the vehicle on the server and, with true, warps the player into the driver seat. Returns the network id, or nil if the vehicle could not be created. It does not give keys.
Driving it from your own scripts? Every command, keybind, export and event is listed in Commands and Exports. Something not behaving? Check Common Errors.
The 31 default garages from garages.lua are added after yours.