I'm finally getting around to putting "proper" netcode in my golf game, and I'm having a lot of trouble figuring out how to "sync" against a previous state. I've currently got it implemented in the most naive way: the server sends a "sync" message with everyone's positions and velocities to every client every second, and the client just resets all the positions/velocities of the physics bodies to whatever the server sent.
The problem is that the server state is often ahead of the client state, which I think makes sense: the server is sending each player's swing to the clients, so the network lag there causes the client simulation to be slightly behind. So when the sync happens, the balls of all the players "jump" forward a bit to whatever the server simulated.
I looked into implementing a clock, with the idea that the server would send a clock with its positions data the client could compare against. But I'm not sure what this should look like.
My first thought was that:
- When the player connects to the server, the server sends its current time, and the client does all of its time calculations based on this initial time.
- Sync messages will include the current server time
- When the client receives a sync message, it:
- Looks back to the physics state at that time
- Check to see if the stored state significantly off from the sync message state
- If so, reset all of the ball positions and to the synced message and advance the world by the delta between the current time and the sync time to catch up.
However, the problem I ran into with this plan was that the client's time is always going to be behind the server time (since there was some lag in sending the initial time to the client). This means that when the sync message comes in, the server time included in it is often ahead of the client's time, and of course the client then can't "look back" to the state at that time, since it hasn't been calculated yet.
I'm not sure what the right way to solve that is. I suppose that either the sync messages could be stored until that time is reached and then checked, or simply some kind of buffer could be added to ensure the client is always ahead of the server.
I've been looking into some articles on this (like http://gafferongames.com/game-physics/networked-physics/) but all of them seem to assume that the client time is always ahead of the server time, so I feel like I must be implementing the clock wrong, but I'm not sure how.
a) give yourself a buffer and let the server get a head start b) give the client an animation for hitting the ball before it hits -- send notice as soon as ball hits of what the force is going to be at which frame (or time offset) c) the server can be ahead, either the client needs to catch up, or wait for the frame (time) to actually do anything. If things get more than 200ms behind, try to catch up, otherwise, let the server be ahead. If the server is less than 17ms (16.66~), let the server get ahead a bit, and slow down the simulation.