netplayjs icon indicating copy to clipboard operation
netplayjs copied to clipboard

One sided rollbacks

Open EikaMikiku opened this issue 2 years ago • 2 comments

Any ideas why one-sided rollbacks could occur? I made a small testing game and tried it with a friend, I could see his actions jaggy, but on his end it was smooth. This also happened when he was hosting. I was still seeing lots of rollbacks, but it was smooth on his end.

I'm the blue box in the below vids.

This is my POV: https://user-images.githubusercontent.com/8401769/147406805-a8b15b0e-137a-4dc5-af68-0c099426c7a2.mp4

This is his: https://user-images.githubusercontent.com/8401769/147406872-82831a48-8843-425e-a286-c8a7db1d2f1b.mp4

In my POV the yellow box (my friend) has a jaggy movement, due to lots of rollbacks i assume. In his POV, my box (blue) has smooth movement.

I've noticed that the history size on my friends POV is 1-3, but on my end it was 5-7. Not sure if this has anything to do with it. How would one go about fixing this?

EikaMikiku avatar Dec 26 '21 12:12 EikaMikiku

This is a problem that I'm aware of. The main stat to notice is the number of predicted frames - one player is predicting more frames than the other, resulting in more artifacts from their POV.

Rollback netcode works best when both players are ticking forward on exactly the same clock. For example, if players A and B are both on frame 5, they will send their inputs for that frame at exactly the same time, which, due to network latency, will arrive at some point in the future, say when they are both on frame 7. This will then trigger the rollback on both sides.

The problem here occurs when one player starts ticking slower and falls behind. This can happen for many reasons and is common in the browser. The player that has fallen behind receives the other player's inputs much earlier than intended. For example, if A is on frame 5 and B is on frame 6, B has already simulated frame 5 and sent his input. That input is already in transit, so A isn't waiting the entire transmission delay.

On the other side, the fast ticking player is getting inputs much later than they should. B is on frame 6 but A hasn't even reached there. So there is additional delay on top of network latency for B to get A's input for frame 6.

The result is that the fast-ticking player will predict more frames, and the slow ticking player will predict fewer frames.

You can see this happening in Street Fighter V: https://www.youtube.com/watch?v=HQAZ8xmXVLU

There is actually already some code to deal with this. If one player falls so far behind that they are actually receiving inputs before they get to a frame, they will start to tick faster. Without this, the problem would be much worse and potentially even be unbounded. This is reported in the stats as "Largest Future Size."

Dealing with this problem will require additional messages as well as a little bit of experimentation. Both sides need to inform each other of their predicted frame count. Then, each side can tick slower or faster to balance the number of predicted frames to be roughly equal.

rameshvarun avatar Apr 06 '23 11:04 rameshvarun

Hmm, I understand what you are saying. Because my PC is faster, My game is ahead in frames so this makes my game have less buffer time, so when inputs from P2 arrive, they cause large rollbacks.

What i don't get though is how "Largest Future Size" is being shown as 0 in both videos. Did you mean to say that it will eventually be reported in that stat, and it's not functioning as expected currently? I can see there is some code trying to speedup the ticks.

EikaMikiku avatar Jul 20 '23 08:07 EikaMikiku