gschup / ggrs

GGRS is a reimagination of GGPO, enabling P2P rollback networking in Rust. Rollback to the future!
Other
501 stars 25 forks source link

PredictionThreshold error drops requests missing correction #75

Open MaxCWhitehead opened 3 months ago

MaxCWhitehead commented 3 months ago

Describe the bug

When client receives input and flags a first_incorrect frame, adjust_gamestate pushes load + advance requests to perform rollback. it then calls self.sync_layer.reset_prediction() which resets tracked first_incorrect frame.

In advance_frame when applying local input, if PredictionThreshold error is returned, function exits with error and drops the requests for the correction. Due to first incorrect frame being reset, this correction is missed and causes desync.

I'm still reasoning about exactly where the issue is / what the solution is. I believe the example games are vulnerable to this bug too.

Additional Context

Here is example of logs on a client that missed the correction (3 client game. One client missed correction for player 1's input, the 2nd applied it correctly, now players 0 and 2 are desynced). (the frame listed in input log is predicted frame, in case that is confusing). Might be more confusing than helpful, but demonstrates that both clients were notified of player 1's input, ggrs pushed requests for corrections, but the one that hit prediction threshold did not rollback, causing desync.

Player 0's logs (Missed correction on player 1's input due to prediction threshold)

Player 2's logs (correction applied correctly on player 1's input):

To Reproduce

I can repro in jumpy pretty easily / can provide steps - but I will try to write a test to repro this for testing + preventing regression once figure out what to do here.

One thing that helps repro is having 4 clients open at once (with a relay server so not p2p locally), and having 200+ ping, lots of prediction threshold errors :) (Silly way to say that poor conditions definitely bring this to light, possibly high ping + lower prediction window might do it).

MaxCWhitehead commented 3 months ago

Haven't gotten to exploring what kind of fix might make the most sense, but I wrote a test that reproduces this.

I implemented a fake DebugSocket mechanism that allows the test implementation to control when messages are actually delivered between clients, to help reproducibly enter a state in which a correction happens at same time as prediction threshold error.

The simplest form I have found to repro this is with 3 clients.

Here's the test for reference: https://github.com/gschup/ggrs/compare/main...MaxCWhitehead:ggrs:prediction-error-rollback-test

Will look into how might fix / test against this.

gschup commented 1 month ago

Hi! thanks for posting this bug report. Sorry for not responding so far. I have just posted a PR that slightly alters the logic for handling inputs. I am not 100% sure this fixes this issue, but it might. Would you be able to test this again on the lockstep branch? -> #79

gschup commented 1 month ago

70 has additional information on this issue.