I've been wanting to create a multiplayer FPS.
For the network part I've come up with the following:
There will be one central server, acting as a lobby. All clients can connect to this server and request a list of games being hosted. A client can then pick one of those games and request the server for the needed information to actually join the game.
Every game is hosted by one player, the host. The host will act as the central point connecting all the clients in the game. The hosts gamestate is the one true gamestate, ie when one of the clients disagrees with the host's gamestate that’s too bad, because the host is the boss around here.
Whenever a client provides input for the game (such as clicking a mouse button, moving the mouse, pressing a key) this input is sent to the server, which in turn sends it to all other clients.
To provide some illusion of smooth motion, gamestates are updated locally according to the locally known input states. But there is always some difference in time between actual input and the arrival of a message notifying about this input. That’s why these messages should have some sort of timestamp, so that when receiving an update on input we can handle it as if it really happened at that point in time. To make this happen, we need to keep a buffer of gamestates so we can make the update in a previous gamestate and recalculate the new gamestate.
But now I'm still having some questions:
- What sort of timestamp should I use? A simple counter that starts at 0 and increases at, for example, 60Hz? How do I synchronize this counter for all clients?
- Would it be okay to handle some collisions only at serverside? Such as a bullet hitting a player or a player picking up a health pack. Server sends a message that it happened and voila, it happened everywhere. Else I'd have to implement some kind of query "Did I pick up this health pack?", which seems an inferior choice.
- How long should I keep old gamestates? Discard anything before the oldest update of all of the players? But what if somebody in the game is AFK for 15 minutes, that would make everyones buffers grow pretty big. Maybe send an obligatory status update every 2 seconds or so?