Vehicle IDs changing randomly / Non-unique NetworkID

If you create a few cars through CreateVehicle in session with other players, it’s possible that vehicle will change it’s ID and loose blip added to it. And NetworkGetEntityFromNetworkId will return zero for saved NetworkID.

I’m creating vehicle with CreateVehicle, adding blip using AddBlipForEntity and getting vehicle NetworkID using NetworkGetNetworkIdFromEntity. I don’t call SetVehicleAsNoLongerNeeded right after that because I don’t want it to despawn randomly.

Right after that NetworkGetEntityFromNetworkId and NetworkGetNetworkIdFromEntity are working correctly and return VehicleID from NetworkID and vice versa accordingly. But then at random moment (when other player is getting closer to my vehicle than me, I guess) it change it’s VehicleID to random one. Both NetworkGetEntityFromNetworkId and NetworkGetNetworkIdFromEntity ruturn zero for old IDs. But if I get in that vehicle to see it’s current VehicleID and call NetworkGetNetworkIdFromEntity it will return old NetworkID. Witch is most likely a bug because NetworkGetEntityFromNetworkId still return zero for given NetworkID. Also I can see two vehicles with same NetworkID. Something is wrong with it. Maybe I broke Rockstar networking by creating next vehicle without calling SetVehicleAsNoLongerNeeded for previous one and I must prevent vehicles from despawning by other means. But I also want to identify vehicles and NetworkID natives are not suitable for it for some reason. I’m almost sure that I got those problems because NetworkID is unique for one player instead of entire session.

Maybe I should use RESERVE_NETWORK_MISSION_VEHICLES or _NETWORK_SET_NETWORK_ID_DYNAMIC or SET_NETWORK_ID_CAN_MIGRATE or NETWORK_REGISTER_ENTITY_AS_NETWORKED or something. But it looked fine when I was alone in session, vehicles spawned with CreateVehicle are getting NetworkIDs automatically for some reason. Maybe they shouldn’t then?

Screenshot of debug output: https://steamuserimages-a.akamaihd.net/ugc/856100508769152201/05326D507381C5D7696030210D312887C951B7A5/

Code for debug output:

Citizen.CreateThread(function()
    while true do
        Citizen.Wait(1000)
        if debug_mode then
            local test="debug:m="
            if mycar then
             test=test..mycar
            else
             test=test.."nil"
            end
            test=test.." o="
            if mycar_old then
             test=test..mycar_old
            else
             test=test.."nil"
            end
            test=test.." r="
            if rentcar then
             test=test..rentcar
            else
             test=test.."nil"
            end
            if IsPedInAnyVehicle(GetPlayerPed(-1), false) then
             test=test.." "..GetVehiclePedIsUsing(GetPlayerPed(-1))
            end
            SetNotificationTextEntry("STRING");
            AddTextComponentString(test)
            DrawNotification(false, false);
            Citizen.Wait(1000)
            test="ent2n:m="
            if mycar then
             test=test..NetworkGetNetworkIdFromEntity(mycar)
            else
             test=test.."nil"
            end
            test=test.." o="
            if mycar_old then
             test=test..NetworkGetNetworkIdFromEntity(mycar_old)
            else
             test=test.."nil"
            end
            test=test.." r="
            if rentcar then
             test=test..NetworkGetNetworkIdFromEntity(rentcar)
            else
             test=test.."nil"
            end
            if IsPedInAnyVehicle(GetPlayerPed(-1), false) then
             test=test.." "..NetworkGetNetworkIdFromEntity(GetVehiclePedIsUsing(GetPlayerPed(-1)))
            end
            SetNotificationTextEntry("STRING");
            AddTextComponentString(test)
            DrawNotification(false, false)
            Citizen.Wait(1000)
            test="net2e:m="
            if net_mycar then
             test=test..NetworkGetEntityFromNetworkId(net_mycar)
            else
             test=test.."nil"
            end
            test=test.." o="
            if net_mycar_old then
             test=test..NetworkGetEntityFromNetworkId(net_mycar_old)
            else
             test=test.."nil"
            end
            test=test.." r="
            if net_rentcar then
             test=test..NetworkGetEntityFromNetworkId(net_rentcar)
            else
             test=test.."nil"
            end
            SetNotificationTextEntry("STRING");
            AddTextComponentString(test)
            DrawNotification(false, false);
            Citizen.Wait(1000)
            test="netdb:m="
            if net_mycar then
             test=test..net_mycar
            else
             test=test.."nil"
            end
            test=test.." o="
            if net_mycar_old then
             test=test..net_mycar_old
            else
             test=test.."nil"
            end
            test=test.." r="
            if net_rentcar then
             test=test..net_rentcar
            else
             test=test.."nil"
            end
            SetNotificationTextEntry("STRING");
            AddTextComponentString(test)
            DrawNotification(false, false);
        end
    end
end)

Workaroud I tried to use:

local function trytofixvehid(veh,net)
    if veh~=nil and net~=nil and net~=0 then
        local vehnew=NetworkGetEntityFromNetworkId(net)
        if veh~=vehnew then
            if vehnew~=nil and vehnew~=0 then
                addcarblip(vehnew)
                return vehnew
            elseif IsPedInAnyVehicle(GetPlayerPed(-1),false) then
                vehnew=GetVehiclePedIsUsing(GetPlayerPed(-1))
                local netnew=NetworkGetNetworkIdFromEntity(vehnew)
                if netnew==net then
                    addcarblip(vehnew)
                    return vehnew
                end
            end
        end
    end
    return veh
end

Calling it in cycle like this:

            mycar=trytofixvehid(mycar,net_mycar)
            mycar_old=trytofixvehid(mycar_old,net_mycar_old)
            rentcar=trytofixvehid(rentcar,net_rentcar)

Maybe SET_ENTITY_AS_MISSION_ENTITY will solve my particular problem but I feel that something is not ok with NetworkIDs. Sorry for that.

take a look at this native and tell me if they work for you :wink:

SET_NETWORK_ID_EXISTS_ON_ALL_MACHINES(int netId, BOOL toggle);
_NETWORK_SET_NETWORK_ID_DYNAMIC(int netID, BOOL toggle);

Maybe I should call NETWORK_DOES_NETWORK_ID_EXIST in loop for NetIDs from 1 to 255 to force game to check if some of them are already in use? Or simply RESERVE_NETWORK_MISSION_VEHICLES because game is not doing it automatically beforehand. And use NETWORK_DOES_ENTITY_EXIST_WITH_NETWORK_ID to check when entity is lost.

What SET_NETWORK_VEHICLE_RESPOT_TIMER is for?

Use SET_NETWORK_ID_EXISTS_ON_ALL_MACHINES and the 05cfa83c-a124-4cfa-a768-c24a5811d8f9 manifest version for your resource.

See:

    if input == 'a' then
        local model = "t20"
        RequestModel(model)
        while not HasModelLoaded(model) do
            Citizen.Wait(0)
        end
        local c = GetEntityCoords(PlayerPedId())
        local vehicle = CreateVehicle(model, c, 0.0, true, false)
        SetModelAsNoLongerNeeded(model)
        SetVehicleOnGroundProperly(vehicle)

        local netID = NetworkGetNetworkIdFromEntity(vehicle)
        SetNetworkIdExistsOnAllMachines(netID, true)
    elseif input == 'b' then
        local ped = GetPlayerPed(-1)
        if IsPedInAnyVehicle(ped, false) then
            local vehicle = GetVehiclePedIsIn(GetPlayerPed(-1), true)
            local netID = NetworkGetNetworkIdFromEntity(vehicle)
            local entityFromNetID = NetworkGetEntityFromNetworkId(netID)
            Citizen.Trace(vehicle .. " | " .. netID .. " | " .. entityFromNetID .. "\n")
        end
    end
3 Likes

I’m trying to make random car or ped persistent to make it mission target for stealing or assassination.

local function NetworkUnregisterNetworkedEntity(entity)
    return Citizen.InvokeNative(0x7368E683BB9038D6,entity)
end

local function NetworkRegisterEntityAsNetworked(entity)
    return Citizen.InvokeNative(0x06FAACD625D80CAA,entity)
end

local function _NetworkSetNetworkIdDynamic(netID,toggle)
    return Citizen.InvokeNative(0x2B1813ABA29016C5,netID,toggle)
end

local function networkingshit(veh)
    SetEntityAsMissionEntity(veh,true,true)
    local netID=NetworkGetNetworkIdFromEntity(veh)
    if netID==0 then
        NetworkRegisterEntityAsNetworked(veh)
        Wait(0)
        netID=NetworkGetNetworkIdFromEntity(veh)
    end
    SetNetworkIdExistsOnAllMachines(netID, true)
    _NetworkSetNetworkIdDynamic(netID,true)
    Wait(0)
    netID=NetworkGetNetworkIdFromEntity(veh)
    return netID
end
Guess what it does.

Nothing. NetworkID is still 0 and it will despawn whenever it want to. No errors.

Why the InvokeNative calls? Did you even test with the manifest version as posted above?

Also, there should be a total of no reason to use InvokeNative manually, except for DLC natives, which these are not.

Because NetworkUnregisterNetworkedEntity, NetworkRegisterEntityAsNetworked and _NetworkSetNetworkIdDynamic are not defined anywhere.

Are you even using any resource manifest version at all? These would be defined if only you’d use the latest one mentioned on the wiki, or the one mentioned above that you need for network IDs

Just in case you’re unable to read, this manifest version is 05cfa83c-a124-4cfa-a768-c24a5811d8f9.

1 Like

You are right. Found all three of them in natives_0193d0af.lua but they were defined exactly the same way I did. This is my __resource.lua

resource_manifest_version '05cfa83c-a124-4cfa-a768-c24a5811d8f9'

description 'fragile'

client_script "client.lua"
server_script "server.lua"

ui_page 'ui.html'

-- NUI Files
files {
	'ui.html',
	'pdown.ttf'
}

Didn’t see any difference after adding resource_manifest_version so didn’t mention it.

How about if you spawn your vehicle with true,true instead of true,false, so it is owned by the script handler?

Also, if reconnecting to the server after disconnecting there might be an issue with network IDs, so test with a first join too.

// 0xAF35D0D2583051B0 0xDD75460A
Vehicle CREATE_VEHICLE(Hash modelHash, float x, float y, float z, float heading, BOOL isNetwork, BOOL p6);
p6 - last parameter does not mean vehicle handle is returned
maybe a quick view in disassembly will tell us what is actually does


p6 seems to check for something with the script in the disassembly

https://runtime.fivem.net/doc/reference.html#_0x5DD35C8D074E57AE
How could I know that? Same for last parameters of CreatePed and CreatePedInsideVehicle I guess? Is there any way to create entity without losing any track of it in the next monent? Everything is working perfectly when I’m alone, but two players are enough to break everything and both entityID and networkID means nothing since then. I can’t even delete that entity. For some reason planes are almost perfectly persistent by default but cars and peds are very easy to lose.

Can someone make a simple script that will create one vehicle and one ped near each player when they spawn first time and make it so that that ped and that car will have known entityID OR networkID and at least one of two IDs will not change to random number when player walk away for a second?

Wait… Is it so that only one player can have persistent networkIDs - current arbitrator aka host?

Since you just posted that things mess up when another player joins, I wonder if you are encountering the same thing as me.

I was tempted to make this post here, but the upshot is that in my testing with this resource manifest, it is only the script host (according to NetworkGetHostOfThisScript) who can reliably get netIDs. And only after setting the entity as a mission entity. This is for existing npc vehicles however so there is a significant difference.

1 Like

Now they just disappear instantly instead of changing their IDs.

Do I need to determine host and send events to them instead of spawning entities myself? Are GET_HOST_ID and NETWORK_IS_HOST working? If host will spawn entity and send its networkID to other client, how that client will get entityID back from it? I’m almost sure that NetworkGetEntityFromNetworkId will not work and writing it is waste of time. Instead I should place ALL logic on host and only send coordinates and text messages to other clients. Right?

I think I got it.
false,false - for something local, not important at all, mostly decorative things.
true,false - semi-synchronized, IDs may change, good for followers, personal vehicles and small(personal) missions, spawned and contolled by player who started that mission.
true,true - most important entities for session-wide missions, should be spawned and controlled by host.
Right?

Entities spawned with true,false may be found again by scanning for mission entities with certain attributes, using IS_ENTITY_A_MISSION_ENTITY, GET_ENTITY_MODEL, GET_VEHICLE_NUMBER_PLATE_TEXT and such.

But how RESERVE_NETWORK_MISSION_OBJECTS works? What if I call RESERVE_NETWORK_MISSION_PEDS(100) and RESERVE_NETWORK_MISSION_VEHICLES(100) from each of 32 clients? Will it reserve 6400 netIDs total or just 200?

1 Like

Presumably only the script host.

IV had a simpler system for this, a future update might revert to working like this again (network IDs that should be more reliable, and not merely an index into a script handler).

4 Likes

So I need to reserve netIDs for everyone at startup? 32*5 to reserve netIDs for 5 vehicles for each player for example?

1 Like

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.