I have client-side prediction working (based on various articles like Gabriel Gambetta and gafferongames) as follows:
Every tick, the client...
1) Receives and applies snapshots from the server (potentially skipping old ones)
2) Collects input
3) Applies input locally and simulates
4) Logs that input as well as the ship's resulting position with a client timestamp C
5) Sends input to the server with timestamp C
Every tick (same rate as client), the server...
1) Receives and input from clients (potentially skipping some if the client is moving too fast)
2) Applies input and updates the world
3) Sends out snapshots to clients (including C)
At the client's step (1), when it gets snapshot S, that snapshot contains C. So the client rolls back through its logs to find the input that it sent marked C (trashing anything older), and finds the corresponding local position P for when that input was sent to the server. If S and P are far enough away from each other, it's time to correct. The naive way to do this, which works fine, is to set P to S (i.e. replace the position I had stored in the past with the position I just got from the server, also in the past), and re-simulate forward through all of my stored input, applying that input to the new updated position and updating the corresponding states in my input log with the updates ones. That works fine, here's how it looks with some ping and packet loss:
Blue is the predicted player position. Red is the received server position (S). Green is the stored position that we're rolling back to when we get the server position and correcting (P). The white dots represent all of the positions between green and blue, and those dots turn red when we did a correction this tick.
You can see jumps from the packet loss, but overall it's alright.
My problem comes from wanting to smooth those jumps. I got the bright idea that, rather than just setting P to S directly, I could do something like P += (S - P) * 0.3 -- ideally this would cause some softer adjustments. However, what this seems to cause is these sorts of cyclical adjustments in rapid succession, even when there's no input or anything that would cause the client to deviate from the server:
All I changed in my code was making it a 30% snap instead of a 100% snap. The idea being that I'd rather slowly nudge the correction towards the right position than snap it outright. Is there something conceptually I'm missing here? Is there any other way to smooth these snaps that I could do instead? When I'm not hitting any keys at the end of the gif and the dots are still solid red, shouldn't the green ship slowly be getting dragged back towards the red? It seems to stay right in the middle of the blue and red ship, which is strange to me.
I have a hunch that the fact that my ships have a lot of momentum (as opposed to FPS games where your player stands still if you take your hands off the controls) could cause these repeating corrections, but I'm not sure.
Any advice would be greatly appreciated. Thanks!
Edited by sufficientreason, 19 July 2014 - 01:49 PM.