PiTyUs.Hire me

Engineering

Entity ownership, handles and network IDs in FiveM

How networked entities work in FiveM with OneSync: entity owners, why local handles differ between client and server, network IDs and how to convert them, requesting control, ownership migration, orphan mode, and the bugs that come from sending handles over events.

Updated 12 min readBy PiTyUs · FiveM developer

Overview

Most “it works for me but not for other players” bugs in FiveM come from one misunderstanding: an entity handle is a local number. The vehicle that is handle 131842 on your client is a different number on the server and on every other client. The shared name for an entity is its network ID, and every networked entity also has an owner — the one client that simulates it.

Handles vs network IDs

HandleNetwork ID
What it isA local reference in one script runtimeThe entity’s ID across the whole session
Same on every machine?NoYes
Send in events?NeverYes
Get itCreateVehicle, GetVehiclePedIsInNetworkGetNetworkIdFromEntity(entity)
client.lua — send the vehicle you are in to the serverlua
local veh = GetVehiclePedIsIn(PlayerPedId(), false)
if veh ~= 0 then
    TriggerServerEvent('garage:store', VehToNet(veh))
end
server.lua — turn the network ID back into an entitylua
RegisterNetEvent('garage:store', function(netId)
    local src = source
    if type(netId) ~= 'number' then return end

    local veh = NetworkGetEntityFromNetworkId(netId)
    if not DoesEntityExist(veh) then return end

    local ped = GetPlayerPed(src)
    if GetVehiclePedIsIn(ped, false) ~= veh then return end -- validate!

    DeleteEntity(veh)
end)

Converting on the client

DirectionNatives
Entity → network IDNetworkGetNetworkIdFromEntity, VehToNet, PedToNet, ObjToNet
Network ID → entityNetworkGetEntityFromNetworkId, NetToVeh, NetToPed, NetToObj
Does it exist here?NetworkDoesEntityExistWithNetworkId(netId)

A client only knows entities near it. If the server sends a network ID for a vehicle across the map, the client cannot resolve it until it is in range — wait with NetworkDoesEntityExistWithNetworkId before converting.

client.lua — wait until the entity exists locallylua
local function waitForNet(netId, timeout)
    local deadline = GetGameTimer() + (timeout or 5000)
    while not NetworkDoesEntityExistWithNetworkId(netId) do
        if GetGameTimer() > deadline then return nil end
        Wait(0)
    end
    return NetworkGetEntityFromNetworkId(netId)
end

Owners and control

With OneSync every networked entity has an owner client that runs its physics and sends its state. NetworkGetEntityOwner(entity) returns the owner — a server ID on the server, a player index on the client. Only the owner’s changes stick; when your client changes an entity it does not own, the owner overwrites it on the next update.

client.lua — take control before modifyinglua
local function requestControl(entity, timeout)
    local deadline = GetGameTimer() + (timeout or 2000)
    NetworkRequestControlOfEntity(entity)
    while not NetworkHasControlOfEntity(entity) do
        if GetGameTimer() > deadline then return false end
        Wait(0)
        NetworkRequestControlOfEntity(entity)
    end
    return true
end

if requestControl(veh) then
    SetVehicleFixed(veh)
end

Migration and orphan mode

When the owner leaves the area or disconnects, ownership migrates to another nearby client. If nobody is relevant any more, the server removes the entity by default. SetEntityOrphanMode(entity, mode) on the server changes that:

ModeNameBehaviour
0DeleteWhenNotRelevantDefault — deleted when no player is relevant
1DeleteOnOwnerDisconnectDeleted when the original owner disconnects
2KeepEntityNever deleted by the server’s relevancy cleanup
From the SET_ENTITY_ORPHAN_MODE documentation.

KeepEntity only stops the server deleting it; a client can still delete it. Use it for things that must survive, like a placed prop, and clean them up yourself.

Attaching data to an entity

Instead of keeping tables keyed by network ID, attach data to the entity itself with an entity state bag: Entity(veh).state:set('fuel', 62.0, true). It follows the entity everywhere. See state bags.

Frequently asked questions

Why does my entity handle not work on the server?

Handles are local to each runtime. Send the network ID (NetworkGetNetworkIdFromEntity) and convert it back on the other side.

What is an entity owner in FiveM?

The client that simulates a networked entity and sends its state. Other clients see the owner’s version.

Why do my changes to a vehicle get reverted?

You are not its owner. Request control first, or make the change with a server-side native.

Why does NetToVeh return 0?

The entity does not exist on that client yet — usually it is out of range. Wait for NetworkDoesEntityExistWithNetworkId.

How do I stop the server deleting my entity?

Call SetEntityOrphanMode(entity, 2) on the server, and delete it yourself when it is no longer needed.

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