The Essentials of Multiplayer Games
There are a few distinct flavors of multiplayer games, all of which require different approaches. On one hand, there're games written for many players, but designed to be played on a single machine. On the other, there are games written for local play, or in general, gameplay across more than one machine with a local connection not reliant on a network (like a null modem cable or dial-up modem game). Finally, there are games which take place over large, wide-area networks. I shall refer to these as single-machine, local, and networked multiplayer games, respectively, from here on in. In single-machine multiplayer games, the main game loop must call the engine to process each player involved in the game; this includes getting input from them, moving them, rendering their view, and computing any other logic associated with them in the game. In a local multiplayer game, the game loop only needs to process one player, the player on the machine which the game is running, then send information about the player out to the other machines and accept information about the other players (if needed) in return. Networked multiplayer games are similar to local multiplayer games, but a client/server model is generally used whereby each machine transmits its data to one server, then gets information about other players back from the server. Single-machine multiplayer gamesWhen designing single-machine multiplayer games, which are not very common on PCs these days, you must take into account several questions. The most important of these would be, "How is each player going to be getting input to the game?" and "How is each player going to see their character move, with only one screen?". Some common approaches include using two input devices, such as a joystick and a keyboard, or sharing one input device, such as two people using one keyboard (there would have to be seperate keys for every action for every player). Trying to share an input device is a very outdated approach, and I'm pretty sure that the gaming community got sick of it early on. There have been a few more worthy approaches to the display problem. Most single-machine-many-players-at-the-same-time games simply let players share the same view. As a rule, this will work well only if the view isn't first person, and only if (for 3D games) camera control is independent of player positions. In the old side-scroller days, we sometimes saw split screens, wherein each player's view was rendered on a different half of the screen. Split-screens are a big drag on rendering time for any kind of game, and they definitely can make a game cumbersome, but they do work. About the most effective approach to the display and input problems associated with one-machine mulitplayer games, at least for PCs, is to use a turn-based system. Considering that they're still actually implemented, I'd say that turn-based systems have had the most luck over the ages. Turn-based systems work by switching between player and player and allowing only one player to play at a time. //A turn-based thingy //somewhere in a header player *cur_player; ..... //somewhere in some source file void switch_player(player *p) { cur_player = p; switch_level(p->level); ..... //in the main loop move((player *)&cur_player); Anyone that can write a single-player game and has an understanding of scalable design knows enough to write a single-machine multiplayer game. Because I've covered scalability, and I assume that you can write a game (as a game programmer...), you can write one, if you'd like. I suspect that you wouldn't like to; you're probably more interested in networked games. Single-machine multiplayer PC games are becoming progressively more extinct, but I find it fit to note that old single-machine techniques aren't useless. Consoles, mind you, are still very big on one-machine multiplayer.
Local multiplayer gamesLocal multiplayer games have been around for quite some time. Support for null-modem play is still very common in today's games. On the contrary, direct machine-to-machine modem connections are a lot less popular than they once were, due to the fact that it gets a bit limiting facing the phone charges associated with long-distance modem calls. The architecture of a local multiplayer game is fairly simple. Each machine is responsible for updating the game for one player. Each machine then stores the changes in player state in a packet (a packet is data with a header to be transmitted across a connection), which is sent to the other machines. The other machines in the game use this data to update their game-state, and send out information about their own players' movements, and the cycle continues. Obviously, the specific implementation of this scheme is different between different games: In realtime games, asynchronous packet transmission is a must, and the game has to stay synchronized even if data packets are missed. In non-realtime games, you can rely on sending and receiving packets at a definite time, and you also don't have to worry about overburdening your data stream. So here's a basic recepie for a local multiplayer game. First, you establish a connection to the other machine(s) in the game. This shouldn't be too hard, considering that a phyisical one (such as a LAN or a null-modem cable, or a direct phone line [modem]) must exist for your game to be considered "local". Then, you somehow negotiate the initial setup of the game. Finally, the game begins, and you begin the data-transfer process just described. Then, of course, you close the "connection". It's conceptually simple. Here's some code to convey all of this, and a bit more (a very simple example). //pseudo-code #define NEW_GAME 2 #define LEAVING_GAME 4 #define SOMETHING 8 #define RESET 16 #define ESCAPE_SEQUENCE 0xFFFFFFFF #define MAX_QUEUE 16 #define MAX_BUFFER 256 typedef struct { int obj,x,y,z,frame; //none of these can be 0xffffffff input_status i; //no elements of this can be 0xffffffff unsigned char flags; //can't = 255 (0xFF) int magic; //always 0xFFFFFFFF to indicate the end of the packet } game_packet; game_packet queue[MAX_QUEUE]; int cur_queue=0, unprocessed_packets=0; int sync_err=0, packets_lost=0; //sync_err is a reserved flag for major //synchronozation errors unsigned char serial_buffer[MAX_BUFFER]; int cur_buf=0, last=0; //read this carefully (regarding an imaginary interrupt handler x): //how it works: //interrupt-handler x is called when a character is received from the //serial buffer. The interrupt handler sets serial_buffer[cur_buf] to the //character received, increments cur_buf, and performs any necessary bounding //work (making sure that cur_buf Networked multiplayer games: Internet intro ala crash-course
Networked multiplayer games are conceptually the same as local-multiplayer games, with a few exceptions. First of all, each machine in the game still handles processing for the player using it. However, instead of sending packets out to all of the other players in the game (or just the other player), in a networked game, machines send packets to one central server and receive packets from the server in return. The server is at the center of the game, storing all the game's information and keeping things running. If turn-based systems are used somehow, then the server is responsible for managing them. All the machines connected to the game's server are called clients. This model in general is called the client-server model of communication. Client-server is the communications model used in the real world, so get used to it.
Networks implement communication protocols in order to give meaning and structure to communications taking place on them. All communications on a network are carried out according to a standard set of these protocols; if you are to use a network effectively, then you must use its communications protocols. The Internet has TCP/IP (Transmission Control Protocol/Internet Protocol) to serve this purpose. TCP/IP is a family of protocols, both application-level (i.e., high-level, like FTP, HTTP, Gopher) and network-level protocols (such as IP, ARP, ICMP). In TCP/IP, packets are constructed and routed through the network to the appropriate machine, based upon the headers of these packets. The data-area of these packets is the acceptable place for you to put your game's data (you don't have to handle packets quite as was done above). The Internet gaurantees that your packets will be sent to the correct machine, that is, the machine running the server. Client applications, or the version of the game that you would distribute to your end-users (this program is often called the "client"), send TCP/IP packets to the server, a program that dissects them and processes them; the server is a program that runs on a machine identified by an IP address. The server listens to a TCP/IP "port", where data comes in, and sends data back to its clients via TCP/IP. For the amateur, client/server based games can present a lot of problems, when one tries to take them on from the ground up: First of all, you need a dedicated machine with a dedicated IP to run the server. Next on the list, the machine has to be able to actually run the server: Many commercial end-user operating systems like Windows 95 don't ship with TCP/IP server implementations. Fortunately, there are solutions such as Linux... There's a lot involved in sending and processing a single packet of data in networked games. Fortunately, in most operating systems, we've got access to TCP/IP client implementations that allow us to avert the technicalities of low-level Internet communication. With Winsock, for instance, it's possible to come up with programs that do things like retrieve web pages from port 80 on any machine, in about a page of code. High-level operating system APIs for Internet functions are a blessing, not a hurdle, despite what the complaints may register. After all, is it really practical to implement around thirty years of Internet yourself? That's all for nowHopefully, this article has helped you understand the essentials of multiplayer game programming. If you didn't understand it, go back and read through it again; this was designed to be a practical introduction that would allow you to go write some multiplayer games as soon as possible. Anyway, happy coding, and finish that game! :) Discuss this article in the forums
See Also: © 1999-2011 Gamedev.net. All rights reserved. Terms of Use Privacy Policy
|