I'm working on a multiplayer game which involves a huge amount of predictable AI enemies, and a few other players. The enemies are the most important to be accurate, because the game involves pixel perfect dodging.
In deciding how to network this game, there are two main objectives:
- Smallest possible bandwidth usage.
- Game remains playable over bad connections, like wifi & mobile.
I have thought of this system:
- On connection, send full server state to client.
- Client & server both simulate all enemies.
- Server sends updates on what tick it is currently on, and anything that's non-predictable (other player movement, etc), but does not include the enemy details.
- Ensure simulation is deterministic by sharing implementation, using fixed timestep, share random seed, etc.
- If client gets out of sync, can re-sync by requesting all information again. Can check via tick number or via some checksumming mechanism.
How to deal with clients & servers going out of sync due to tick rate discrepancies?
Normally I'd use a delta based on the last tick for the simulation, but the need for a fixed timestep (to avoid floating point error) means that's impossible. If the client or server is running slightly slow or fast, it'll get more and more out of sync. If the sync gets bad enough, we can re-sync.
My basic testing with a Chrome client shows that skew can happen fast and consistently, getting about a tick out of sync every second (at 30fps). Even 1 or 2 ticks off can really ruin the game experience since it's a pixel perfect avoidance game. It seems we'd need to resync every second or so, which may also be jumpy and look weird, though interpolation could smooth it out.
Is my system fundamentally flawed, or is this something that can realistically be smoothed out?