This page documents the vehicle data structures, type constants, storage configuration, and vehicle state management in Mythic Framework.
Vehicle Data Structure
Vehicles stored in the database have the following structure:
{
_id = ObjectId , -- MongoDB document ID
Type = 0 , -- Vehicle type (0=car, 1=boat, 2=aircraft)
Vehicle = 1234567 , -- Vehicle model hash
VIN = "ABC123456789" , -- Vehicle Identification Number
RegisteredPlate = "12ABC345" , -- License plate
FakePlate = false , -- Fake plate (string or false)
Fuel = 95 , -- Fuel level (0-100)
Owner = { -- Ownership data
Type = 0 , -- Owner type (0=character, 1=fleet)
Id = 123 , -- Character SID or job ID
Workplace = false , -- Workplace ID (fleet only)
Level = 0 , -- Grade level requirement (fleet only)
Qualification = nil , -- Required certification (fleet only)
},
Storage = { -- Storage location
Type = 1 , -- Storage type (0=impound, 1=garage, 2=property)
Id = "legion_square" , -- Storage location ID
Fine = 0 , -- Impound fine (impound only)
TimeHold = false , -- Hold timer (impound only)
},
Make = "Truffade" , -- Vehicle manufacturer
Model = "Adder" , -- Vehicle model name
Class = "Super" , -- Vehicle class
Value = 1000000 , -- Vehicle value
FirstSpawn = true , -- Never spawned before
Properties = table , -- Vehicle customization (see below)
RegistrationDate = 1700000000 , -- Unix timestamp
Mileage = 12500 , -- Miles driven
DirtLevel = 5.0 , -- Dirt level (0-15)
Damage = { -- Damage state
Engine = 950 , -- Engine health (0-1000)
Body = 850 , -- Body health (0-1000)
},
DamagedParts = { -- Individual part damage
[ 0 ] = 50 , -- Part index to damage value
[ 1 ] = 100 ,
},
WheelFitment = table , -- Custom wheel fitment data
Polish = { -- Polish/wax state
Expires = 1700000000 , -- Expiration timestamp
},
Harness = 100 , -- Racing harness durability (0-100)
Nitrous = { -- NOS system
level = 100 , -- NOS amount (0-100)
},
NeonsDisabled = false , -- Neon lights disabled
ForcedAudio = nil , -- Custom engine audio
Seized = false , -- Vehicle seized (loans)
SeizedTime = false , -- Seizure timestamp
}
Type Constants
Owner Types
Owner type determines who owns the vehicle.
Value Type Description 0 Character Owned by a player character 1 Fleet Owned by a job/faction
Character Ownership:
Owner = {
Type = 0 ,
Id = 123 , -- Character SID
}
Fleet Ownership:
Owner = {
Type = 1 ,
Id = "police" , -- Job ID
Workplace = "lspd" , -- Optional workplace restriction
Level = 10 , -- Minimum grade level
Qualification = "pilot" , -- Optional certification requirement
}
Storage Types
Storage type determines where the vehicle is stored.
Value Type Description 0 Impound Vehicle impounded with fine 1 Garage Public/job garage 2 Property Private property garage
Impound Storage:
Storage = {
Type = 0 ,
Id = 0 , -- Impound lot
Fine = 2500 , -- Impound fine
TimeHold = 24 , -- Hours before retrieval (0=immediate)
}
Garage Storage:
Storage = {
Type = 1 ,
Id = "legion_square" , -- Garage ID
}
Property Storage:
Storage = {
Type = 2 ,
Id = "property_123" , -- Property ID
}
Vehicle Types
Vehicle type determines handling and storage locations.
Value Type Description 0 Car/Truck Standard ground vehicles 1 Boat Watercraft 2 Aircraft Planes and helicopters
Usage:
-- When adding vehicle
Vehicles . Owned : AddToCharacter (
characterId ,
vehicleHash ,
0 , -- Car type
infoData ,
callback
)
-- Boat
Vehicles . Owned : AddToCharacter (
characterId ,
GetHashKey ( 'seashark' ),
1 , -- Boat type
infoData ,
callback
)
-- Aircraft
Vehicles . Owned : AddToCharacter (
characterId ,
GetHashKey ( 'frogger' ),
2 , -- Aircraft type
infoData ,
callback
)
Vehicle Properties
Vehicle customization properties follow the standard FiveM format:
Properties = {
model = 123456 ,
plate = "12ABC345" ,
plateIndex = 0 ,
bodyHealth = 1000.0 ,
engineHealth = 1000.0 ,
tankHealth = 1000.0 ,
fuelLevel = 65.0 ,
dirtLevel = 0.0 ,
-- Colors
color1 = 0 ,
color2 = 0 ,
pearlescentColor = 0 ,
wheelColor = 0 ,
dashboardColor = 0 ,
interiorColor = 0 ,
-- Paint types
paintType1 = 0 ,
paintType2 = 0 ,
-- Custom colors
customPrimaryColor = { 255 , 0 , 0 },
customSecondaryColor = { 0 , 0 , 255 },
-- Wheels
wheels = 0 ,
wheelType = 0 ,
-- Mods
modEngine = 3 ,
modBrakes = 2 ,
modTransmission = 2 ,
modSuspension = 3 ,
modArmor = 4 ,
modTurbo = true ,
modXenon = true ,
-- Extras
extras = {
[ 1 ] = true ,
[ 2 ] = false ,
[ 3 ] = true ,
},
-- Neons
neonEnabled = { true , true , true , true },
neonColor = { 255 , 0 , 255 },
-- Tire smoke
tyreSmokeColor = { 255 , 255 , 255 },
-- Windows
windowTint = 0 ,
-- Livery
livery = 0 ,
livery2 = 0 ,
}
Vehicle Entity State
Spawned vehicles have state stored in Entity(vehicle).state:
Core State Fields
-- Identity
VIN = "ABC123456789" , -- Vehicle Identification Number
Plate = "12ABC345" , -- Visible plate
RegisteredPlate = "12ABC345" , -- Real registered plate
FakePlate = false , -- Fake plate if installed
-- Ownership
Owned = true , -- Is owned vehicle
Owner = { Type = 0 , Id = 123 }, -- Owner data
GroupKeys = false , -- Group key access ("police", "ems")
-- Vehicle Info
Make = "Truffade" ,
Model = "Adder" ,
Class = "Super" ,
Value = 1000000 ,
-- State
Locked = true , -- Door locks
Fuel = 65 , -- Fuel level
Mileage = 12500 , -- Miles driven
DirtLevel = 5.0 , -- Dirt accumulation
-- Damage
Damage = {
Engine = 950 ,
Body = 850 ,
},
DamagedParts = {
[ 0 ] = 50 ,
},
-- Special Equipment
Harness = 100 , -- Racing harness
Nitrous = { level = 100 }, -- NOS level
Polish = { Expires = ... }, -- Polish expiration
-- Flags
VEH_IGNITION = false , -- Engine on/off
PlayerDriven = true , -- Was driven by player
wasThermited = false , -- Locks thermited
Hotwired = false , -- Successfully hotwired
HotwiredSuccess = false , -- Hotwire in progress
Deleted = false , -- Marked for deletion
BlownUp = false , -- Exploded
-- Sync
neonsDisabled = false , -- Neon lights disabled
ForcedAudio = nil , -- Custom engine sound
Trailer = false , -- Is a trailer
Accessing Vehicle State
Server Side:
local vehicle = entity
local vState = Entity ( vehicle ). state
print ( 'VIN:' , vState . VIN )
print ( 'Fuel:' , vState . Fuel )
print ( 'Locked:' , vState . Locked )
print ( 'Owner:' , vState . Owner . Type , vState . Owner . Id )
-- Modify state
vState . Fuel = 50
vState . Locked = true
Client Side:
local vehicle = GetVehiclePedIsIn ( PlayerPedId (), false )
local vState = Entity ( vehicle ). state
if vState . VIN then
print ( 'Vehicle VIN:' , vState . VIN )
print ( 'Fuel:' , vState . Fuel )
print ( 'Locked:' , vState . Locked )
-- Check ownership
if vState . Owned then
print ( 'This is an owned vehicle' )
end
end
Garage Configuration
Garages are defined in shared/vehicleStorage.lua:
_vehicleStorage = {
[ 'garage_id' ] = {
name = 'Garage Display Name' ,
vehType = 0 , -- Vehicle type (0=car, 1=boat, 2=aircraft)
default = false , -- Is default storage
coords = vector3 ( x , y , z ), -- Interaction point
-- Interaction zone
zone = {
type = 'box' ,
center = vector3 ( x , y , z ),
heading = 0 ,
length = 10.0 ,
width = 10.0 ,
minZ = 20.0 ,
maxZ = 25.0 ,
},
-- Spawn points
spaces = {
vector4 ( x , y , z , heading ),
vector4 ( x , y , z , heading ),
-- ...
},
-- Access restrictions (optional)
restricted = {
{
job = "police" ,
workplace = "lspd" , -- Optional
},
},
-- Fleet storage (optional)
fleet = {
{
JobId = "police" ,
WorkplaceId = "lspd" , -- Optional
HQ = true , -- Is headquarters
},
},
retrievalOnly = false , -- Can only retrieve, not store
},
}
Garage Example (Public)
[ 'legion_square' ] = {
name = 'Legion Square Parking' ,
vehType = 0 ,
default = true ,
coords = vector3 ( 215.9 , - 808.5 , 30.8 ),
zone = {
type = 'box' ,
center = vector3 ( 215.0 , - 805.0 , 30.8 ),
heading = 340 ,
length = 10.0 ,
width = 5.0 ,
minZ = 29.8 ,
maxZ = 32.8 ,
},
spaces = {
vector4 ( 229.7 , - 800.1 , 30.6 , 160.0 ),
vector4 ( 233.5 , - 798.9 , 30.6 , 160.0 ),
vector4 ( 237.3 , - 797.7 , 30.6 , 160.0 ),
},
}
Garage Example (Job Fleet)
[ 'mrpd_garage' ] = {
name = 'MRPD Vehicle Fleet' ,
vehType = 0 ,
coords = vector3 ( 452.0 , - 1018.0 , 28.5 ),
zone = {
type = 'box' ,
center = vector3 ( 452.0 , - 1020.0 , 28.5 ),
heading = 0 ,
length = 15.0 ,
width = 10.0 ,
minZ = 27.5 ,
maxZ = 30.5 ,
},
spaces = {
vector4 ( 438.4 , - 1018.3 , 28.7 , 90.0 ),
vector4 ( 438.4 , - 1014.3 , 28.7 , 90.0 ),
vector4 ( 438.4 , - 1010.3 , 28.7 , 90.0 ),
},
restricted = {
{ job = "police" },
},
fleet = {
{
JobId = "police" ,
HQ = true ,
},
},
}
Garage Example (Boat Dock)
[ 'paleto_boat' ] = {
name = 'Paleto Bay Boat Dock' ,
vehType = 1 , -- Boats
coords = vector3 ( - 277.0 , 6637.0 , 7.5 ),
zone = {
type = 'box' ,
center = vector3 ( - 280.0 , 6635.0 , 7.5 ),
heading = 45 ,
length = 8.0 ,
width = 6.0 ,
minZ = 6.0 ,
maxZ = 10.0 ,
},
spaces = {
vector4 ( - 289.5 , 6623.4 , - 0.5 , 45.0 ),
vector4 ( - 293.2 , 6627.1 , - 0.5 , 45.0 ),
},
}
Garage Example (Helipad)
[ 'hospital_helipad' ] = {
name = 'Pillbox Hill Medical Center Helipad' ,
vehType = 2 , -- Aircraft
coords = vector3 ( 351.8 , - 588.2 , 74.2 ),
zone = {
type = 'box' ,
center = vector3 ( 351.0 , - 588.0 , 74.2 ),
heading = 0 ,
length = 12.0 ,
width = 12.0 ,
minZ = 73.0 ,
maxZ = 76.0 ,
},
spaces = {
vector4 ( 351.7 , - 587.8 , 74.2 , 160.0 ),
},
restricted = {
{ job = "ems" },
},
fleet = {
{
JobId = "ems" ,
HQ = true ,
},
},
}
Impound Configuration
Impound system configuration in shared/vehicleImpound.lua:
_vehicleImpound = {
name = 'Impound Yard' ,
coords = vector3 ( - 217.7 , - 1179.0 , 23.0 ),
spaces = {
vector4 ( - 197.8 , - 1174.7 , 22.6 , 200.8 ),
vector4 ( - 194.4 , - 1174.5 , 22.6 , 200.8 ),
-- ...
},
interactionBoxZone = {
center = vector3 ( - 192.6 , - 1162.3 , 23.7 ),
length = 3.0 ,
width = 0.8 ,
heading = 0 ,
minZ = 23.5 ,
maxZ = 23.9 ,
},
}
_impoundConfig = {
RequiredPermission = 'impound' ,
RegularFine = 750 ,
Police = {
RequiredPermission = 'impound_police' ,
Levels = {
{
Fine = { Min = 2000 , Percent = false },
Holding = 0 , -- Hours
},
{
Fine = { Min = 3500 , Percent = false },
Holding = 6 ,
},
{
Fine = { Min = 5000 , Percent = false },
Holding = 12 ,
},
{
Fine = { Min = 8500 , Percent = false },
Holding = 24 ,
},
},
},
}
Impound Levels
Police can impound vehicles at different severity levels:
Level 1: Minor Violation
Fine: $2,000
Holding: 0 hours (immediate retrieval)
Level 2: Moderate Violation
Fine: $3,500
Holding: 6 hours
Level 3: Serious Violation
Fine: $5,000
Holding: 12 hours
Level 4: Severe Violation
Fine: $8,500
Holding: 24 hours
Regular Impound (Non-Police):
Fine: $750
Holding: 0 hours
Vehicle Identification
VIN Generation
VINs are auto-generated for owned vehicles:
-- Format: 3 letters + 9 numbers
-- Example: "ABC123456789"
-- Generation code
function GenerateVIN ()
local chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
local nums = "0123456789"
local vin = ""
-- 3 letters
for i = 1 , 3 do
vin = vin .. chars : sub ( math.random ( 1 , # chars ), math.random ( 1 , # chars ))
end
-- 9 numbers
for i = 1 , 9 do
vin = vin .. nums : sub ( math.random ( 1 , # nums ), math.random ( 1 , # nums ))
end
return vin
end
Plate Generation
License plates are auto-generated:
-- Format: 8 characters (numbers and letters)
-- Example: "12ABC345"
function GeneratePlate ()
local charset = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
local plate = ""
for i = 1 , 8 do
local rand = math.random ( 1 , # charset )
plate = plate .. charset : sub ( rand , rand )
end
return plate
end
Best Practices
Before performing vehicle operations: -- Check if vehicle is owned
local vState = Entity ( vehicle ). state
if not vState . VIN then
print ( 'Not an owned vehicle' )
return
end
-- Get vehicle data
Vehicles . Owned : GetVIN ( vState . VIN , function ( vehData )
if vehData then
-- Vehicle exists in database
end
end )
Verify Ownership Before Actions
Check ownership before allowing actions: local player = Fetch : Source ( source )
if not player then return end
local char = player : GetData ( 'Character' )
if not char then return end
local stateId = char : GetData ( 'SID' )
Vehicles . Owned : GetVIN ( VIN , function ( vehData )
if vehData . Owner . Type == 0 and vehData . Owner . Id == stateId then
-- Player owns this vehicle
else
-- Not the owner
end
end )
Use Entity State for Real-Time Data
Entity state is synced automatically: -- Update fuel (auto-synced to all clients)
Entity ( vehicle ). state . Fuel = 50
-- Read on client (automatically updated)
local vState = Entity ( vehicle ). state
print ( 'Fuel:' , vState . Fuel )
Always save vehicle before deleting: -- ✅ Good - Uses Delete export (saves automatically)
Vehicles . Owned : Delete ( VIN , function ( success )
if success then
print ( 'Vehicle saved and deleted' )
end
end )
-- ❌ Bad - Direct deletion without saving
DeleteEntity ( vehicle )
Handle Fleet Access Properly
Check grade level and workplace: local player = Fetch : Source ( source )
if not player then return end
local char = player : GetData ( 'Character' )
if not char then return end
-- Get character's jobs array
local jobs = char : GetData ( 'Jobs' )
Vehicles . Owned : GetVIN ( VIN , function ( vehData )
if vehData . Owner . Type == 1 then
-- Fleet vehicle - check if character has the required job
for _ , job in ipairs ( jobs ) do
if job . Id == vehData . Owner . Id then
if not vehData . Owner . Level or job . GradeLevel >= vehData . Owner . Level then
if not vehData . Owner . Workplace or vehData . Owner . Workplace == job . WorkplaceId then
-- Has access
end
end
end
end
end
end )
Data Migration
When modifying vehicle data structures, use database migrations:
-- Example migration: Add new field
Database . Game : updateMany ({
collection = 'vehicles' ,
query = {
NewField = {[ '$exists' ] = false }
},
update = {
[ '$set' ] = {
NewField = defaultValue
}
}
}, function ( success , modifiedCount )
print ( 'Updated' , modifiedCount , 'vehicles' )
end )
Next Steps
Vehicles - Exports Vehicle management methods
Vehicles - Events Vehicle-related events
Garages Feature Complete garage system
Impound System Vehicle impound mechanics
Entity State Performance: Entity state is automatically networked. Avoid storing large tables or frequently changing data in entity state to minimize network traffic.
VIN Uniqueness: VINs must be globally unique. Never manually assign VINs without checking for duplicates in the database first.