Synchronizing AI position over network

Hello,

I’m currently using the RVO solution with a RecastGraph and I’m trying to efficiently handle position synchronization for AI.

Right now, I am using the same script for synchronizing both player and AI position.

I figure that since the server is aware of where the AI is headed, however, the most efficient solution would be to only synchronize the AI’s state (running/walking/stationary/etc) and the waypoint/player it is running toward. I can then simply pass that transform to the client for the AI to move toward.

Instead of sending the actual position of the AI 30 times a second, I will send position only a few times a second to perform position corrections on the client if the position difference between client and server surpasses the error threshold.

With the RVO solution and AIPath, which variable can I reference for synchronizing the point the AI is currently running toward?

Thanks! :slight_smile:

Not being a network expert, I think your solution is the way to go. Some kind of interpolation, either using current position and velocity to extrapolate or interpolate between two positions.

For AIPath, that depends on which type of underlaying controller you are using, CharacterController, Rigidbody etc. if you are using the RVOController, you can access the position and velocity properties of it.
`
RVOController c = GetComponent();
c.velocity;
c.position;

PS: Sorry for the delay, I have been away for some time

Hey Aaron,

Position and velocity with interp/extrapolation is how I do it now. The problem is that those values need to be updated often (10+ times a second). In the current state, if you had all players and AI near each other, that would mean you would have to send around 200kb/s per player, which is definitely not going to happen in a 64 player game. If it’s not updated often, the AI will run past its current point and error correction will look really bad. The way I’d like to do it is to find out what point the AI is running to, whether it be a point on the path, or if near the end of the path, the moving transform of the player. That way, the server only triggers a state sync when this point changes.

What I mean is I want to know what AIPath is actually doing. What variable stores the current point AIPath is telling the AI to run to?

The AIPath script itself interpolates the target point during each frame, so it’s not as simple as sending a target point for each player unfortunately.

Would it work for you to send the whole path and then have all clients simulate agent movement with corrections for deviations once every second or so?

Yes, that might work depending on how much data would need to be serialized for a path.

I’m guessing the majority of the work is to create a network version of the Seeker class to receive RPCs from the server for pathing. Corrections could be applied in the same way RVO applies force.

So it looks like I just need to modify Seeker on server to send an RPC to the modified Seeker script on the client. The RPC would contain just the vectorPath. Smoothing modifier would be applied on the client. When RVOController is about to apply direction/velocity “force” for local avoidance, I add any necessary “force” to correct position.

So I think I could use a few RPCs:

RPC sent by server’s Seeker script when vectorPath changes.
RPC sent when AI “state” changes. For example, if the maxspeed changes, AI changes state (alive/dead/hit/etc), AI stops pathing/moving from a server-side event, etc.
And periodic RPCs containing AI’s position on the server for force correction via RVOController. (Or if the correction is very large, teleport) Whenever an AI is actively pathing, these position correction updates can be sent every half second or so when a player is in scope (in range).

I think with this setup, I can get away with sending a third of the data or less. It will not be as accurate, but it doesn’t need to be, and this way can also look smoother. To prevent rampant client cheating (IE, client says AI is in very different position), I will just enforce a maxPositionError check on the server before attacks are applied. The maxPositionError will be equal to the maximum possible variance in server and client based on the AI’s max speed and the time between the correction RPCs.