Friday, December 25, 2009

First Game Publication

Season's Greetings! This year, I received a nice gift to complete 2009: the game I recently completed, Henway, was approved and published on the Indie Games area of Xbox LIVE Marketplace.

Henway: The goal is to cross the road without being killed; hence this game is based on real life.


During playtest and review, the feedback received on the XNA Creators Club was really positive and there were plenty of great ideas posted by fellow creators on the site.

Note: creators must have a Premium Membership before they can playtest and review Indie Games.

Here is a quick summary of features and updates that could potentially be added in a future release:
  • add more vehicles: trucks, buses, cyclists, motorcycles, tractors, emergency
  • add variety of squelching noises when the chicken gets run down
  • pause game when batteries removed from controller
  • use Xbox button images for quit and error popups
  • add exhaust particles for some of the vehicles
  • disable sign in guide when saving
  • disable the continue option

Tuesday, December 15, 2009

Template Method Design Pattern

In XNA, the Update() and Draw() methods are invoked, by default, 60 frames per second. During each frame, a general algorithm for both the Update() and Draw() methods could be applied in game code as follows:

Update AlgorithmDraw Algorithm
  • update input
  • update objects
  • update HUD (heads up display)
  • draw background
  • draw objects
  • draw HUD (heads up display)

Here we have defined a template for both the Update() and Draw() methods. A template is a method that defines an algorithm as a set of steps. One or more of these steps can be implemented by the main game code, or deferred to a subclass where appropriate. This ensures that the structure of the algorithm stays the same, while subclasses can provide some part of the implementation as required.

By definition, the Template Method design pattern defines the skeleton of an algorithm in an operation, deferring some steps to subclasses. Template Method lets subclasses redefine certain steps of an algorithm without changing the algorithm's structure.

Let’s complete the discussion with a simple code sample.

First, create the skeleton of an algorithm for both the Update() and Draw() methods in the main game code:
// Template method for Update.
public void Update(Microsoft.Xna.Framework.GameTime gameTime)
{
 if (IsActive)
 {
  return;
 }

 UpdateInput(gameTime); 
 UpdateObjects(gameTime);
 UpdateHUD(gameTime);
}

// Template method for Draw.
public void Draw(Microsoft.Xna.Framework.GameTime gameTime)
{
 if (IsActive)
 {
  return;
 }

 DrawBackground(); 
 DrawObjects();
 DrawHUD();
}
Next, create the steps to be implemented by the template methods in the main game code:
public virtual void UpdateInput(GameTime gameTime) {}
public virtual void UpdateObjects(GameTime gameTime) {}
public virtual void UpdateHUD(GameTime gameTime) {}

public virtual void DrawBackground() {}
public virtual void DrawObjects() {}
public virtual void DrawHUD() {}
As this is a simple example, none of the steps will be deferred to subclasses; each step would execute the same game code each frame.

However, the Template Method can be used in conjunction with the State design pattern to redefine certain steps of the algorithm without changing the algorithm’s structure.

First, define an interface to be implemented by all game state objects. This interface contains all actions that each game state object will implement. In our example, the 2x actions Update() and Draw(), are now defined as template methods; this ensures that the structure of the Update() and Draw() algorithms stays the same while subclasses can provide some part of the implementation as required:
public class AbstractGameState
{   
 protected readonly Game game;   
  
 protected AbstractGameState(Game game)   
 {   
  this.game = game;   
 }   
 public void Update(GameTime gameTime)
 {
  if (IsActive)
  {
   return;
  }

 UpdateInput(gameTime); 
 UpdateObjects(gameTime);
 UpdateHUD(gameTime);
}

public void Draw(Microsoft.Xna.Framework.GameTime gameTime)
{
 if (IsActive)
 {
  return;
 }

 DrawBackground(); 
 DrawObjects();
 DrawHUD();
}
Next, construct one concrete implementation class for each state in the game. Each step in both the Update() and Draw() template methods can now be deferred to the concrete implementation class as required.

For example, imagine the Splash Screen game state concrete implementation class is responsible for detecting the Start button press and displaying the splash screen only:
public class SplashScreenState : AbstractGameState
{
 public override void UpdateInput(GameTime gameTime)
 {
  // Detect player press Start button.
 }

 public override void DrawHUD (GameTime gameTime)
 {
  // Draw splash screen
 }
}
Note: the remaining steps in both the Update() and Draw() template methods are invoked automatically by the algorithms contained in the base game state class.

To summarize, the Template Method design pattern offers algorithm encapsulation so that subclasses can hook themselves right into a computation anytime they want.

Tuesday, December 1, 2009

Command Design Pattern

The Command design pattern encapsulates a command request as an object. In game code, an example of a command request could be a simple move command: e.g. move sprite left, right, up, down.

The Command design pattern is used to express a command request, including the method call and all of its required parameters, into a command object. The command object may then be executed immediately, queued for later use or reused to support undoable actions.

Note: the command object does not contain the functionality that is to be executed; only the information required to perform an action. The functionality is contained within a receiver object. This removes the direct link between the command object and the functionality to promote loose coupling. Finally, neither the command object nor the receiver is responsible for determining the execution of the command request; this is controlled using an invoker.

In our move sprite example above, the move command object encapsulates the method invocation to update the position of the sprite. The receiver object is the sprite itself. The invoker is input detection from the player’s controller to determine the execution of the move command request.

Initially, the thought of using the Command design pattern to move a sprite seems overkill. In game code, this can easily be accomplished using the following excerpt:
protected override void Update(Microsoft.Xna.Framework.GameTime gameTime)
{
 Single velocityX = GamePad.GetState(PlayerIndex.One).ThumbSticks.Left.X;
 Single velocityY = GamePad.GetState(PlayerIndex.One).ThumbSticks.Left.Y;
 if (velocityX == 0 && velocityY == 0)  
 {  
  return;  
 }  

 sprite.Velocity = new Vector2(velocityX, velocityY);
 sprite.Update();
}
However, by implementing the Command design pattern to move a sprite we are now able to record each move command, add to a list of move command objects, and persist to playback at a later time. This can be useful, for example, to implement a demo mode in a game. In fact, this is exactly how the game Henway employs a demo mode in the title screen. Let’s check it out:

First, define an interface to be implemented by each command object. Typically, this interface contains a single Execute() method but can be extended to support Undo() operations:
public interface ICommand
{
 void Execute();
}
Next, construct a concrete implementation class for each command object in the game. In our example there is simply one command object: MoveCommand.
public struct MoveCommand : ICommand
{
 private readonly Sprite sprite;
 private readonly Vector2 velocity;

 public MoveCommand(Sprite sprite, Vector2 velocity): this()
 {
  this.sprite = sprite;
  this.velocity = velocity;
 }

 public void Execute()
 {
  sprite.Velocity = velocity;
  sprite.Update();
 }
}
Next, construct a list of command objects. This list will record each command object as it’s created in game code and will be used to playback at a later time.
public IList<ICommand> CommandsSave { get; set; }
Note: you will also need to construct a list of integers that record the number of frames that elapse between each command object being recorded; this is required for playback mode.
public IList<Int32> CommandsDelta { get; set; }
Next, update the main game class Update() method: replace the simple sprite update above with game code that now:
  • constructs a new command object;
  • sets all required parameters;
  • executes the command;
  • records the command for later use;
protected override void Update(Microsoft.Xna.Framework.GameTime gameTime)
{
 updateFrame++;
   
 Single velocityX = GamePad.GetState(PlayerIndex.One).ThumbSticks.Left.X;
 Single velocityY = GamePad.GetState(PlayerIndex.One).ThumbSticks.Left.Y;
 if (velocityX == 0 && velocityY == 0)
 {
  return;
 }

 Vector2 velocity = new Vector2(velocityX, velocityY);
 ICommand command = new MoveCommand(sprite, velocity);
 command.Execute();

 CommandsSave.Add(command);
 CommandsDelta.Add(updateFrame);

 updateFrame = 0;
}
Finally, after all command objects have been recorded through the revised Update() method, the list of frame deltas and the list of command objects can be formatted and saved:
private void SaveCommands()
{
 for (Int32 index = 0; index < CommandsSave.Count; index++)
 {
  Int32 frame = CommandsDelta[index];

  MoveCommand command = CommandsSave[index];
  Single velocityX = ((MoveCommand)command).Velocity.X;
  Single velocityY = ((MoveCommand)command).Velocity.Y;

  String format = String.Format("{0},{1},{2}",
   frame,
   velocityX,
   velocityY,
   );

  // Persist command object data.
 }
}
Now the list of frame deltas and the list of command objects can be loaded at a later time, for example, during the title screen:
public ICommand[] Commands;
public Int32[] Frames;

private void LoadCommands()
{
 IList<String> lines = GetCommandData();

 Int32 maxCommand = lines.Count;
 Commands = new ICommand[maxCommand];
 Frames = new Int32[maxCommand];

 for (Int32 index = 0; index < maxCommand; index++)
 {
  String line = lines[index];
  String[] values = line.Split(new[] { ',' });

  Frames [index] = Convert.ToInt32(values[0]);

  Single velocityX = Convert.ToSingle(values[1]);
  Single velocityY = Convert.ToSingle(values[2]);
  Vector2 velocity = new Vector2(velocityX, velocityY);

  Commands[index] = new MoveCommand(sprite, velocity);
 } 
}
And the list of frame deltas and the list of command objects can be played back as a demo mode:
private Int32 frame = 0;
private Int32 index = 0;
private Int32 maxCommand = Commands.GetLength(0);

protected override void Update(Microsoft.Xna.Framework.GameTime gameTime)
{
 frame++;
 if (frame >= Frames[index])
 {
  frame = 0;
  Commands[index].Execute();

  index++;
  if (index >= maxCommand)
  {
   // All commands executed – stop playback.
  }
 }  
}
To summarize, the Command design pattern can be very useful in game development: by encapsulating method invocation, game code can crystallize pieces of computation so that the object invoking the computation doesn’t need to worry about how to do things; it just uses the crystallized method to get its work done.

Sunday, November 1, 2009

State Design Pattern

During its lifecycle, each game will transition through many states, for example: splash screen, title, introduction, menus, instructions, options, game play, level complete, death sequence, game over, hi scores etc

Consequently, there should be an easy mechanism to transition from one game state to another in game code. A typical approach is to construct a custom enum type in game code and set one entry for each game state:
public enum GameState
{
 SplashScreen,
 Title,
 Introduction,
 Menus,
 Instructions,
 Options,
 GamePlay,
 LevelComplete,
 DeathSequence,
 GameOver,
 HiScores
}
Therefore the game can execute state specific code depending on the current state of the custom enum type at each particular frame.

A simple example of this approach can be demonstrated in Microsoft's Mini Game Catapult. This game contains 6x states which are stored in a custom enum type, CatapultState, in game code:
public enum CatapultState 
{ 
    Rolling, 
    Firing, 
    Crash, 
    ProjectileFlying, 
    ProjectileHit,
    Reset
}
Unfortunately, the logic to execute state specific code in the Update() and Draw() methods is wrapped in a long if-elseif-else code block:
private CatapultState currentState;

if (currentState == CatapultState.Rolling)
{
}
else if (currentState == CatapultState.Firing)
{
}
else if (currentState == CatapultState.Crash)
{
}
else if (currentState == CatapultState.ProjectileFlying)
{
}
else if (currentState == CatapultState.ProjectileHit)
{
}
else if (currentState == CatapultState.Reset)
{
}
Game code that contains multiple if-elseif-else statements throughout the code base like this becomes cumbersome and error prone. Also, this approach does not scale: if 7x, 8x, 9x etc states were added to the game then this approach would become unwieldly and difficult to manage.

A cleaner approach would be to implement the State design pattern. The State design pattern allows an object, in this case our game, to alter its behavior when its internal state changes. The object will appear to change its class.

In the Catapult example, we would like to localize the behavior of each state into its own class.

First, define an interface to be implemented by all game state objects. This interface contains all actions that each game state object will implement. In our example there are 2x actions, Update() and Draw():
public abstract class AbstractGameState
{
 protected readonly Game game;

 protected AbstractGameState(Game game)
 {
  this.game = game;
 }
 public virtual void Update(Microsoft.Xna.Framework.GameTime gameTime)
 {
  // Update code common to every state.
 }
 public virtual void Draw(Microsoft.Xna.Framework.GameTime gameTime)
 {
  // Draw code common to every state.
 }
}
Next, construct one concrete implementation class for each state in the game. In our example there are 6x game state objects, thus one for each state:
public class RollingState : AbstractGameState
{
 // Rolling state specific code.
 public RollingState(Game game) : base(game) {}
 public override void Update(Microsoft.Xna.Framework.GameTime gameTime) {}
 public override void Draw(Microsoft.Xna.Framework.GameTime gameTime) {}
}
public class FiringState : AbstractGameState
{
 // Firing state specific code.
 public FiringState(Game game) : base(game) {}
 public override void Update(Microsoft.Xna.Framework.GameTime gameTime) {}
 public override void Draw(Microsoft.Xna.Framework.GameTime gameTime) {}
}
public class CrashState : AbstractGameState
{
 // Crash state specific code.
 public CrashState(Game game) : base(game) {}
 public override void Update(Microsoft.Xna.Framework.GameTime gameTime) {}
 public override void Draw(Microsoft.Xna.Framework.GameTime gameTime) {}
}
public class ProjectileFlyingState : AbstractGameState
{
 // ProjectileFlying state specific code.
 public ProjectileFlyingState(Game game) : base(game) {}
 public override void Update(Microsoft.Xna.Framework.GameTime gameTime) {}
 public override void Draw(Microsoft.Xna.Framework.GameTime gameTime) {}
}
public class ProjectileHitState : AbstractGameState
{
 // ProjectileHit state specific code.
 public ProjectileHitState(Game game) : base(game) {}
 public override void Update(Microsoft.Xna.Framework.GameTime gameTime) {}
 public override void Draw(Microsoft.Xna.Framework.GameTime gameTime) {}
}
public class ResetState : AbstractGameState
{
 // Reset state specific code.
 public ResetState(Game game) : base(game) {}
 public override void Update(Microsoft.Xna.Framework.GameTime gameTime) {}
 public override void Draw(Microsoft.Xna.Framework.GameTime gameTime) {}
}
Note: state specific code is now localized to each game state object instead of being embedded in a long if-elseif-else code block.

Next, we construct a custom enum type as before:
public enum CatapultState 
{ 
    Rolling, 
    Firing, 
    Crash, 
    ProjectileFlying, 
    ProjectileHit,
    Reset
}
But now we store a reference to the current game state in a private variable of this custom enum type in the main game class:
private CatapultState currentState;
Finallly, we create an array of AbstractGameState objects, instantiate one concrete implementation class for each state in the game and add to the array:
private AbstractGameState[] States;

protected override void Initialize()
{
 // Use reflection to determine how many states there are as
 // .NET Compact Framework does not support Enum.GetValues().
 Type type = typeof(CatapultState);
 FieldInfo[] info = type.GetFields(BindingFlags.Static | BindingFlags.Public);
 Int32 numberStates = info.Length;

 // Instantiate each game state.
 States = new AbstractGameState[numberStates];
 States[(Int32)CatapultState.Rolling] = new RollingState(this);
 States[(Int32)CatapultState.Firing] = new FiringState(this);
 States[(Int32)CatapultState.Crash] = new CrashState(this);
 States[(Int32)CatapultState.ProjectileFlying] = new ProjectileFlyingState(this);
 States[(Int32)CatapultState.ProjectileHit] = new ProjectileHitState(this);
 States[(Int32)CatapultState.Reset] = new ResetState(this);

 // Initialize current game state.
 currentState = CatapultState.Rolling;
 base.Initialize();
}
The States array will now be referenced in the main game class Update() and Draw() methods to delegate the corresponding action to the correct game state concrete implementation class:
protected override void Update(GameTime gameTime)
{
 States[(Int32)currentState].Update(gameTime);
 base.Update(gameTime);
}
protected override void Draw(GameTime gameTime)
{
 States[(Int32)currentState].Draw(gameTime);
 base.Draw(gameTime);
}
This solution is scalable: as more states are added to the game, each new game state can be added to the existing custom enum type, then simply add a new game state concrete implementation class to encapsulate all game code specific to that state.

One final note: the State design pattern can also be used in conjunction with the Device Factory. The main game class invokes the Update() and Draw() methods on the Device Factory as before:
// Game.cs
protected override void Update(Microsoft.Xna.Framework.GameTime gameTime)
{
 DeviceFactory.Update(gameTime);
 base.Update(gameTime);
}
protected override void Draw(Microsoft.Xna.Framework.GameTime gameTime)
{
 DeviceFactory.Draw(gameTime);
 base.Draw(gameTime);
}
However, each device factory method would now execute state specific code depending on the state of the game at that particular frame but now for the appropriate device:
// AbstractDeviceFactory.cs
public abstract class AbstractDeviceFactory
{
 protected readonly Game game;

 protected AbstractDeviceFactory(Game game)
 {
  this.game = game;
 }
 public virtual void Update(Microsoft.Xna.Framework.GameTime gameTime)
 {
  game.States[(Int32)game.CurrentState].Update(gameTime);
 }
 public virtual void Draw(Microsoft.Xna.Framework.GameTime gameTime)
 {
  game.States[(Int32)game.CurrentState].Draw(gameTime);
 }
}

Thursday, October 1, 2009

Device Factory

XNA 3.0 allows game development to target 3x independent devices: Windows, Xbox 360 and Zune. Consequently, Microsoft released the Platformer Starter Kit to demonstrate how a single game code base can be deployed and executed on these 3x devices independently.

The ability to target a single game code base to multiple devices creates some interesting challenges: there are elements of a game that are dependent on each target device, for example: screen resolution, input detection, frame rate, content, storage, trial mode, volume, etc.

The Platformer Starter Kit deploys the same game code on Windows and Xbox 360. However, all Zune specific game code is wrapped within the following #if-#else-#endif conditional statement:
#if ZUNE
 // Execute Zune device dependent code.
#else
 // Execute Windows / Xbox 360 code.
#endif
Game code that contains multiple #if-#else#endif conditional statements throughout the code base like this becomes cumbersome and error prone. Also, this approach does not scale: if 4x, 5x, 6x, etc devices were added to target the XNA platform, then this approach would become unwieldy and difficult to manage.

A cleaner solution would be to implement a Device Factory. Essentially, the Device Factory is an abstract base class that contains all game code common to every device, but allows device specific game code to be overridden in the concrete implementation class through polymorphism.
public abstract class AbstractDeviceFactory
{
 protected readonly Game game;

 protected AbstractDeviceFactory(Game game)
 {
  this.game = game;
 }
 public virtual void Initialize()
 {
  // Initialize code common to every device.
 }
 public virtual void LoadContent()
 {
  // LoadContent code common to every device.
 }
 public virtual void Update(Microsoft.Xna.Framework.GameTime gameTime)
 {
  // Update code common to every device.
 }
 public virtual void Draw(Microsoft.Xna.Framework.GameTime gameTime)
 {
  // Draw code common to every device.
 }

 // Properties common to every device.
}
In our example, there will be 3x device factory concrete implementation classes: Windows, Xbox 360 and Zune. Each concrete implementation class will contain all game code to target that specific device.
public class WorkDeviceFactory : AbstractDeviceFactory
{
 // Windows specific game code implementation.
 public WorkDeviceFactory(Game game) : base(game)
 {
 }

 // Override property and method implementations for Windows.
}
public class XboxDeviceFactory : AbstractDeviceFactory
{
 // Xbox 360 specific game code implementation.
 public XboxDeviceFactory(Game game) : base(game)
 {
 }

 // Override property and method implementations for Xbox 360.
}
public class ZuneDeviceFactory : AbstractDeviceFactory
{
 // Zune specific game code implementation.
 public ZuneDeviceFactory(Game game) : base(game)
 {
 }

 // Override property and method implementations for Zune.
}
The main game constructor is now responsible for creating the device factory concrete implementation for the device the game is deployed to, and this instance will be used throughout the game.
public class MyGame : Microsoft.Xna.Framework.Game
{
 public AbstractDeviceFactory DeviceFactory { get; set; }

 public MyGame()
 {
  DeviceFactory = CreateDeviceFactory();
 }

 private AbstractDeviceFactory CreateDeviceFactory()
 {
  AbstractDeviceFactory deviceFactory;
#if WINDOWS
  deviceFactory = new WorkDeviceFactory(this);
#elif XBOX
  deviceFactory = new XboxDeviceFactory(this);
#elif ZUNE
  deviceFactory = new ZuneDeviceFactory(this);
#else
  throw new NotSupportedException("Device not found");
#endif
  return deviceFactory;
 }
}
Note: there must be at least one #if-#else-#endif conditional statement to determine at runtime what device the game is being executed on.

The standard XNA methods in the main game class will be now very lean as each method will delegate the corresponding action to the device factory.
protected override void Initialize()
{
 DeviceFactory.Initialize();
 base.Initialize();
}
protected override void LoadContent()
{
 DeviceFactory.LoadContent();
 base.LoadContent();
}
protected override void Update(Microsoft.Xna.Framework.GameTime gameTime)
{
 DeviceFactory.Update(gameTime);
 base.Update(gameTime);
}
protected override void Draw(Microsoft.Xna.Framework.GameTime gameTime)
{
 DeviceFactory.Draw(gameTime);
 base.Draw(gameTime);
}
Each device factory concrete implementation will either execute device dependent game code, or simply invoke the base class where the game code is the same for all devices.

Finally, this solution is scalable: if another device is added to target the XNA platform then simply add a new device factory concrete implementation class that contains all game code specific to that device, and extend the CreateDeviceFactory() method in the main game class to target this new device.

Tuesday, September 1, 2009

First Game Completion

Recently, I completed a basic 2D game to gain more experience in end-to-end game development on the XNA platform.The game, Henway, is basically a Frogger clone. The goal is to cross the road without being killed; hence this game is based on real life.

Henway is built using content that I purchased in 2003. The game play is simple; which was important in order to concentrate on the end-to-end game development experience in XNA.










The game took about four months to write outside work hours. A further month was spent upgrading game features to comply with XNA's
best practices and
publishing requirements.

The game is available on Windows, Xbox 360 and Zune.
Click here for more information on this title.


This blog will document some of the design and performance challenges
encountered during development on the XNA platform, and game development in general. This information will be available in subsequent posts.

Saturday, August 1, 2009

SteveProXNA Introduction

Hi, I’m Steve @ StevePro Studios. SteveProXNA is my XNA creator name and Xbox gamer tag.

I've been following XNA since 2007. Recently, I completed a basic 2D game to gain more experience in end-to-end game development on the XNA platform.

This blog attempts to highlight some of the issues found during XNA game development, potential solutions to these issues, and provide a general discussion on XNA.