Skip to main content
TRACK A·ADD CONTENT·Verified June 2026 · Lua 5.4 · ox_lib 3.x
Learning with an AI assistant?
Copies this lesson plus 2026 ground rules (no lua54 'yes', Cfx.re Portal, correct callback signatures) as a ready-to-paste mentor prompt.

Build a FiveM carpack from scratch

Adding vehicles to FiveM is the most common first project for server owners. A carpack bundles everything - 3D models, textures, audio, handling data - into one resource. This lesson walks through the full structure using a real working example (Karin 98S), so you can swap in any add-on vehicle.

You'll build
A complete carpack with proper folder structure, spawn code, and fxmanifest that loads automatically.
Time
~30 minutes
You need
A local FiveM server, a text editor, and the carpack example files.
You'll learn
The carpack folder structure (data/, stream/, audio/), file types (.meta, .yft, .ytd, .awc, .dat, .rel), spawn codes, and fxmanifest auto-integration.
BEFORE YOU START

Build it

Learn the folder structure

You know what each folder and file type does.

Every carpack follows this structure:

code
carpack/
fxmanifest.lua         <- tells FiveM what to load
data/                  <- vehicle metadata
handling.meta        <- physics: mass, traction, suspension
vehicles.meta        <- vehicle definition: model name, type, plates
carvariations.meta   <- color variations and liveries
carcols.meta         <- color definitions
stream/                <- 3D models and textures (streamed to clients)
modelname.yft        <- vehicle 3D model (fragment)
modelname_hi.yft     <- high-detail interior model
modelname.ytd        <- texture dictionary (paint, interior, details)
audio/                 <- engine sounds
modelname.awc        <- audio wave container
modelname.dat        <- audio configuration (rel files reference)
modelname.rel        <- audio relationship data

File types quick reference:

  • .yft - model geometry (3D mesh)
  • .ytd - texture dictionary (images)
  • .meta - XML metadata (handling, vehicle definition)
  • .awc - compressed audio
  • .dat / .rel - audio config

Write the fxmanifest

FiveM knows how to load your vehicle.
code
fx_version 'cerulean'
game 'gta5'

description 'Karin 98S/1 Carpack - Quasar School'

files {
'data/*.meta',
'stream/*.yft',
'stream/*.ytd',
'audio/*.awc',
'audio/*.dat',
'audio/*.rel',
}

data_file 'HANDLING_FILE'        'data/handling.meta'
data_file 'VEHICLE_METADATA_FILE' 'data/vehicles.meta'
data_file 'CARCOLS_FILE'          'data/carcols.meta'
data_file 'VEHICLE_VARIATION_FILE' 'data/carvariations.meta'
data_file 'AUDIO_WAVEPACK'       'audio'
data_file 'AUDIO_GAMEDATA'       'audio/dlcname_game.dat'
data_file 'AUDIO_SOUNDDATA'      'audio/dlcname_sounds.dat'

Key lines: files {} lists every asset the client downloads. data_file lines tell FiveM to parse those metadata files and integrate the vehicle into the game.

Engine audio needs three data_file lines. AUDIO_WAVEPACK is a real, documented data_file type (it uses the audWavePackDataFileMounter): point it at the FOLDER that holds your .awc wave containers, and the mounter registers every container in that folder. Then AUDIO_GAMEDATA loads the compiled game config and AUDIO_SOUNDDATA loads the compiled sounds config. The compiled config names carry a number that changes per pack - for example game.dat151.rel and sounds.dat54.rel - so open the audio/ folder and match the real file names your pack shipped. Do not rely on 'audio/*.awc' in files {} alone to mount the wave containers; AUDIO_WAVEPACK pointing at the folder is what actually mounts them.

Understand the spawn code

You know how to spawn the vehicle by its model name.

The model name comes from vehicles.meta - look for <modelName>s98</modelName>. That string is what you use in code:

code
-- Spawn the vehicle by its model name
local model = 's98'  -- matches <modelName> in vehicles.meta
RequestModel(model)
while not HasModelLoaded(model) do
Wait(0)
end
local coords = GetEntityCoords(PlayerPedId())
local veh = CreateVehicle(model, coords.x + 2, coords.y, coords.z, 0.0, true, false)
SetVehicleNumberPlateText(veh, 'QUASAR')
SetModelAsNoLongerNeeded(model)

Keep reading the full lesson

Sign in to start, then unlock every step of this lesson and the full FiveM School with a membership.

Still ahead in this lesson
  • Common failures

The remainder of Build a FiveM carpack from scratch is available to FiveM School members.