Client prediction misbehaving at the end of a jump

Hi,

I’m working on a character controller and I’m having issues in certain jumping scenarios.
In the images below the green plot is the client position and the blue plot is the server position.
When there is a high ping, the client has a strange behavior at the end of the jump.
What seems to happen is that on the client when the player reach the ground level, all position,velocity and acceleration (vertical ones) are set properly by the end of the simulation step. but at the beginning of the next one, they have changed. I have no other systems writing to this data.

2024-11-0413-38-10-ezgif.com-video-to-gif-converter

The higher the ping the weirder the client path is.

I’m not sure what’s happening here…

My entity is set to be owner predicted

Everything is synced over the network by my own component

And finally, the issue is only there if the vertical velocity at the time of reaching the ground level is high enough. with a basic symmetrical jump it does not occur :

Yeah this is the kind of problem that’s hard to solve without tracing tools. At first glance, I see your quantization is pretty high, that might create discrepancy between client/server (see this page)

To test, you can remove quantization temporarily and see if that removes the issue.

If that doesn’t, you could log your position before/after multiple systems (GhostUpdateSystem is the one updating your client position that’s coming from the network) and try to identify which system is introducing that big jump.

Thanks I’ve already try to remove quantization and it doesn’t change the issue. I’ll try to log the data at different point in the loop to see where that comes from.

Is your issue consistently happening at the same time or is it random? If random, tick batching might be a culprit there too.
I’m also noticing your green and blue lines diverge even at the top of your first gif, not just when landing. Might be worth checking.

This is a trace of the position, velocity and acceleration Before the GhostUpdateSystem, After the GhostUpdateSystem and finally the State after the controller update

It looks like the client is receiving a snapshot of the server and when it repredicts the movement is uses the velocity before the jump top so it does not repredict it correctly.

weird thing is as long as I keep the jump button pressed, the simulation is flawless.
But if I stop pressing the space bar in the jump, then there is a bounce at the end on the client side _O_/

it is not always happening with the same intensity.
most of the time the top of the jump is perfect but the bounce is varying in size.

I think I can safely eliminate the step batching hypothesis.

With the following config on both the client and server I still get the issue.

Hi! Did you solve the issue? Would be great if you could show some code as well! How you process input to logic, all the relevant components, where you update your systems etc.

Hello, no the issue is not solved.
If you are brave enough you can have a look at my streams vod on youtube, you should be able to see the whole code. I don’t have a git repo for it.
And I’m focused on another feature for this project.
I’ll get back to it later

1 Like