Flash 10 Multiplayer Game: Game Interface Design

(For more resources on Flash and Games, see here.)

Overview of Pulse library components

The Pulse package includes two components Pulse.swc and PulseUI.swc.The Pulse.swc offers the API required for you to build a multiplayer game. While PulseUI offers the game screen management, both aid in the rapid development of your game. The Pulse.swc is required in order to communicate with the server and with other clients. The usage of PulseUI, on the other hand, is optional. It is recommended to use the PulseUI since it allows you to focus only on the game implementation and leaves the standard feature set of a multiplayer game to be taken care of by the PulseUI package. Once you have the implementation of your game done and working well, you can then replace the PulseUI package with something of your own that is more suited to your game.

The following is a block diagram that shows the dependencies among different components:

The Pulse API design

The interaction of the game client with the server and other clients happens primarily via two classes that expose the Pulse features:

  • GameClient
  • GameClientCallback

The GameClient is primarily used to send request to the server while creating a room, joining a room, or sending a message to other players such as chat or game state updates during game play.

The GameClientCallback is an AS3 interface class for which one of the classes within the GameClient must implement. All notifications from the server are processed by the Pulse layer and corresponding notifications are called on the implementation of the callback class—for example, when a create room request was successful or when a chat message was received, etc.

Creating the Hello World sample

Let us now explore the Hello World sample that is included in the Pulse package. The Hello World sample and the rest of the samples rely heavily on the game screen management framework package, PulseUI, which is also included in the Pulse package along with the source code. In this article, we will focus on the code contained in the Hello World sample and how the sample makes use of the PulseUI.

In order to explore the Hello World sample, we first need to create a project in Flash Builder—all the required source files already exists in the sample folders. The Hello World sample does the following: create a room or join an existing game room, then add, remove, or modify a game state—the changes done on one client instance are then reflected on all other clients that are in the same room.

Think it is too much for a Hello World sample? It is not! These are just the basic functionalities for any multiplayer game. Moreover, we don't need to write the code for every bit of functionality because we heavily rely on Pulse SDK to do all the dirty work.

Setting up the project

Fire up the Flash Builder 4 IDE and let us start by creating an ActionScript project called Hello World:

  1. From the main menu, navigate to File | New | ActionScript Project. You will see the following screenshot. Enter a project name HelloWorld or any other name of your choice.

  2. Since we already have the entire source required for Hello World from the Pulse package, click on Next to specify that the source folder is already on the disk. This will bring up the following screen where we choose the Hello World src folder as shown. Note that the screenshot shows that Pulse was installed under F:\Gamantra. This path may be different on your computer.

  3. Once we have chosen the source folder, we still need to choose the main source folder and main application file. Unfortunately, in order to do this, we need to navigate a bug in Flash Builder 4. You need to click on the Back button and then again on the Next button, bringing us back to where we were.
  4. We now click on the Browse button, as shown in the screenshot, and choose the [source path] src and click on OK.

  5. Next we choose the main application file—this determines the main class file that the execution will start with.

  6. We need to tell the Flash Builder to use the Pulse libraries for this project. In the Flash world, the library files come with an extension .swc, which stands for shockwave component. Once you make it available to your project, you can start using the classes and functions that are exposed from within the library. In order to do so, choose the Library Path tab view and click on the Add SWC… button; navigate to the lib folder within the Pulse installation folder and choose Pulse.swc and once again do the same procedure for PulseUI.swc. Click on the Finish button.

As a final step, before attempting to run the sample, we also need to set the stage size to 800 (width) by 600 (height). The PulseUI requires the stage size to be exactly this size. We may also set the background color of our choice as shown in the following screenshot:

After this step, Flash Builder 4 should be able to crunch all the code in folders and report no problems. This will also create the swf files under the project folder within the workspace ready for you to take it for a spin.

At this point, you may also use the debugger to step through the code. But make sure the Pulse server is running so that you may login and explore all the screens.

The Hello World specification

The Hello World client will be able to create a new HelloGameState and share it with other players, and any player may change the x and y and have that change reflected in every player's screen. Here is the final screen that we will end up with:

The screenshot is that of the game screen. The circles are a visual representation of the game states, the position of the circle comes from the corresponding game states x and y values and so does the color from the color property. We will have two buttons: one to add new game states and another to remove them. To add a new circle (a game state), we click on the Add button. To remove an existing game state, we click on any of the circles and click on the Remove button. The selected circle appears to be raised like the one on the far right-hand side of the screenshot. We may also modify an existing game state by moving the circles by clicking and dragging them to a different position—doing that on one client, we can observe the change in every other player's screen as well.

The schema file

For any Pulse-based game development, we first start out with an XML-formatted schema file. Let's now explore the schema file for the Hello World sample.

The game developer must create a schema file that specifies all the needed game states, avatars, and game room objects. After you have created the schema file, we then use a Pulse modeler tool to create the class files based on the schema to be used within the game.

So first let's examine the schema file for the Hello World project:


<client import="pulse.gsrc.client.*" />
<class name="HelloGameState" parent="GameState" classId="601" >
<property index="0" name="x" count="1" type="int"/>
<property index="1" name="y" count="1" type="int"/>
<property index="2" name="color" count="1" type="int"/>

Navigate to the project folder where you have created the project and create a file called GameSchema.xml with the above content.

We will not go through the details of the XML file in greater detail since it is out of the scope of this article. For the Hello World sample, we will define a game state object that we can use to share game states among all the players within a game room. We will name the class as HelloGameState, but you are welcome to call it by any name or something that makes sense to your game. You may also define as many game state classes as you like. For the HelloGameState in the schema file, each game state instance will define three properties, namely, x, y, and color.

Code generator

In order to create the AS3 class files from the schema file, you need to run the batch file called PulseCodeGen.bat found in the $\bin folder. It takes the following three parameters:

  1. Path to schema file
  2. Namespace
  3. Output directory

In order to make our life easier, let us create a batch file that will call the PulseCodeGen and pass all the required parameters. The reason for creating the batch file is that you have to code generate every time you modify the schema file. As you progress through your game implementation, it is normal to add a new class or modify an existing one.

The convenience batch file may look like what's shown next. Let's call it .init.bat and save it in the same root folder for the sample along with the schema file.

IF EXIST .\src\hw\gsrc\client del .\src\hw\gsrc\client\*.as
CALL "%GAMANTRA%"\bin\PulseCodeGen.bat .\GameSchema.xml hw.gsrc
ECHO Success!
ECHO oops!

The schema file parameter to the Pulse code generator is specified as .\GameSchema.xml because the schema file and the batch file are in the same folder. The second parameter is the package name for the generated classes—in this example, it is specified to be hw.gsrc. You specify the directory that the generated classes will be saved to as the last parameter. Note that the code generator appends client to both the package and directory into which it will be saved. It is also important to match the package name and directory structure as required by the AS3 compiler.

Upon running the code gen successfully, there is one AS3 class generated for each class in the schema file and two additional supporting class files. One is a factory class called GNetClientObjectFactory, which is responsible for creating new instances of generated classes, and the other is GNetMetaDataMgr, which aids in serializing and de-serializing the transmitting data over the network. The data carried is what resides in the instances of generated classes. You don't need to deal with these two extra classes first hand; it is mostly used by the underlying Pulse runtime system.

As for the generated classes for what is defined in the schema file, the name of the class would be identical to what is specified in the schema file plus the suffix Client. In this example, there would be a class generated with the name HelloGameStateClient.as.

Go ahead and try running the batch file called init.bat under $\samples\HelloWorld.

Project directory structure

The Hello World that is part of the Pulse package is organized into the following directory structure:

  • hw
    • gsrc
      • client
    • rsrc
    • ui

The package hw being the root package contains the main class HelloWorld.as, and the gsrc as you see contains the generated class. The rsrc folder contains the skin files, which we will discuss in more detail later in this article. The skin files in Pulse consist of three PNG files that provide all the basic buttons and background for the game. You can simply replace these PNG files with your own set, provided the individual elements with the file are of the exact dimensions and are placed at the exact same positions.

(For more resources on Flash and Games, see here.)

Introduction to PulseUI

Before we start exploring the code within Hello World, let's briefly check out the PulseUI framework. It contains numerous classes that implement the screen management for a multiplayer game. For us to leverage the PulseUI framework, we simply need to subclass and override the classes defined in the framework.

The bare minimum classes to subclass from PulseUI are:

  • PulseGame
  • Skinner
  • NewGameScreen
  • GameScreen

Screen management in PulseUI

The following figure shows you the various screens that are managed and the arrowhead shows how different screens could be navigated:

The PulseUI starts off with the login screen as one would expect for any multiplayer game. Upon successful login, we enter the lobby screen, where the player can browse through all the available rooms and join one of them. From the lobby screen, the player may also visit the registration screen or the top ten screen. The registration screen allows players to quickly register, which then provides them with a login username, password, and an avatar name. The top ten screen shows off the top ten players as well as the player's own ranking.

The PulseGame class

This class is where all the action starts for our multiplayer games. The game code must subclass the PulseGame class in order to leverage the initial set of required boot strapping. It also makes sense for our subclass to be the main class for the project, although it does not have to be.

PulseGame instantiates and holds a pointer to the GameClient to publish any action from the game client to the server. It also implements the GameClientCallback interface that implements the logic when the notifications from the server are received.

Let us now look at the methods that must be overridden. Starting with the constructor of the subclass (MyGame), you should instantiate your subclass of the skinner. The first thing that the constructor of PulseGame does is to create and init the login screen, as it will most probably be displayed right after the splash screen has done its thing.

It is important to have the static protected property defined in PulseGame s_instance set to our subclass instance of PulseGame as shown below:

public function MyGame() {
s_instance = this;
new MySkinner();

Note that we also want to call the super class's (PulseGame) constructor only after we are done with our initialization.

The reason is that PulseGame is a singleton, and there are numerous places within the framework that require access to this singleton. The previous code makes sure that the instance of our subclass is returned in all cases.

The following figure shows the methods calls stack. Important to note here is that all the methods are protected, meaning that we can customize default behavior of the class at any step on the way.

In order to provide our own customized login screen, we simply override the initLoginScreen. If we wanted something fancy during the splash, we could override the splash method. On the other hand, if we simply wanted to provide a different sprite for the splash instead of the default, we would override the getSplash method.

We could also entirely skip the splash screen by overriding the splash method and calling onSplashDone, as shown below:

protected override function splash():void {

If the splash method is completely overridden, it is the subclass's responsibility to call the onSplashDone method after the splash screen has done its thing. The default behavior of onSplashDone is simply to call the start method.

The start method then initiates the following series of method calls. First it instantiates the GameClient, the main API class of Pulse, which enables all communication with the server. This method must be overridden if the game defines a schema, which is true in most cases. The login screen is then initialized so that it can create any sprites that are needed for display, and finally makes a call to display the login screen to the player.

In the case of advanced implementation of a game, the showLogin method may be overridden to read parameters passed from the HTML embedded code into the Flash game swf. In some cases, the game may not show the login screen, but retrieve the username and session from the fl ash parameters and directly invoke the server login.

Upon the server's response to the login request, the Pulse SDK serves up a GameLoginEvent defined in the Pulse layer. The login event callback, onLogin method, is called. The login event passed in may be examined to determine if the login was successful or returned an error.

The following is the default implementation that you may find in PulseGame:

protected function onLogin(event:GameLoginEvent):void {
if ( event.isSuccess() ) {
init(); // init the game client screen
else {
var loginError:int = event.getErrorCode();
if ( loginError == GameErrors.ERR_LOGIN_FAIL ) {
// try again
else {
// Server un-available!!

We see that if the login was successful, we can continue with the initialization for the rest of the game screens. This happens in the init method. The init method first draws the outline, which serves the background for the entire game and never changes; other game screens are laid on top of the outline. The init method after drawing the outline then initializes all the other screens. The following is how the init method looks in the PulseGame class:

protected function init():void {
// Show the outline
// init other screens

Each of the init methods may be overridden to create our versions of the screen. For example, a custom lobby screen may be created by overriding the initLobbyScreen.

The outline, in addition to drawing the background, also shows the player's own avatar representation. We may provide our own implementation of the outline by simply overriding the initOutline method.

The final step of the init method is the postInit, which the subclass may override to perform any additional tasks or drawing required for the game. The default implementation of the postInit requests the server to take the player to the lobby.

Exploring the Hello World sample

In the following sections, we will explore parts of the Hello World sample, specifically dealing with the initial start-up phase.


The main class called HelloGame inherits from PulseGame, which is defined in PulseUI. In the constructor of the class, we initialize the Skinner instance that provides buttons and background for the game sample.

public function HelloGame() {
s_instance = this;
protected function initSkinner():void {
new HelloSkinner();

Since the Pulse server is capable of serving multiple games, we need to override the getGameId method and provide a string that must be unique among all the games hosted by the server.

public override function getGameId():String {
return "HelloWorld";

In order to connect to the server for sending and receiving messages, we need to create the Pulse level class instance called GameClient. To instantiate the network communication client, it also needs the instance of the generated factory class.

protected override function initNetClient():void {
var factory:GNetClientObjectFactory;
factory = new GNetClientObjectFactory();
m_netClient = new GameClient(factory, this);

In the Hello World example, we will modify only two screens—one screen where a new room is created and another the game screen. We will leave all the other screens such as lobby, high scores, and register as they are.

protected override function initNewGameScreen():void {
m_newGameScreen = new NewGameRoomScreen();
protected override function initGameScreen():void {
m_gameScreen = new HelloGameScreen();

Whenever a new game state arrives, an existing one is removed or modified, the corresponding methods on the PulseGame are invoked. Remember that this HelloGame class inherits from PulseGame, so we can simply override these methods and pass it to the game screen for update.

public override function
onNewGameState(gameState:GameStateClient):void {
(m_gameScreen as HelloGameScreen).onAddGS(gameState);
public override function
onUpdateGameState(gameState:GameStateClient):void {
(m_gameScreen as HelloGameScreen).onUpdateGS(gameState);
public override function
onRemoveGameState(gameState:GameStateClient):void {
(m_gameScreen as HelloGameScreen).onRemoveGS(gameState);

That's it for the main class! The reason why it seems so simple to write games based on PulseUI is that all the game mechanics are handled by PulseUI framework. What we are doing is simply modifying the default behavior.

The login screen

The login screen is the first screen to be shown for any multiplayer game.

It offers two buttons, one being the Guest button for which the player need not type any username or password. In this case, the player will be logged in as a guest. If the player does have a username and password, the player needs to click on the OK button after filling in the fields.

The login class allows one to customize the login screen, so the server IP does not show up in the login screen. After creating the login screen, we may simply call the showIP method and pass false. The best place to call the method is by overriding the initLoginScreen in your subclass of PulseGame class.

protected override function initLoginScreen():void {

We also need to remember to set the IP of the Pulse server. During the development phase, you may want to show the IP field, but during deployment, you may want to hide it and set the IP value programmatically.

The login method takes in the IP of the server and port. By default the IP is the localhost, but could be any IP on the Internet. The Pulse server always listens to port 2021, so the client must pass the same value. For the enterprise edition of Pulse, this port may be configured.

public function login(ip:String="",

The user name and password may be passed from user input or could be null in case the player wishes to log in as a guest.

The session ID in most cases can be passed a value of zero. The session ID is provided for advanced game portal implementation where a user gets assigned a session ID from the web portal implementation. From then on, the player may jump from one page to another, containing different games. In this case, for providing the user name and the session ID, the user need not log in every time a new game is attempted to be played.

The screen class

This is the base class for all the screen classes. It defines the bare minimum methods such as init, show, and hide. Each subclass then overrides these methods for their specific sprite management.

public class Screen extends Sprite
protected var m_showing:Boolean;
public function Screen() {
public function init():void {
public function show():void {
if ( m_showing ) {
trace("Already showing!");
m_showing = true;
public function hide():void {
if ( !m_showing ) {
trace("Already hidden!");
m_showing = false;
public function isShowing():Boolean {
return m_showing;

For each screen, the init method is called once, where the subclass may initialize any sprites it needs, ready to be displayed. The show and hide methods can be called several times during the life of the game. The show method is called when the screen is to be displayed and hide to remove it from display. All screen-swapping is done by the showScreen method in PulseGame. If there is any custom screen class (for example, a credits screen) other than those subclassed from the PulseUI framework, it is recommended that it is inherited from the screen class so as to leverage the existing screen management code.

(For more resources on Flash and Games, see here.)

The skinner class

The skinner class provides a simplistic way to change the UI specific to your game. It is meant to provide a quick way to an alternative set of UI theme. The skinner class provides the art asset for all the UI in the game except for the art required for the game itself. It provides the background and buttons sprites for the general UI. The skinner is designed to take in three PNG files, namely online.png, ui.png, and frame.png.

Outline.png provides the art that is behind everything, which means the outline is drawn first and everything else is laid on top of it. From start to finish, the outline does not change and is always seen if nothing draws to cover it.

Frame is a small section to hold various UI elements in login and new game screen. Both outline and frame are simply copied from the file and displayed as they are onto the screen.

UI.png supplies all the required buttons for all the screens except for those required specifically for the game. Once the file content is copied into memory, it cuts it up into various pieces. The position and size of each UI element is hardcoded, which means that when you want to provide your own UI, the elements must be in the same position and size as the original.

If you needed something more sophisticated, you would need to replace the skinner with your own implementation as well as with various parts of PulseUI code where this is accessed.

The outline class

As you saw in the walk-through of the PulseGame object, the outline object is the first one to be painted onto the screen.

Let us now dissect the outline class in detail. The following screenshot shows the lobby screen that lays on top of the outline. The outline class draws the following:

  • Background
  • Top-left avatar
  • Friends bar
  • Chat history
  • Chat input

All the other UI elements are laid by the lobby screen, which we will discuss shortly. Also note that the outline class is not a subclass of screen object, although it could be. The reason it does not have to be is because the outline is always present in the background as opposed to other screens, which they may show and hide many times over.

Player registration

A player may register and create an avatar right within the game. A guest player may register via the RegisterScreen. The basic information for a player to register is:

  1. Username
  2. Password
  3. Avatar name

All functionality to register a guest is already provided by the PulseUI framework. Similar to the HiScore screen, you may customize the font and color by overriding the getFormat method.

Exploring the game server deployment

Let us explore in detail some of the functionality of the game server.

Registration and login

As simple as it may sound, the login is a complicated beast. From a user experience stand point, login must be simple no matter what happens behind the scenes.

In order for new users to get into your game, there are the three essential steps:

  • Registration
  • Authentication
  • Login


Registration is the process where new users create their account name and set their password usually through a website. Although it is a common practice to implement this functionality as a web-based application, players are often allowed to register within the game. This has the advantage of players not having to go to another screen, typing in the URL, and so on. Casual players just don't have the patience.

When a new user successfully creates an account, the backend web server creates the database entry with the user name, password, and other collected information. This database is called the authentication database or Auth DB for short.

The authentication DB is then used to authenticate users during the time when players are attempting to log in to the game.

Other important information that the authentication database may store is the user's place of residence, e-mail, date of birth, etc. This data often comes from the user entry during the registration process. The other kinds of information that could be automatically collected are data such as date and time of registration, the IP from where the person is registering, etc. These data are valuable to collect in order establish trends as the game progresses in its deployment stages.

Further, the authentication DB could also keep track of the login activity. Every time a player logs in or out, a DB log is recorded along with other information such as the IP. This kind of data is helpful in discovering the user trends of your community. For example, this data can help you find out the last players activity in the week and be designated as the server update period, or if the user activity was high at certain periods of a week or day, it would allow yourself to be more cautious about server stability during these times.

The login

A login may be as simple as the client logging into the game server. It opens a network connection to the server to send the username and password. The server then verifies the username and password, and allows or denies the client to log in. This may be true during the development of the game, but when the game is deployed publicly and when a large number of people are on the game cluster, the login process soon gets complicated during a public deployment.

The client first contacts the balancer, which keeps track of all the load statistics of all the processes within the game cluster. The balancer first determines if the client is the latest release that is compatible with the server. If so, then the login process continues further.

The balancer then determines the least loaded session server. The determination of least load is a combination of the number of client connections the server is maintaining and the CPU usage of the machine.

The balancer then sends the session server's IP and port to the client for it to connect. The client then proceeds to connect to the assigned session server, which then must authenticate the username and password. There are two common schemes during the login process that the authentication could be implemented.

In the early authentication scheme, the authentication is verified before the connection to the session server is established. If the authentication passes, the login server will inform the appropriate session server to expect a login from the client. The session server will receive the username, and for additional security, a session key is also passed. This session key is also sent to the client, so when the client connects to the session server, the client sends the username and the session key for the session server to validate the connection. Notice that this scheme further splits the responsibility to another process, the login server.

In lazy authentication, the session server is responsible for initiating the authentication and either accept or deny the request. The lazy authentication is much simpler than the early authentication mechanism.

Dealing with multiple logins

The one common issue that must be dealt with in a public deployment is the issue of multiple logins. There are two options that could be implemented when a duplicate login is detected:

  1. Disallow the second login.
  2. Disconnect the first login.

Even though the first option seems simpler, it is not commonly adopted. There are two reasons why the second option is more practical and preferred. One technical reason is that sometimes there is a chance that there is a stale server session after a client crash, so the second login forces a cleanup of these stale sessions. If such a problem is present in a deployment, it should be fixed by the developer. But a more legitimate reason for opting for option two is the user behavior—a player may leave the computer without logging out of the game and may then choose to log in to the game from another place. When the player attempts to log in, the first loggedin client will be disconnected and the player can play from the other computer. A similar situation may arise even within the same computer when the user opens another browser window or tab and initiates a fresh login.

Guest logins

Guest logins are great for new players to try out without having to go through the extensive registration process. It provides an opportunity for them to explore your game very quickly.

Guests are special; they are let into the game without a login. But ultimately, and depending on the game, you would want them to register, especially for a multiplayer game. What sets multiplayer games apart from single player games is that the players are part of a community, which means that identity becomes an important aspect to players.

Players who log in as guests are restricted players in many ways; for one thing, they are seen as guests to other players, meaning they don't have a unique identity. Most often their data is not saved to the database, meaning that their high score or experience are not kept track by the server. These restrictions encourages a guest player to sign up and be an active member of your community while giving them an opportunity to experience your online game.


In this article, we got our feet wet exploring the Hello World sample. We learned how to set up the project in Flash Builder 4 and the project directory structure. We also learned how to create a game schema and how we can set up the code generator. Now we also have a handle on all the screens required for the game and how PulseUI manages it for us. Finally, we have made the first contact with the server and logged in the client.

Further resources on this subject:

You've been reading an excerpt of:

Flash 10 Multiplayer Game Essentials

Explore Title