Monday, March 1, 2010

Remote Performance Monitor II

In the previous post, we began a discussion on the XNA Framework Remote Performance Monitor. To recap, the Remote Performance Monitor exposes 2x common game code scenarios that unnecessarily generate garbage on the XNA platform:
  1. Unnecessary string object creation
  2. Unnecessary boxed value types
In the previous post, we discussed the first scenario: Unnecessary string object creation. Now, let's complete this discussion with the second scenario: Unnecessary boxed value types.

Unnecessary boxed value types
In a typical game, there are often enemies to kill, obstacles to avoid, gems to collect etc. Usually game code stores, for example, a list of enemy sprites to kill, in one collection variable:
IList<Sprite> Enemies { get; set; }
During game play, game code may need to iterate through the list of enemy sprites every single frame to invoke the Update() and/or Draw() methods accordingly. In .NET, iterating through an IList<T> can typically be done either using the for statement or the foreach.

Code Optimization Demos measure the performance of the for statement compared to the foreach: the for statement is generally more performant although the foreach statement provides better readability in code. However, if used incorrectly, the foreach statement can unnecessarily generate garbage, impact performance and potentially drop frames.

Let's check out an example using the foreach statement in more detail.
Consider the following Sprite class:
public class Sprite()
{
 public Sprite()  {}  // ctor.
 public void Update(GameTime gameTime) {}
 public void Draw(GameTime gameTime) {}
}
As above, game code may store, for example, a list of enemy sprites to kill, in one collection variable and construct the collection accordingly:
IList<Sprite> Enemies { get; set; }
Enemies = new List<Sprite>();
During game play, game code may iterate through the list of enemy sprites and update each sprite accordingly:
public void Update(GameTime gameTime)
{
 foreach (Sprite Enemy in Enemies)
 {
  Enemy.Update();
 }
}
The previous game code snippet may seem harmless enough, however, the Remote Performance Monitor reveals a single managed object allocated on the heap and a single value type is boxed every single frame. When game code executes this Update() method at 60fps then 60x value types are boxed every second:


What happened? Why is this simple game code snippet generating so much garbage?

The problem begins with our collection variable declaration: the collection is declared as an IList<T> but game code actually constructs a new List<T>.
IList<Sprite> Enemies { get; set; }
Enemies = new List<Sprite>();
The problem then manifests itself with the foreach statement: the foreach statement requires an enumerator to iterate through each enemy sprite in the list.
foreach (Sprite Enemy in Enemies)
{
 Enemy.Update();
}
In .NET, both List<T> and IList<T> implement the IEnumerable<T> interface. The IEnumerable<T> interface has one method: GetEnumerator(), which returns the enumerator required to iterate through each object in the list.

However, the implementation of the GetEnumerator() method differs between List<T> and IList<T>: List<T> GetEnumerator() method returns Enumerator<T>, which is a struct: a value type stored on the stack. Whereas IList<T> GetEnumerator() method returns IEnumerator<T>, which is an interface, a reference type stored on the heap.

Therefore the previous game code snippet initially returns an Enumerator<T>, as a value type for the List<T>, but then boxes the enumerator value type to a reference type because the collection is actually declared as an IList<T>!

Therefore, there are 2x potential solutions to resolve this issue with Unnecessary boxed value types:
  1. Update the collection variable declaration to List<T>
  2. Replace foreach with the for statement altogether

The first solution simply updates the collection variable declaration thus no boxing will be necessary:
List<Sprite> Enemies { get; set; }
Enemies = new List<Sprite>();

foreach (Sprite Enemy in Enemies)
{
 Enemy.Update();
}
The second solution simply replaces the foreach with the for statement thus no enumerator will be required:
IList<Sprite> Enemies { get; set; }
Enemies = new List<Sprite>();

for (Int32 index = 0; index < Enemies.Length; index++)
{
 Enemies[index].Update();
}
Either way, the results in the Remote Performance Monitor are the same:


To summarize, when using an object in which Enumerator<T> is a value type, like List<T>, game code can employ either the foreach or for statement and not generate garbage. When using an object in which IEnumerator<T> is a reference type, like IList<T>, the foreach statement may generate garbage whereas the for statement will not.

In conclusion, the XNA Framework Remote Performance Monitor a simple tool to detect if game code is generating garbage on the XNA platform. Typically, there are 3x static statistics that require the most attention during performance testing:
  • Managed String Objects Allocated
  • Managed Objects Allocated
  • Boxed Value Types
However, there is also one final statistic that is important to monitor: "Exceptions Thrown". In a perfect game, the "Delta" column in the Remote Performance Monitor will be zero at all times.

Monday, February 1, 2010

Remote Performance Monitor

Performance is critical in game development. In XNA, game performance will degrade if you allow garbage to be generated during game play. On Xbox 360, generating too much garbage will force full garbage collection. If garbage collection takes longer than 1/60th of a second then the game will drop frames, and the more frequently full garbage collection occurs, the more frequently the game will drop frames.

The XNA Framework Remote Performance Monitor is a simple tool that can detect if game code is generating too much garbage. Here is a common work flow to game development and performance testing using the Remote Performance Monitor:
  • Write game code on Windows
  • Test game play on Windows
  • Deploy game code to Xbox 360
  • Launch Remote Performance Monitor
  • Start game from Remote Performance Monitor
  • Monitor performance results
  • Resolve performance issues as necessary
  • Repeat process

Here is a quick tutorial on how to use the XNA Framework Remote Performance Monitor if you have never used the tool before.

There is a large source of information available on the Internet, in the form of blog posts, audio casts, articles and white papers that gives detailed analysis on all the statistics generated from the Remote Performance Monitor; from Pinned Objects to Platform Invoke Calls.

However, in my experience, there are typically 3x statistics that require the most attention during performance testing:
  • Managed String Objects Allocated
  • Managed Objects Allocated
  • Boxed Value Types

Ideally, the goal is to have the "Delta" column in the Remote Performance Monitor for these 3x statistics consistently set to zero during game play:
This ensures game code does not unnecessarily generate garbage, force full collections and drop frames.

Unfortunately, during game development on the XNA platform, there appears to be 2x common game code scenarios that cause the "Delta" column in the Remote Performance Monitor to be consistently set to values greater than zero during game play:
  1. Unnecessary string object creation
  2. Unnecessary boxed value types

Each scenario reveals game code that consistently generates too much garbage, impacts performance and has the potential to drop frames.

Let's check out each scenario in greater detail:

Unnecessary String Object Creation
In a typical game, there is often a lot of numeric data that must be displayed on screen to the player, for example: score, hi score, level, lives, bonus etc. Consequently, there are numerous game code snippets similar to the following:
public void Draw()
{
 spriteBatch.DrawString(spriteFont, score.ToString(), position, color);
}
Each time game code executes score.ToString(), the .NET Framework will allocate a single managed string object on the heap. When game code executes score.ToString() unconditionally at 60fps then 60x additional managed string objects will be allocated accordingly every second:


However, there is no reason for game code to execute score.ToString() unconditionally every single frame.

A better approach would be to create 2x variables: one variable to store the integer score value and another variable to store the equivalent string representation of the score:
private Int32 scoreValue;
private String scoreText;
Now game code would only be required to execute score.ToString() when the score actually changed:
public void Update()
{
 if (playerKilledSomething)
 {
  scoreValue += 100;
  scoreText = scoreValue.ToString();
 }
}
public void Draw()
{
 spriteBatch.DrawString(spriteFont, scoreText, position, color);
}
During a standard frame, in which the score value will not change, the "Delta" column in the Remote Performance Monitor for Managed String Objects Allocated will now be set to zero as no garbage generation occurs:


This simple approach to avoid unnecessary string creation may seem obvious, but it is surprising how many times the following game code can be found in Production:
public void Draw()
{
 spriteBatch.DrawString(spriteFont1, score.ToString(), position1, color1);
 spriteBatch.DrawString(spriteFont2, hiScore.ToString(), position2, color2);
 spriteBatch.DrawString(spriteFont3, level.ToString(), position3, color3);
 spriteBatch.DrawString(spriteFont4, lives.ToString(), position4, color4);
 spriteBatch.DrawString(spriteFont5, bonus.ToString(), position5, color5);
 // continue draw method...
}
In the next post, we will continue this discussion on the Remote Performance Monitor with unnecessary boxed value types.

Friday, January 1, 2010

Retrospective

Happy New Year! The company that I currently work for operates an agile software development process and employs SCRUM as an iterative incremental framework for managing complex work.

At the end of each Sprint cycle our team holds a Retrospective to:
  • make continuous improvements to the development process
  • reflect on the previous sprint
  • set goals for the next sprint
Therefore, I thought I would conduct a simple XNA retrospective for 2009 and set goals for 2010.

2009 Achievements
Note: purchasing and configuring Zune device outside United States is an achievement!

2010 Objectives
XNA general developmentXNA 3.1 developmentZUNE development
  • 3D graphics
  • Networking
  • Unit tests
  • Mocking
  • Physics
  • Avatar personalization
  • Xbox LIVE Party
  • Video support
  • Accelerometer
  • Touch panel
  • 3D graphics
One final goal is to become more active in the XNA Creators Club: contribute more in the forums and participate more in the playtest and review process.

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);
 }
}