I did a talk on games at Flash Kit in 2001, when games were just starting to become feasible in Flash. Ironically, the talk was on games in general, but also on how one would integrate them to 3D – which was simply not done at the time. It was a lot of fun, in Los Angeles, at the big convention center next to the Staples Center.
My aspect on the talk was on the relatively new concept of Multiplayer gaming in Flash. Read on to see what I wrote.
“The future is now. Soon every American home will integrate their television, phone, and computer. You’ll be able to visit the Louvre on one channel, and watch female mud wrestling on another. You can do your shopping at home, or play Mortal Kombat with a friend in Vietnam. There’s no end to the possibilities.”
– Jim Carrey, The Cable Guy – (Columbia, 1996)
Multiplayer games generally come in two types: Real-time and turn-based. Real-time games are game in which the action is reflected on all players’ screens and things change and move quickly (many times per second). There is no stopping to wait for other players to make their moves and the sense of being there in an alternate reality is heightened. These games have a large hardware requirement in order to make the game run quickly but smoothly over the Internet with an indefinite number of players.
A turn-based game is just the opposite. It’s a game in which players wait for their turn to perform an action. Games like Chess or Risk are perfect, classic examples of turn-based games. Turn based games require a less robust communication architecture.
Client / Server Architecture
The client/server method of connection and communication differs from peer-to-peer because the client/server method utilizes an intermediary in the communication process.
A client is simply an industry word that refers to the player’s computer. This is the game itself, and is all the player cares about.
A sever is a centralized computer that connects many clients together, and is often responsible for performing a great many tasks. Often, the server is a very powerful computer that can handle things that an individual client cannot. The server is responsible for telling all the clients where each other client is. Take a look at this image:
When one client performs an action, like moving or attacking, that message action is conveyed to the server, which then informs every other client of the action. This has the advantage of allowing an unlimited number of players to connect to one game. The server keeps track of the entire game world, allowing the players to roam freely. The server is also responsible for keeping everything synchronized between clients.
In client/server architecture, the players never directly communicate with each other as in peer-to-peer communication. Any action, like move, shoot, or even chat must pass through the server. There are many different types of servers, from game servers to FTP servers to HTTP servers.
The standard method for addressing an individual computer on the Internet is through a number known as an IP (Internet Protocol) address. This number comes in the form of ###.###.###.###, where each number between the dots can be from 0 to 255. So a computer might have the IP address 18.104.22.168, and that computer is accessible from anywhere on the Internet, as long as you know that IP address.
How exactly that computer responds to incoming requests depends on the computer’s setup. For example, a computer that is setup as a web server will respond to incoming requests by sending back web pages. However, a computer that is set up as an FTP server will respond by attempting to create an FTP session with the incoming computer. However, it’s not that simple, because a computer can be both an HTTP and an FTP server. This is accomplished with the use of ports, as seen below.
Along with the IP address, there is another number known as the port. The port is usually notated by putting a “:” after the computer’s IP address followed by the number, 22.214.171.124:80, would be port 80 at that IP address. A port is like a television channel – certain types of information are transferred over different ports, though they all come from the same station (the IP address).
For example, port 80 is usually reserved for HTTP, so when use a web browser to visit a site, your browser invisibly sends its requests to the web server through port 80. On the other side, the web server is sitting listening on port 80, and it knows that anything that arrives on port 80 is an HTTP request so it prepares to fire up an HTML page. These are some of the typical reserved port numbers:
|101||NIC Hostname Server|
Expect a response from an IP (on a particular port) only if the computer at that IP has a server running that is designed to listen on that port. So, if you find out the IP address of your friend’s computer, don’t expect to find an FTP server running on port 21 of your friend’s computer. Your friend must have an FTP server running before your FTP client will be able to connect to him.
There are many other reserved ports beyond these. When we get into socket communications for games, you’ll see that they require an IP and port to transfer game information. Your choice of port is arbitrary but it should not interfere with common port numbers. So, as a rule of thumb it’s generally a good idea to try and use ports for your game that are above 1023.
Flash has two means of communicating with external resources: HTTP and Sockets. Each has advantages and disadvantages.
HTTP (HyperText Transfer Protocol) is the standard method of data transmission amongst computers on the web. HTTP works by sending variables to an HTTP server (a website), and that server performs various tasks and sends information back to Flash. An HTTP connection is opened once the data is sent, and then closed when the results are returned to Flash. This is the exact same protocol used in web pages when you send data from an online form.
HTTP information is sent primarily with the loadVariables() function, and it works by sending the variables that are sitting in the same object level as the call to loadVariables(). Take a look at a the following Actionscript attached to a button that is inside a MovieClip called container:
a = 1;
b = "HELLO";
loadVariables ("http://www.test.com", _root.results, "POST");
This is a very simple piece of code that create two variables, a and b, and then POST them over HTTP to the HTTP server at http://www.test.com. When the server has performed some actions with these variables, it will return its results to a MovieClip called _root.results.
Note: Flash will send any variables that have been defined in the local object (from where the loadVariables() was called), so even though we see only a and b in this example, if there were any other variables that were created in the container MovieClip, they will be sent too. The URL specified in the loadVariables() command must begin with http:// in order to work.
There are two methods of sending data “GET” and “POST”. These are functionally different, and some servers expect to receive data via a GET and some via POST. What you would use would depend on your server, and you would thus need to design accordingly. When information is sent via HTTP, there are several other items that Flash sends (in accordance with the HTTP protocol) that increase overhead and slow down the system. Items such as the current time, the user’s IP address, referrer address and browser information are all sent through with your GET / POST data.
I’m assuming that if you can make a server, then you know the difference between GET and POST. This chapter is not on making servers; it’s on making multiplayer games.
HTTP has one distinct disadvantage, and that is its speed and connection. Since HTTP closes the connection after data has been returned, connection must be reestablished when the next call is made – and this slows things down. It also means that the server cannot talk to you unprompted. In order to get a server status update, you must send an HTTP request asking the server for updates and information.
Many games can be made however, that make use of HTTP communication, and it has the distinct advantage of being able to get past most major firewalls. Simply put, firewalls do not usually block port 80 (HTTP) so any Flash request coming via that port will not normally be blocked.
HTTP is best suited for turn-based games because of the connection and communication limitations. From a programming standpoint, this type of game is generally easier to make (than real-time)
Socket communications are one of the most recent additions to Flash, and one of the most powerful. With a socket, it is possible to open a direct line of communication between a Flash client and a game server. This socket does not require a specific protocol like HTTP, so you can send any amount of information between two computers talking on a socket port – no extra information is sent; you specify what will be sent.
Generally, a socket connection is established with a socket server (a server that is set up to listen on a predetermined port) and when a connection request comes through it initiates a connection, and then the client and the server are connected. At this point, any data can be freely transferred between them.
When the server decides that the client needs something updated in the game, it can simply send out the information to the client and when data is received Actionscript is automatically executed to handle the incoming data. This real-time event response means that sockets are a much faster and more stable way of communicating between a game client and server. Sockets lend themselves perfectly to the task of creating high-speed, real-time multiplayer games.
A socket communication path is created between a client and a server. Generally, the server is at a specific IP address, and it sits listening and waiting on a specific port. Let’s say that there was a chess game server at IP 126.96.36.199 on port 15000, then that means that when our chess client connected to 188.8.131.52 port 15000 that the game server would recognize the incoming connection request and, upon acceptance of the connection, the game could begin!
Opening a socket is a simple procedure of creating a new XMLSocket object in Flash and then assigning it some callback functions that will be automatically executed when data is received. The following code creates a new XMLSocket object.
sock = new XMLSocket();
Now, sock is an XMLSocket object, and we can assign two callback functions, onConnect and onXML. Let’s say that we create two functions:
function myOnXML (doc)
These two functions are very simple, and they merely use the trace() command to display some information. The key thing is, the purpose of the functions. myOnConnect() is going to be the function that is called when our socket server returns a successful connection message. myOnXML() is what is going to be called every time the server sends us information. It is this function that is the bread and butter of Flash socket communications.
But, first we have to tell Flash what the name of our functions are so it knows what to call when these events occur. This is accomplished with the following Actionscript:
sock.onXML = myOnXML;
sock.onConnect = myOnConnect;
onXML and onConnect are simply properties of the XMLSocket object, and into those we assign the names of our custom functions.
When onConnect is triggered, then myOnConnect() is called, and it is passed a simple Boolean (true/false) variable that says whether or not the connection was a success. In our function I’ve called the variable success. When onXML is triggered, then myOnXML is called and the incoming data is passed as a string. In our function I’ve called the variable simply doc.
When you wish to actually issue the connection request, you simply use the XMLSocket’s connect method, like so:
Where ipaddress and serverport are going to be defined by the IP of the server and the port on which it’s listening. When the server returns a successful connect, then success will be passed as true to the myOnConnect() function.
What to use?
Deciding what method of communications to use is entirely dependent on the type of game you wish to create. If you are creating a fast, real time game like the racing game later in this chapter, then you must use sockets because only sockets can freely and quickly send data back and forth between the server and multiple clients. However, if your players are behind a firewall, then you can create a game that doesn’t utilize a real time high-speed structure (like Chess or Bingo) and perform communications over the unblocked HTTP port 80. Unfortunately because HTTP communication does not use callback functions, the client must be programmed to regularly send a POST or GET to the server to find out the current status.
In this chapter, I’m going to focus on socket communications for making high-speed multiplayer games. This is the communication model that allows the fastest game play, and as of this writing, its potentials go untapped in today’s Flash games.
I suppose what is also going unsaid here, is the fact that the communications model in Flash must be the client / server model, and not the peer-to-peer model. This is because Flash cannot be told to listen on a port without first establishing a connection. Only servers can be told to listen for connections – Flash cannot. Two Flash peers would never be able to talk to each other because neither one would be willing to listen – just talk. You need the server to bridge the communication gap.
Multiplayer Flash must use the client/server architecture since Flash utilizes http and socket communication – two systems that both work by talking to a server at a specific URL or IP address, therefore it is not possible to make a Flash client talk to another Flash client directly.
Now, let me say this: XML is a very powerful way of sending large amounts of data from a server to a client. However, there is one small problem: XML is not efficient – in space or in time. An XML document takes a relatively large amount of time for Flash to parse into directly usable variables, and the amount of data sent from a server is large because it contains all the <tags></tags>.
What does this mean? Basically that in the context of our high-speed multiplayer Flash games, XML is not the route I’m going to take. Yes, I’m using the XMLSocket, but I’m not sending XML data across it. I’m only interested in the Socket part of it, and what I’m going to be sending are pieces of data called packets. These are much smaller, and can be anything I want them to be.
Thus ends my discussion of XML. If you want to learn about the XML object itself, then take a look at Flash 5 Actionscript Studio, chapter 11 on the XML object. We’re going to focus now on game efficiencies.
Our best friend will soon be the packet. A packet is not something that you can define – it is, put simply, anything you want it to be. A packet is a general term used to describe some data that is sent from one computer to another.
A packet will vary in shape and size depending on the information that is being transmitted. For example, a packet that sends a player’s location may look like this:
That’s all the information that will be sent either from the client or from the server. We make up our own packets – we decide how they are going to be structured, nobody else. For us, a packet is simply a string. For example, I’ve decided that my packet will consist of variables and values, separated by commas. The above packet would mean:
“This is a player’s location (the L) Player number 451 is at location _x = 200, _y = 100. ”
If your XMLSocket object was called sock as in our earlier example, and our packet was stored in a variable called packet, we would send the information to the server like so:
That’s it. Packets are short and simple, and don’t require tons of overhead to dissect and interpret. A few simple string manipulations are all that are required to break the above packet apart.
Packets are usually sent every time an event occurs. Some of the events that may trigger packets are:
- Movement: When a player moves, the client will send through a packet indicating that movement to the server. Such a packet might include player id, x and y coordinates, speed and direction. When the server receives this packet, it will then send out a packet to all other players, telling them that this player has moved, and where they are.
- Firing: When a player fires a weapon, it sends through a packet to the server in the same manner, and the server tells everyone else, and determines if someone was hurt, and if so, informs the victim’s client.
- Connect: When someone joins the game, they will be sent a packet from the server, which indicates the location of every other player in the game. The other players in the game will also be sent a packet informing them of the new player’s arrival.
- Disconnect: When a player leaves, the server will inform all the other players and the exiting player will disappear from everyone’s game.
- Chat Message: When a player uses an in-game chat feature, then the client will send a packet to the server that contains the chat message. This will then be sent out to the appropriate clients so that the message appears on their screen.
- Game Restart: When the game finishes or restarts, the server will send a restart packet to every player so that everyone’s game will restart to the same point (for example, everyone back to the starting line).
- Key state: Sometimes the simplest packet is sending the player’s current key state (which keys are currently pressed) to the server, so that other clients can use this information to accurately draw the player’s movement.
Packet design is a tricky process of deciding what information is needed to fully convey game events, without providing too much information and taking up unnecessary bandwidth. Remember, in a socket-based multiplayer game, bandwidth is very important because the information is coming fast and furiously so Flash needs as much help as it can get in simplifying the overall process.
These Excerpts taken from Flash Games Studio, ©2001, friendsofED
For a complete multiplayer game tutorial (and many, many more game fundamentals) get Flash Games Studio today.
© 2001, Glen Rhodes (www.glenrhodes.com) all rights reserved.