Onesync - Control faraway peds?

Hey there,

as noted in the FiveM-cookbook entities can be owned by the server in OneSync if “no player is having the entity in scope” (A quick note about OneSync server-side persistence – FiveM Cookbook). Thus I was wondering whether it is possible to give tasks to the server-owned entities (e.g. TaskVehicleDriveWander() ). If yes, how would that be possible?
Whenever I tried the spawned peds would sometimes do things when I was alone on the server. As soon as multiple people spawned the success-rate was very close to 0%.

Best,
Sebastian

1 Like

Until there’s RPC native support for routing tasks, a way to do this fairly simply would be to poll using state bags.

A naive approach could look as follows:

-- server
local thePed = CreatePed(...)
Entity(thePed).state.task = 1
-- client
for _, ped in ipairs(GetGamePool('CPed')) do
    if NetworkHasControlOfEntity(ped) then
        local task = Entity(ped).state.task

        if task == 1 then
            if GetScriptTaskStatus(ped, 0xbba3b7ca) == 7 then -- see GetScriptTaskStatus docs for the hashes
                TaskWanderStandard(ped, ...) -- ... as in the usual args for TASK_WANDER_STANDARD
            end
        end
    end
end
3 Likes

Thanks for the quick answer! So the entity shows up however I can’t control it at all. Setting Entity(thePed).state.task = 1 results in an error InvokeNative: execution failed: Tried to access invalid entity: [serverside(?) entityID]. Trying to manually send the client the ped (as in sending thePed to the client) doesn’t work either as that entity doesn’t exist on the clientside. thePed also isn’t a NetID, I tried that one.
I also can’t execute the NetworkGetNetworkIdFromEntity()-native for thePed on the serverside, the error is invalid entity as well.

Edit: Should note that I’m coming back to this fairly quickly but I’m at a loss regarding state bags. First time I hear from them, have found one tutorial (OneSync / SERVER/CLIENT-SIDE Data Sharing) but apart from the tutorial doing this for players I don’t know what the issue could be.

my serverside code (what I’ve tried so far is noted as comments):

GlobalState.mode = 'open' -- doesn't matter if I got that one or not

CreateThread(function()
  local modelhash = GetHashKey('a_f_m_beach_01')

  local thePed = CreatePed(26, modelhash , 414.96, -979.43, 29.45, 92.67, true, true)
  -- tried changing both booleans (all four possible combinations of true and false)

  Wait(2000)

  TriggerClientEvent('RecievePed', -1, thePed) -- when I got the error for 

  --Entity(thePed).state.task = 1
end)

and my clientside-code

PedList = {}

CreateThread(function()
  -- the 'state'-part has vanished from this list because I'd manually sync the relevant entites
  while true do
    for _, ped in ipairs(PedList) do
      if NetworkHasControlOfEntity(ped) then
        if GetScriptTaskStatus(ped, 0xbba3b7ca) == 7 then
          TaskWanderStandard(ped, 10.0, 10)
        end
      end
    end
    Wait(5000)
  end
end)

RegisterNetEvent('RecievePed')
AddEventHandler('RecievePed', function(thePed)
  -- currently active version
  table.insert(PedList, thePed)

  -- this doesn't work either as thePed isn't a network ID
  -- local ped = NetToPed(thePed)
  -- table.insert(PedList, ped)

end)

I’m wondering though, would NetworkHasControlOfEntity ever return true for any client if the ped is far away from everyone? Say every single player is in Los Santos and an entity was spawned in Paleto Bay. I’d still like for the entity in Paleto Bay to move.

That’s your error, thePed server-side has a different ‘local’ id with clients. You should NetworkGetNetworkIdFromEntity to get the entity NetId, then client-side you just NetworkGetEntityFromNetworkId to get the entity local id.


You should set both to true, they mean isNetwork and isMissionEntity, so you need them to share the ped with everyone.

Sadly said native also gives me the invalid entity-error on the serverside, so I already tried NetworkGetNetworkIdFromEntity(thePed).
I just retried and the code already fails on the serverside. Interestingly enough when no players are on the server CreatePed() returns ID 0 (indicating that the ped never was created / was deleted instantly) and NetworkGetNetworkIdFromEntity() returns 0 as well.

As for the CreatePed-bools, yeah setting both to true is what I do most of the time. I tried this thinking maybe my error lies here.

Try having only the first one be true. Also until server-side sync trees are done (though I’m not sure why there isn’t one for CPed yet?) it might be needed to loop DoesEntityExist/GetNetworkId ~= 0 for a RPC-created entity.

Looping not DoesEntityExist did the trick regarding spawning! So I was not using Entity.state.task but that should work just fine as I uncommented that line and it worked just fine.

Sadly the game only seems to be able to spawn peds while a player is near that location, also the peds will stop moving when said player gets far away (presumably this will happen only when every player gets far away from the ped; I’m testing alone currently). They won’t resume their task once a player gets near.

As far as I know this would be intentional design by Rockstar Games (FiveM without OneSync behaves like this, I tried that back in April: Getting far-away peds to act?). There are certain exceptions, e.g. the latest CayoPerico Heist where you see guards moving around their towers even when you are way further than 200 m (approx. player scope) away. However these exceptions are very clear and could easily be hardcoded so I am not sure whether these are helpful.

EDIT: Just remembered that you mentioned RPC tasks. Would that be what will allow faraway entities to execute tasks?


If anyone has the same problem as I do:
It took approximately 350 ms from the execution of CreatePed() to the end of the while-loop (that would be seven prints of Waiting. I didn’t test it multiple times as the behavior is clear. After that the entity is callable from the server.

local modelhash = GetHashKey('a_f_m_beach_01')

local thePed = CreatePed(26, modelhash , 414.96, -979.43, 29.45, 92.67, true, true)

while not DoesEntityExist(thePed) do
  print('Waiting')
  Wait(50)
end  

local PedNetId = NetworkGetNetworkIdFromEntity(thePed)
Entity(thePed).state.task = 1

Correct, for now. However, what are you trying to do with a ped without any ‘real’ game representation?

I’ll investigate adding pedestrian sync tree creation to the server later this week, anyway, which should behave a bit more like you’d hope for server-side creation. This currently is only done for vehicles (using the undocumented CREATE_AUTOMOBILE test native) but that’s not finalised mainly as it’s impossible to know what type a vehicle is without storing game data on the server. Peds don’t have this limitation so it might be easier to do so for those and objects.

I also think task RPC should be fairly simple actually, so will add this to the same todo entry as well.

Basically a search-game where a ped will drive over a mentioned highway in a certain direction (e.g. Senora Freeway towards Paleto Bay) and the players will need to find the ped before it reaches the city.

The context would be a police multiplayer, where the ped is fleeing after a carjacking and the players need to stop the ped.

I was thinking about how to fake the mentioned behavior. But the only method that imo would feel right is simulating the peds’ movement over the highway. Now that would be possible but if I want to randomize the location that will outright mean simulating the entire map.

Tbf that’s what I would be doing in the next month… thank you very much for the support and pushing todos! Would you say that it could be worth for me to do really start coding on this or will OneSync make any of my tries obsolete in the near future?

Somewhat, yeah, until a player is actually nearby and it’ll turn into a physical ped.

That’s a curious use case, definitely, however, and currently I don’t think the RPC SET_ENTITY_COORDS is suited for that: it’ll likely need real node-based write overrides to do so. :slight_smile:

It’s good to see people finally try to write server-side logic, so we finally know what use cases people have and what to enhance. It’s been a bit hard to get a conclusive set of useful functions without anyone making use of the existing functionality!

Path node formats are generally documented, I believe.

1 Like

I actually made some research into Rockstars pathnode-system as well as FiveM pathnode natives a while ago. Now I only can do some lua-coding but I couldn’t access the necessary information with the natives. Also for faraway-simulation Rockstars nodes (> 70.000) are way excessive as they also contain information for the number of lanes etc which can be disregarded entirely for faraway-simulation. So cutting the number down atleast by a factor 10 could be a good goal.

Judging by your post I think I’ll go forward and actually write the necessary logic to get peds to move on the serverside. Thank you so much for your help!

I don’t know whether I should have put it that boldly…
But let me follow up on the comment. This youtube video shows the current progress. Synced spawning and despawning of entities as well as recreation of the TaskGoStraightToCoord() native on the serverside. I do believe that the code is structured well enough to allow for other necessary features to be added, e.g. syncing ped clothing, health or other task natives. So I think this is a promising start. Opinions on this? :slight_smile:

4 Likes