[Unsolved] Problem w. applying forces over the network (client is faster than server)


I already created a post for this problem over in the Content Creation section, but was advised to ask in this section as well. I will provide a brief description of the problem. You can find more in-depth details and figures over in the original post (ask if you need more info).
Original post in Content Creation section

I’ve created a simple car game where two or more people can drive around together (Thanks to Epic’s Blueprint Networking Tutorial).
However, for some odd reason the client’s car accelerates faster than the server’s. I’ve looked everywhere for a potential fix without any luck.

Video Example:

I’m dumbfounded and need some help from the community due to still being new at implementing networked-based frameworks. In the original post you will find relevant information regarding the event(s) that make the car accelerate on the server.

Based on what I’m seeing in your code (Tick based Acceleration)… I would presume that the client having a higher FPS (more ticks per second) is applying more acceleration per second. As a test you can cap your client FPS to match the servers tick rate.

I think that you have something (probably in your tick) that is not replicated right.
It’s “forced” on client side, but not on the server, so server Interpolating positions and you get frequent desynchronized vehicle movement.

If you try to forcibly synchronize the client and the server you will get results like in your video.
I think you need to change complete logic for your car movement (try to avoid tick as much as possible).

Hi Mr. Wood,

Thanks for your reply.
When you say that it’s “forced” on the client what do you mean exactly?

Because in the project it is set up such that the server is running the simulation.
The position, rotation and velocity is then sent via Unreal Engine’s default replication framework to all connected clients.
I can see how what you describe would be a problem in a deterministic physics replication system, but not how that would affect the system I have (which simply sends the transform data of an object).

If I misunderstood your post, please correct me.

Hi Rev0verDrive,

Thanks for your reply as well.
Originally, I had the very problem you are describing. For this reason, I have moved the Add Force at Location Local-node and the relevant calculations to a separate event called *Engine Functionality *which runs at every server tick (This is also explained in the original post). This should eliminate the need for the client to run at the same tick-rate as the server.

Only the acceleration input (-1, 1]) is sent to the server via the client now.

Well, based on blueprint from Original post in Content Creation section you provided, I think you already got answer:

The problem is in your tick where you “force” logic for clients and the server in every single frame (after Switch Has Authority). Basically, you can try the following:
If you need to put physics logic in tick, then do not separate code for the server and clients (eg. write it as normal event). You need to let engine do that. Even if the server and the client have the same tick-rate there will be interpolation and desync problems, specially if there are more clients.
So, when the client press “Accelerate” button you simply replicate variable and the same for turning. Or even better if you axis values are only -1, 0 and 1 you need only to replicate Pressed and Released buttons. Engine will do the rest.

So what I would do is simply have a variable called AccelerationInput that is then set to replicated, and then change that instead of using an event to change it on the server?

Also, I don’t quite understand what you mean by

Should I use a IsLocallyControlled-node in a normal event instead? Otherwise, I can’t see how it will work properly since the player acting as the server will have control of every car and thus remove control from all clients.

By the way, just so we are on the same page; the simulation on each client doesn’t really matter since it is being corrected by the server’s game state (I think?)

Apologies if I don’t understand this right away.

This is your blueprint

As you can see, you have different simulations for the server and for the client in tick. If the server fps is 60 (does not matter client fps), it will 60 times per second call this events on the client and on the server in the same time.
And that is the main problem why you have choppy gameplay, stutter and desync between the server and other clients.
So you have to change the logic for this. Let’s just consider acceleration only. The server only need to know when you press the accelerate button and when you release it, so you replicate only that value by calling an event from the client to server (and check Reliable). The server will act just as other player (and the server will always have advantage, so maybe it’s better to use dedicated server).
Of course you can use axis value for replication, but not in every frame (only when it changes). At least it’s better for optimization.
For instance, earlier I used this: rewrite it a bit for multiplayer and it works smooth with over 15 players and AIs (but client can not play as server in my case).

Okay. I will try to implement what you’ve described.

I’ll report back when I get some results.