Ok, I'm feeling really pressured right now so you'll have to forgive me if I don't come up with a really cool intro paragraph on multiplayer networked online game programming (he he, a few keywords for the search engines...). Over the course of the next few weeks I'm going to show you how to build a realtime game for as many players as you would like, ala defender/asteroids/etc... I read Winsock 2.0 by Lewis Napper (ISBN 0-7645-8049-3), pretty much everything after that was self-taught so if I screw up the terminology, I appologize ahead of time.

The next few weeks are going to cover a lot, so here's the game plan:

1. Things that make you go "hmm...": What you need to consider before you start coding. Includes discussion of game types, client/server models, game elements, thoughts on program structure.

2. cComm one, cComm all: The base communications class.

3. cClient. cClient run: A general client class built on top of cComm.

4. cServer? I barely know her!: A general server class built on top of cComm.

6. Talk about things you like to do: Designing a language for our client & server. Once you've connected and you're in the game.

7. I bent my wookie: Tips on how to smooth things out and dealing with latency.

Now let's get the show on the road!

Things that make you go "hmm..."

There are a number of things to consider before you start writing your game. That's right, before. Some of you may have tried to convert single player games to multiplayer only to find yourself buying new keyboards because you cried so hard the old ones short circuitted. I feel your pain.

The first consideration is: how realtime does your game have to be? I can think of three basic "speeds" of game:

1. Play by mail (Imperial Nomic...)

2. Turn based games (Go, Chess, Bridge, etc...)

3. Real time (Quake, Half-Life, Unreal, etc...)

Play by mail doesn't concern us since it doesn't require a server. Ok, ok, you could write one, but why?

Turn based games are really a fast version of play by mail. I say this because if players were known to take a really long time between turn you could disconnect from the network during the iterim. I've never heard of anyone doing this, so it's a moot point. One nice thing about turn based games is you don't have to worry about a little delay in response time so the ammount of data being sent back and forth isn't a major concern.

Real time games are the bread and butter of the game industry today. They're the fast-paced space racing kung-fu eye gouging adventure we've all come to love. If you've just started coding and you want to bite off more than you can chew while you skip to the last chapter, this is the thing to start with. Seriously, you need an ingenuity that only comes with real understanding of your programming language (in our case, C++) because you're going to want to do EVERYTHING possible to reduce the ammount of data passing between client and server.

The next consideration is the complexity of the game or (as I like to think of it) the size. The more different things people can do in the game, the bigger it gets. The bigger it gets, the more data has to be transmitted. The more data has to be transmitted, the more bandwidth is needed. The more bandwidth is needed, the fewer the players and the greater the lag. It's a little like dominoes, knock over one and they all come tumbling after. This doesn't mean that you have to scale back your design and start simplifying, it just means you've got to be clever about it. More on that later.

Based on each of these considerations you have to choose a client server model. There are two types:

Distributed model: Every client is connected to every other. NOT reccomended for a large scale multiplayer game because the number of connections is O( n2 ) which almost guarantees somebody somewhere will lose some crucial data and fall out of synch. In fact, I don't think it should be used for any type of game at all. The only advantage of a distributed model is that if one computer logs off the game doesn't end. Theoretically you could keep playing forever as long as there were two or more players.

Centralized: All clients are connected to a central server. There are O( n ) connections at any time, meaning much less work on the part of the client computers. The real advantage, however, is that the server can keep everyone in synch and that's very important. There are a few drawbacks, however. If the server hiccups, everyone else gets sick. What I mean is if the server lags everyone lags and if the serer disconnects it's game over. Also the server has to be O( n ) times more powerful than any client machine in terms of bandwidth in order to be able to handle the transmitted data. Many games have a client that is also a server. The advantage in this is that the game data dosen't have to be loaded twice and a lot of CPU usage is saved, meaning more clients can connect smoothly.

Now let's take a look at our space shooter game and see what it will entail.

Client Login
... should connect to a server and request information like game name, number of players (and their names), max players, password protection and time the game has been running.
... should make a login attempt by sending a name and password.

Client Round Menu
... is where the client should choose the arena to fight in (if there's more than one).
... is where the client should choose the team or clan they belong to.
... should wait for selection approval from the server.
... should wait for chat messages and echo them to the screen.
... is a good place to put a chat and message system.

Client in game
... is where the client can move about. We'll accept movement forward, back, left, right, strafe, fire and maybe a "use" action.
... is where the client sprite can be spawned, teleported, healed, hurt and killed.
... is where the client sprite can collide with things.

Client misc
... should await game status, sysadmin messages and echo them to the screen.
... should cope nicely with sudden server disconnect.

Server Login
... The server should always be ready to accept new login. It should reject new clients if

The server is full.

Their IP has been banned (probably for hammering DoS attacks).

Their name is already being used.

Their password is wrong.

... The server should only accept login commands from players it recognizes as being in login state.

Server Round Menu
... should only accept menu commands from players it recognizes as being in menu state.
... should approve requests to join a team or arena based on how many people are currently in that team/arena.
... should echo chat messages back to all clients in menu state except the one who sent it.
... should echo sysadmin and game status message to all clients.

Server in game
... should only accept menu commands from players it recognizes as being in game state.
... should await the following commands: move forward and back, strafe left and right, turn left and right, fire, use, quit to menu and quit game.
... should echo the effects of all commands from a player to every other player that would be affected.
... should keep track over every sprite, bullet, bomb, nunchuck, broken arrow head, nuclear weapon, roving derelict space ship, planet, black hole, bonus item and hot dog stand moving in the game and deal with what should happen when they collide.

Server misc
... should track the idle time of online players and disconnect those that lag too long.
... should cope nicely with sudden client disconnect.

Phew! That's a lot of stuff to do, but we'll get there. Next week I'll detail the base network communication class that everything else will be built upon and show you how to get it working in a Win32 application.

Article Series:

Network Game Programming - Issue 01 - Things that make you go "hmm..."