Structure of a user-hosted client/server network game

jwatte's picture

Recently, a question came up about how to structure a client/server networked game where users can host games that other users can join. I think I did a reasonably concise write-up of a common-sense approach that's been successful for many years, so I'm archiving it here for posterity:

I would implement it something like this:

1) The game always uses a client and a server. Even when playing single player -- client and server run on the same machine (in the same process, even).

2) When a player hosts, and a second player connects, then that second player is running only the client part. The server part is then run on your machine.

3) Exactly how to distribute state between client and server depends on your specific game design. How you do simulation, prediction and validation varies greatly between, for example, a multiplayer RPG, a FPS, or an RTS game.

4) In general, though, you want game objects to have a few different responsibilities:
- input: how does the user interact with it? (mouse, key, etc)
- action: how does the object affect game state?
- presentation: how is the object rendered?
- persistence: how is the object saved/restored in savegame files?

It's quite possible that you write input and presentation to run on the client side, and action and persistence to run on the server side. You can define some set of properties that the two sides can use to agree on the state of the object -- position, velocity, mesh used to render, whether some explosive has been fused, etc.

Now, the job of your client code is to present a UI to the user, based on the state of the game objects, and forward requests from that UI to the action component. The job of the action component is to validate requests, reject bad requests (for example, two users may request to pick up a health pack -- only the first one actually gets it), and update state based on this. State changes get reflected back to clients. Clients render the objects based on the state.

This is a pretty classic model that's been used by many games over the years, and it works pretty well.

Note that the interaction - action - presentation isn't actually synchronous in a real implementation. Each frame, each object will look for any possible interaction, may receive state updates from the server, and will render itself based on the current state.