Add Impulse - Network and FPS inconsistency

Im currently trying to solve this problem, Add Impulse is used in a server-only event to push player characters in a networked game when colliding with an object, but the amount of force applied to clients is seemingly different depending on the connected clients frame rate. (altho movement is not client authorative)
The same behaviour is replicated if running 2 simulated clients in editor with low frame rate (10-15fps), the difference between the force applied to the characters differs with around 50% from running with high frame rate (60-120fps).

The setup of the function is as basic as could be:

Any help is much appreciated. Perhaps there is a workaround that am not seeing?

Hey MADHOUSE,

I performed a quick search in our documentation for this, and came across a thread that I’d highly recommend taking a look at, as it contains a lot of useful information that I believe will be relevant to what you’re trying to accomplish:

Let me know if that helps.

Have a great day

Hi, thanks for your reply!

I have read through that thread a few times but not really been able to solve the problem. If I do delta * impulse then the effect is reversed, the lower the framerate, the stronger the impulse, but this is also not desirable since it scales way too much.
To my understanding Add Impulse is not supposed to be used with delta time, altho the actual physics effect on the movment component treats the impulse differently on different frame rates regardless. Turning on sub-stepping did not change this behaviour.

I do lack experience with physics in relation to delta time so there might be something im missing.

This comment from that thread is interesting:
“An impulse allows you to change velocity instantaneously. You can think of this as a force applied over some period of time. An example of this may be that an object is pushed on for exactly 0.5 seconds. In this case if you applied a force you would not get the correct result unless the frame rate happened to be exactly 0.5 seconds. So in this case you can calculate the impulse as 0.5s * (the force you’d apply) and PhysX will change the velocity accordingly.”
-[Epic]Ori Cohen

Does this refer to Add Force or Add Impulse? Any example of how it would be accomplished?

Thanks a lot for helping out!

I am currently testing out this workaround, and it has better results:

This function behaves better, but I’ll do some more testing soon.

If I have a listen server running at ~60fps this function seems to push the low fps client as much as the high fps client.

The Add Impulse function however does not, and only pushes the low fps client about 50% of the impulse applied to high fps clients.
Currently it seems like the workaround function pushes the clients seemingly equally, but if the server is lagging heavily, 10% or so from the impulse is lost.

Hey MADHOUSE,

What were the results of your additional tests?

If you’re still believing that this is a bug after your additional testing, would you mind providing a repro case so that I could take a look into it on my end?

Greetings. I find the workaround to function better and is less prone to lag-hacking, even if not perfect…
Add Impulse does not act as I would expect when executed on the server only, players with different latency would recive different amounts of impulse:

Add Impulse also seems more heavily affected by the clients frame rate, related to the clients update rate perhaps? Not sure how one would account for that in this case, since it would be an issue independent of the host fps/delta.

To replicate the issue have a function from the host pawn (server side) that pushes all pawns in a direction with an add impulse. Lag down the framerate of one of the connected clients. Observe as the host and non-lagging clients are moved further than the lagging client.

Latency lag as shown in the picture also affects it, but not as bad. The picture is from an experiment with simulated latency, the fps issues where observed in live multiplayer sessions, and should be tested there, could possibly be simulated with a cheat engine or similar to lag down one of the client instances.

If some of these issues would possibly be by design, what is the appropriate approach to this issue?
/Best Regards

Sorry for the delay.

Could you do me a favor and provide your test project so I can take a closer look at your setup and determine if there could be some sort of bug interfering with the performance?

If you want to keep the project private you can PM me a link to dropbox or google drive so I can take a closer look: https://forums.unrealengine.com/member.php?160394-Sean-Flint

Greetings. Ive uploaded the sample project here: link text

Instructions:

  1. Open project

  2. Play in editor with 3 simulated players

  3. Add net pktlag to one of the clients

( Controls are shown on screen)

If this test was run on 3 separate computers it would also be possible to observe the lag-hacking behaviour when one client has lower fps.
(at which point using the 2 different add velocity modes could be compared)

Best Regards

Btw the sample project is from source build 4.14.1

Hey MADHOUSE,

After further investigation and discussion, we do not believe that this is a bug. Physics Simulation, although this may sound silly, is just a simulation. This means that it will not be perfectly replicated on the clients, which would explain the differences you’re seeing, especially when there is lag involved. Replicating physics perfectly is a tricky task that will require some additional work likely using a custom pawn.

I’d recommend taking a look at this thread for a bit more information as far as a starting point if this is something that you’re looking to do:

[Video] Player-Controlled Replicating Physics Movement, Simulating Physics! - C++ Programming - Unreal Engine Forums!

If you have any further questions, feel free to let me know.

Hi, thanks for your reply!
Indeed physics simulation is just a simulation, I was somewhat assuming that the simulation being run on the server should be somewhat consistent on all spawned pawns (server side).

Am I correct to assume then that the interpolation of client data etc is interfering with the physics simulation/pawn movement even when executed on the server? Thanks for the link, it seems to be going through a lot of these issues, personally however rewriting a custom pawn/character class from scratch will probably not be realistic at this point.

Thanks for helping out with investigating this issue.
/Best Regards

as of 4.19 I discovered the following:
All character movement is calculated within a PerformMovement method. This method, for reasons unknown to me, ticks at a different rate on clients than it does on servers/localhost.

I experimented with this by running AddForce in a Character’s Tick method and observing that a localhost moved slow and a remote client moved fast.

I moved the AddForce into an overridden PerformMovement method, and all clients/localhosts moved at the same speed.

My solution was to do something like … replicate the desired push forces into the Character without actually applying them, and then consume the values from PerformMovement. Care has to be taken not to apply a force twice, because other Actor Ticks to apply forces might be occurring at a different rate than PerformMovement is being Ticked. (Would love it if anyone knew why the CharacterMovementComponent ticks at a different rate on clients - I’m actually a newbie myself)

This is indeed silly, I’m being constantly surprised how things behave differently on server and local client. Maybe there should be documentation section dedicated just for those differences?