Engineering
Server-side entity spawning in FiveM
Spawn entities from the server in FiveM with OneSync: CreateVehicleServerSetter vs CreateVehicle, vehicle types, handing the network ID to the client, putting the player in the seat, plates and state, cleanup, routing buckets and entity lockdown.
Overview
Spawning a garage car on the client is how most scripts start — and how most exploits work, because the client can spawn anything. Moving creation to the server means the server decides what exists, knows the network ID immediately, and lets you turn on entity lockdown so cheaters cannot spawn at all.
01Spawning a vehicle
local function spawnVehicle(src, model, coords, heading, plate)
local hash = type(model) == 'string' and joaat(model) or model
local veh = CreateVehicleServerSetter(hash, 'automobile', coords.x, coords.y, coords.z, heading)
local deadline = GetGameTimer() + 5000
while not DoesEntityExist(veh) do
if GetGameTimer() > deadline then return nil end
Wait(0)
end
if plate then SetVehicleNumberPlateText(veh, plate) end
Entity(veh).state:set('owner', src, true)
SetPedIntoVehicle(GetPlayerPed(src), veh, -1)
return veh, NetworkGetNetworkIdFromEntity(veh)
end| Vehicle class | `type` value |
|---|---|
| Cars, vans, trucks, quads | automobile |
| Motorbikes, bicycles | bike |
| Boats | boat |
| Helicopters | heli |
| Planes | plane |
| Submarines | submarine |
| Trailers | trailer |
02Finishing on the client
Some things — mods applied from saved properties, fuel scripts, keys — still run on the client. Send the network ID, let the client wait until the vehicle exists locally, then apply them. The pattern is in entity ownership and network IDs.
-- server
local veh, netId = spawnVehicle(src, 'sultan', vec3(-45.0, -1098.0, 26.0), 70.0, 'PITY 01')
if netId then TriggerClientEvent('garage:spawned', src, netId, props) end
-- client (waitForNet from the network ID guide)
RegisterNetEvent('garage:spawned', function(netId, props)
local veh = waitForNet(netId)
if not veh then return end
-- apply saved mods here, e.g. lib.setVehicleProperties(veh, props)
end)Peds and objects
local ped = CreatePed(4, `s_m_y_cop_01`, 441.0, -982.0, 30.7, 90.0, true, true)
local obj = CreateObjectNoOffset(`prop_barrier_work05`, 400.0, -980.0, 29.4, true, true, false)
FreezeEntityPosition(obj, true)A server-created ped has no behaviour of its own. A handful of task natives exist server-side (TaskPlayAnim, TaskGoStraightToCoord, TaskEnterVehicle, TaskCombatPed…), but richer AI — scenarios, driving styles, relationship groups — is set by the owning client. A common pattern is to create the ped on the server and let the client drive its behaviour.
Cleanup
- Track what each resource created and
DeleteEntityit inonResourceStop. - Despawn player vehicles when they are stored or the owner has been gone for a while.
- Use
SetEntityOrphanMode(entity, 2)only for entities you clean up yourself.
local spawned = {}
-- after creating: spawned[#spawned + 1] = veh
AddEventHandler('onResourceStop', function(res)
if res ~= GetCurrentResourceName() then return end
for _, e in ipairs(spawned) do
if DoesEntityExist(e) then DeleteEntity(e) end
end
end)Entity lockdown and routing buckets
| `sv_entityLockdown` | Meaning |
|---|---|
inactive | Clients can create any entity |
relaxed | Entities created by client scripts are blocked |
strict | No entities can be created by clients at all |
The same modes can be set per routing bucket with SetRoutingBucketEntityLockdownMode, and SetEntityRoutingBucket moves an entity into a bucket (an instance). Server-side spawning is the precondition for both.
Frequently asked questions
How do I spawn a vehicle on the server in FiveM?
Use CreateVehicleServerSetter(model, 'automobile', x, y, z, heading), wait for DoesEntityExist, then send its network ID to the client if needed.
What is the difference between CreateVehicle and CreateVehicleServerSetter?
Server CreateVehicle relies on an entity creation RPC; CreateVehicleServerSetter creates it with server setter logic and is documented as the more reliable option.
Do I need RequestModel on the server?
No. RequestModel is a client native. The model hash must still be valid and streamed.
Why does my server-spawned ped not move?
It has no tasks yet. Use one of the server task natives such as TaskGoStraightToCoord, or let the owning client give it its behaviour.
Need this built, not just explained?
Ten years of FiveM work, from Lua to NUI
Custom resources, React NUI, ESX / QBCore / Qbox integration, OneSync performance audits and security reviews — plus the websites and SEO around your server brand.
Related guides
- EngineeringEntity ownership, handles and network IDs in FiveMEntity handles are local to each client and to the server; never send them over events. Convert to a network ID with NetworkGetNetworkIdFromEntity, send the ID, and convert back with NetworkGetEntityFromNetworkId (or NetToVeh/NetToPed/NetToObj on the client). Each networked entity has an owner that simulates it; other clients must request control before changing it, and ownership migrates when the owner leaves.
- EngineeringProtecting a FiveM server against cheatersBuild in layers: make the server the authority for money, items and entities; validate every net event; enable sv_entityLockdown once scripts spawn server-side; filter dangerous game events (explosionEvent, weaponDamageEvent, clearPedTasksEvent) on the server; ban on several identifiers plus GetPlayerToken tokens; add honeypot events; and log everything. A commercial anticheat adds client-side detection on top — it does not replace the rest.
- EngineeringState bags in FiveM: synced data without eventsA state bag is a set of key–value pairs attached to something: GlobalState (the whole server), Player(source).state (a player) or Entity(entity).state (an entity; also LocalPlayer.state on the client). Set a value on the server and it replicates to clients that can see it; clients react with AddStateBagChangeHandler. Clients can only write their own values when the server allows it, and those writes must never be trusted.
- EngineeringWriting server events that cannot be abusedAny client can call any event you registered with RegisterNetEvent, with any arguments. In each handler: copy source into a local, check argument types and ranges, re-derive everything from server state (prices, amounts, rewards), verify the player can do this now (distance, job, item, cooldown), and log refusals. Events only other server scripts should use are registered with AddEventHandler alone, so clients cannot trigger them.