Thursday, September 15, 2011

XNA and Breaking into the Games Industry

The video games industry is a multi-billion dollar business. A recent analyst report suggests that the worldwide market for video games will exceed $60 billion in 2011. The report also expects the video games industry to generate more than $80 billion in 2014.

The video games industry is dynamic, innovative and exciting. Consequently, game development itself has diversified: capitalizing on digital distribution, mobile devices, new free-to-play business models, cloud gaming, next-generation game consoles and social networking sites.

Expected growth in the video games industry creates demand for talent, particularly as video games become more complex and require larger development teams. So, this all sounds great, therefore...

How do you break into the games industry?

One common theme to help break into the games industry is simple: Just do it. Go. Make Games.
Quote: if you want to make games for a living, start making them for fun now.

Making your own game shows initiative. It showcases your talent and demonstrates commitment:
That you can produce a complete game! This is where technologies like XNA can help.

XNA is an exciting technology that allows independent game code to be developed and deployed to the Windows PC, Windows Phone 7 and Xbox 360. The App Hub provides tools, information and assistance
to help create games for these devices.

Completing your own game is a rewarding achievement. Plus you create opportunities to blog about your experience and take advantage of social networking sites to: promote your work, share information and build reputation as a bone fide game developer.

In my experience, the transition from independent to professional is difficult, but not impossible.
Here are some further recommendations on how to break into the games industry:

Learn C++:
Play video games:
Focus on skillset:
Subscribe to job sites:
Follow the industry:
Join associations:
Prepare to relocate:
Recommended reading:
C++ is currently the dominant language for game development.
Play tons of games and really get to know the hardware / software.
Target your core strengths and search for jobs with the best fit.
Receive daily emails to guage trends in games skillset requirements.
Keep up-to-date with industry events and read online magazines.
E.g. IDGA / TIGA. Attend conferences and network with professionals.
Consider moving closer to games studios / games related companies.
Game Engine Architecture, Game Programming Gems, Effective C++, Game Scripting Mastery, 3D Math for Graphics / Game Development.

In conclusion, the video games industry seems poised for a bright future. New education policy, company grants and improved Research & Development tax breaks are significant for continued industry growth.

Therefore, if breaking into the games industry appeals to you then just do it. Go. Make Games.
And, of course, the best of luck to you J

Friday, April 1, 2011

XNA and Test Driven Development

In the previous post, we discussed the topic of XNA and Unit Testing.
Now, let's discuss the topic of Test Driven Development with XNA.

Note: this post includes complete code sample on CodePlex.
Download code sample here.

Test Driven Development (TDD)
Test driven development (TDD) is similar to unit testing except the unit tests are written before the objects they test. TDD is gaining as a development best practice because objects are designed with testability in mind: an object and its dependencies must be loosely coupled from the outset.

TDD practitioners follow these three laws:
First Law:
Second Law:
Third Law:
You may not write production code unless you’ve first written a failing unit test
You may not write more of a unit test than is sufficient to fail
You may not write more production code than is sufficient to make the failing unit test pass

Instead of designing a module, coding then testing, you turn the process around and do the testing first.
To put it another way, you don't write a single line of production code until you have a test that fails.

The typical programming sequence is something like this:
 1. Write a test.
 2. Run the test. It fails to compile because the code you're trying to test doesn't even exist yet!
     This is the same thing as failing.
 3. Write a bare-bones stub to make the test compile.
 4. Run the test. It should fail.  If it doesn't, then the test wasn't very good.
 5. Implement the code to make the test pass.
 6. Run the test. It should pass.  If it doesn't, back up one step and try again.
 7. Start over with a new test!

Example
As an example, let's revise the Going Beyond tutorial to demonstrate XNA and Test Driven Development.

Sample
The following code sample refactors the tutorial to move a 3D model using input from the controller.
In order to test the model's rotate and move methods in isolation, the external dependency on the controller must be broken.

Download the code sample from XNA and IoC Container post; Unit Tests will be added to this code.
However, this time the unit tests will be written before the objects they test.

First, identify the System Under Test: the component that will drive the unit tests: Game Object Manager
The Game Object Manager is responsible for managing all objects in the game: currently 1x spaceship.

Therefore, all unit tests will involve the interaction between the SpaceShip and input from the controller:
Action
Rotate Left
Rotate Right
Move Forward
Warp Center
Windows PC
Press left key
Press right key
Press space key
Press enter key
Windows Phone 7
Tap screen bottom left
Tap screen bottom right
Tap screen top right
Tap screen top left
Xbox 360
Move controller left
Move controller right
Press right trigger
Press A button

Unit Tests
Write the unit tests, one for each action: Rotate Left, Rotate Right, Move Forward and Warp Center.

First, add New Windows Game Library project to the solution; this project will contain the unit tests.
Next, add references to the following managed libraries: NUnit Framework and Rhino Mocks.

Next, add one test fixture for the system under test: Game Object Manager
Note: external dependencies are broken and replaced by mock objects:
[TestFixture]
public class GameObjectManagerTests
{
 // System under test.
 private IGameObjectManager gameObjectManager;

 private ICameraManager cameraManager;
 private IContentManager contentManager;
 private IInputManager inputManager;
 private SpaceShip spaceShip;
 private readonly GameTime gameTime = new GameTime();

 [SetUp]
 public void SetUp()
 {
  cameraManager = MockRepository.GenerateStub<ICameraManager>();
  contentManager = MockRepository.GenerateStub<IContentManager>();
  inputManager = MockRepository.GenerateStub<IInputManager>();
  spaceShip = new SpaceShip();

  gameObjectManager = new GameObjectManager(
   cameraManager,
   contentManager,
   inputManager,
   spaceShip);
 }
}
Test #1: Warp Center
  • Simulate input from the controller to return the Warp Center action
  • Update the Game Object Manager which updates the SpaceShip
  • Assert the position of the SpaceShip updates correctly
 1. Write a test.
[Test]
public void Warp()
{
 // Arrange.
 Vector3 modelPostion = new Vector3(10, 20, 30);
 spaceShip = new SpaceShip(modelPostion);

 gameObjectManager = new GameObjectManager(
  cameraManager,
  contentManager,
  inputManager,
  spaceShip);

 inputManager.Stub(im => im.Warp()).Return(true);

 // Act.
 gameObjectManager.Update(gameTime);

 // Assert.
 Assert.AreEqual(Vector3.Zero, gameObjectManager.SpaceShip.ModelPosition);
}
 2. Run the test. It fails to compile because the code you're trying to test doesn't even exist yet!
 3. Write a bare-bones stub to make the test compile.

SPACE SHIP
public class SpaceShip
{
 private Model spaceShipModel;
 private Matrix[] transforms;

 public SpaceShip() : this(Vector3.Zero)
 {
 }

 public SpaceShip(Vector3 modelPosition)
 {
  ModelRotation = 0.0f;
  ModelPosition = modelPosition;
  ModelVelocity = Vector3.Zero;
 }

 // Same code as previous post.
}
INPUT MANAGER
public class InputManager : IInputManager
{
 // InputManager has dependency on InputFactory.
 private readonly AInputFactory inputFactory;

 public InputManager(AInputFactory inputFactory)
 {
  this.inputFactory = inputFactory;
 }

 public Boolean Warp() { return inputFactory.Warp(); }
}
INPUT FACTORY
public abstract class AInputFactory
{
 public abstract Boolean Warp();
}

public class PhoneInputFactory : AInputFactory
{
 public override Boolean Warp() { // Logic goes here. }
}

public class WorkInputFactory : AInputFactory
{
 public override Boolean Warp() { // Logic goes here. }
}

public class XboxInputFactory : AInputFactory
{
 public override Boolean Warp() { // Logic goes here. }
}
GAME OBJECT MANAGER
public class GameObjectManager : IGameObjectManager
{
 // GameObjectManager has dependency on CameraManager, ContentManager, InputManager and SpaceShip.
 private readonly ICameraManager cameraManager;
 private readonly IContentManager contentManager;
 private readonly IInputManager inputManager;
 private readonly SpaceShip spaceShip;

 public GameObjectManager(ICameraManager cameraManager, IContentManager contentManager, IInputManager inputManager, SpaceShip spaceShip)
 {
  this.cameraManager = cameraManager;
  this.contentManager = contentManager;
  this.inputManager = inputManager;
  this.spaceShip = spaceShip;
 }

 // Same code as previous post.

 public SpaceShip SpaceShip { get { return spaceShip; } }
}
 4. Run the test. It should fail.
 5. Implement the code to make the test pass.

GAME OBJECT MANAGER
public class GameObjectManager : IGameObjectManager
{
 // Same code as previous post.

 // Update each game object.
 public void Update(GameTime gameTime)
 {
  Boolean warp = inputManager.Warp();
  spaceShip.Update(warp);
 }
}
SPACE SHIP
public class SpaceShip
{
 // Same code as previous post.

 // Update warp if action is invoked.
 public void Update(Boolean warp)
 {
  // Warp.
  if (warp)
  {
   ModelPosition = Vector3.Zero;
   ModelVelocity = Vector3.Zero;
   ModelRotation = 0.0f;
  }
 }
}
 6. Run the test. It should pass.
 7. Start over with a new test!

Test #2: Rotate Left
  • Simulate input from the controller to return the Rotate Left action
  • Update the Game Object Manager which updates the SpaceShip
  • Assert the rotation of the SpaceShip updates correctly
 1. Write a test.
[Test]
public void Left()
{
 // Arrange.
 inputManager.Stub(im => im.Rotate()).Return(-1);

 // Act.
 gameObjectManager.Update(gameTime);

 // Assert.
 Assert.AreEqual(0.1f, gameObjectManager.SpaceShip.ModelRotation);
}
 2. Run the test. It fails to compile because the code you're trying to test doesn't even exist yet!
 3. Write a bare-bones stub to make the test compile.

INPUT MANAGER
public class InputManager : IInputManager
{
 // InputManager has dependency on InputFactory.
 private readonly AInputFactory inputFactory;

 public InputManager(AInputFactory inputFactory)
 {
  this.inputFactory = inputFactory;
 }

 public Single Rotate() { return inputFactory.Rotate(); }
 public Boolean Warp() { return inputFactory.Warp(); }
}
INPUT FACTORY
public abstract class AInputFactory
{
 public abstract Single Rotate();
 public abstract Boolean Warp();
}

public class PhoneInputFactory : AInputFactory
{
 public override Single Rotate() { // Logic goes here. }
 public override Boolean Warp() { // Logic goes here. }
}

public class WorkInputFactory : AInputFactory
{
 public override Single Rotate() { // Logic goes here. }
 public override Boolean Warp() { // Logic goes here. }
}

public class XboxInputFactory : AInputFactory
{
 public override Single Rotate() { // Logic goes here. }
 public override Boolean Warp() { // Logic goes here. }
}
 4. Run the test. It should fail.
 5. Implement the code to make the test pass.

GAME OBJECT MANAGER
public class GameObjectManager : IGameObjectManager
{
 // Same code as previous post.

 // Update each game object.
 public void Update(GameTime gameTime)
 {
  Single rotate = inputManager.Rotate();
  Boolean warp = inputManager.Warp();

  spaceShip.Update(rotate, warp);
 }
}
SPACE SHIP
public class SpaceShip
{
 // Same code as previous post.

 // Update rotate and warp if actions are invoked.
 public void Update(Single rotate, Boolean warp)
 {
  // Rotate.
  if (rotate != 0)
  {
   const Single scale = 0.10f;
   ModelRotation -= rotate * scale;
  }

  // Warp.
  if (warp)
  {
   ModelPosition = Vector3.Zero;
   ModelVelocity = Vector3.Zero;
   ModelRotation = 0.0f;
  }
 }
}
 6. Run the test. It should pass.
 7. Start over with a new test!

Test #3: Rotate Right
  • Simulate input from the controller to return the Rotate Right action
  • Update the Game Object Manager which updates the SpaceShip
  • Assert the rotation of the SpaceShip updates correctly
 1. Write a test.
[Test]
public void Right()
{
 // Arrange.
 inputManager.Stub(im => im.Rotate()).Return(1);

 // Act.
 gameObjectManager.Update(gameTime);

 // Assert.
 Assert.AreEqual(-0.1f, gameObjectManager.SpaceShip.ModelRotation);
}
 2. Run the test. It fails to compile because the code you're trying to test doesn't even exist yet!
 3. Write a bare-bones stub to make the test compile.
 4. Run the test. It should fail.
 5. Implement the code to make the test pass.
 6. Run the test. It should pass.
 7. Start over with a new test!

Test #4: Move Forward
  • Simulate input from the controller to return the Move Forward action
  • Update the Game Object Manager which updates the SpaceShip
  • Assert the position of the SpaceShip updates correctly
 1. Write a test.
[Test]
public void Move()
{
 // Arrange.
 inputManager.Stub(im => im.Move()).Return(1);

 // Act.
 gameObjectManager.Update(gameTime);

 // Assert.
 Assert.AreEqual(-1.0f, gameObjectManager.SpaceShip.ModelPosition.Z);
}
 2. Run the test. It fails to compile because the code you're trying to test doesn't even exist yet!
 3. Write a bare-bones stub to make the test compile.

INPUT MANAGER
public class InputManager : IInputManager
{
 // InputManager has dependency on InputFactory.
 private readonly AInputFactory inputFactory;

 public InputManager(AInputFactory inputFactory)
 {
  this.inputFactory = inputFactory;
 }

 public Single Rotate() { return inputFactory.Rotate(); }
 public Single Move() { return inputFactory.Move(); }
 public Boolean Warp() { return inputFactory.Warp(); }
}
INPUT FACTORY
public abstract class AInputFactory
{
 public abstract Single Rotate();
 public abstract Single Move();
 public abstract Boolean Warp();
}

public class PhoneInputFactory : AInputFactory
{
 public override Single Rotate() { // Logic goes here. }
 public override Single Move() { // Logic goes here. }
 public override Boolean Warp() { // Logic goes here. }
}

public class WorkInputFactory : AInputFactory
{
 public override Single Rotate() { // Logic goes here. }
 public override Single Move() { // Logic goes here. }
 public override Boolean Warp() { // Logic goes here. }
}

public class XboxInputFactory : AInputFactory
{
 public override Single Rotate() { // Logic goes here. }
 public override Single Move() { // Logic goes here. }
 public override Boolean Warp() { // Logic goes here. }
}
 4. Run the test. It should fail.
 5. Implement the code to make the test pass.

GAME OBJECT MANAGER
public class GameObjectManager : IGameObjectManager
{
 // Same code as previous post.

 // Update each game object.
 public void Update(GameTime gameTime)
 {
  Single rotate = inputManager.Rotate();
  Single move = inputManager.Move();
  Boolean warp = inputManager.Warp();

  spaceShip.Update(rotate, move, warp);
 }
}
SPACE SHIP
public class SpaceShip
{
 // Same code as previous post.

 // Update rotate, move and warp if actions are invoked.
 public void Update(Single rotate, Single move, Boolean warp)
 {
  // Rotate.
  if (rotate != 0)
  {
   const Single scale = 0.10f;
   ModelRotation -= rotate * scale;
  }

  // Move.
  if (move != 0)
  {
   // Create some velocity if move action invoked.
   Vector3 modelVelocityAdd = Vector3.Zero;

   // Find out thrust direction using rotation.
   Single sin = -(Single)Math.Sin(ModelRotation);
   Single cos = -(Single)Math.Cos(ModelRotation);

   modelVelocityAdd.X = sin;
   modelVelocityAdd.Z = cos;

   // Scale direction by the amount of movement.
   modelVelocityAdd *= move;

   // Finally, add this vector to our velocity.
   ModelVelocity += modelVelocityAdd;
  }

  // Warp.
  if (warp)
  {
   ModelPosition = Vector3.Zero;
   ModelVelocity = Vector3.Zero;
   ModelRotation = 0.0f;
  }

  // Add velocity to position and bleed off velocity over time.
  ModelPosition += ModelVelocity;
  ModelVelocity *= 0.97f;
 }
}
 6. Run the test. It should pass.
 7. All tests complete!

Download code sample here.

Summary
The revised Going Beyond tutorial demonstrates how to integrate Unit Tests into an existing code base.
However, writing the unit tests before the code helps drive development of the systems under test.

In conclusion, agile software development does seem to have the potential to scale using XNA:
However, in it's current form, dependency injection may be susceptible to circular references:
  • ComponentA depends on ComponentB
  • ComponentB depends on ComponentA
A better implementation may be to construct a base class component that all subsystems inherit from;
Extract the GameManager into the base to manage interaction between all subsystems in the game:
public abstract class BaseComponent
{
 public GameManager GameManager
 {
  get { return gameManager; }
  set { if (null == gameManager) { gameManager = value;  }}
 }

 private GameManager gameManager;
}

public class ComponentA : BaseComponent
{
 public ComponentA()
 {
  PropertyA = "Hello";
 }
 public void Print()
 {
  PropertyA = GameManager.ComponentB.PropertyB;
 }

 public String PropertyA { get; private set; }
}

public class ComponentB : BaseComponent
{
 public ComponentB()
 {
  PropertyB = "World";
 }
 public void Print()
 {
  PropertyB = GameManager.ComponentA.PropertyA;
 }

 public String PropertyB { get; private set; }
}

public class GameManager
{
 public GameManager(ComponentA componentA, ComponentB componentB)
 {
  ComponentA = componentA;
  ComponentB = componentB;
 }

 public ComponentA ComponentA { get; private set; }
 public ComponentB ComponentB { get; private set; }
}
Once issues such as circular references have been resolved, then there is an opportunity to integrate more complex game code using XNA and agile software development techniques.

Thursday, March 17, 2011

XNA and Unit Testing

In the previous post, we discussed the topic of XNA and an IoC Container.
Now, let's build on this information to discuss Unit Testing with XNA.

Note: this post includes complete code sample on CodePlex.
Download code sample here.

Unit Testing
Unit testing is the practice in which individual units of source code are tested in isolation. Consequently, unit tests do not measure how objects interact with dependent objects; these are integration tests.

In order to successfully unit test an individual game component, external dependencies are broken, and replaced by mock objects: fake objects that emulate real classes and help test expectations about how that class should function.

Therefore, clean unit tests should be written F.I.R.S.T:
Fast
Independent
Repeatable
Self-validating
Timely
Tests should be fast
Tests should not depend on each other
Tests should be repeatable in any environment
Tests should have a Boolean output: either they pass or fail
Tests should be written in a timely fashion

Example
As an example, let's revise the Going Beyond tutorial to demonstrate XNA and Unit Testing.

Sample
The following code sample refactors the tutorial to move a 3D model using input from the controller.
In order to test the model's rotate and move methods in isolation, the external dependency on the controller must be broken.

Download the code sample from XNA and IoC Container post; Unit Tests will be added to this code.
Write all code changes first then add unit tests afterwards to assert the correct behavior.

First, identify the System Under Test: the component that will drive the unit tests: Game Object Manager
The Game Object Manager is responsible for managing all objects in the game: currently 1x spaceship.

Therefore, all unit tests will involve the interaction between the SpaceShip and input from the controller:
Action
Rotate Left
Rotate Right
Move Forward
Warp Center
Windows PC
Press left key
Press right key
Press space key
Press enter key
Windows Phone 7
Tap screen bottom left
Tap screen bottom right
Tap screen top right
Tap screen top left
Xbox 360
Move controller left
Move controller right
Press right trigger
Press A button

All logic to load, update and draw the model can be encapsulated into a single game object:
SPACE SHIP
public class SpaceShip
{
 private Model spaceShipModel;
 private Matrix[] transforms;

 public SpaceShip() : this(Vector3.Zero)
 {
 }

 public SpaceShip(Vector3 modelPosition)
 {
  ModelRotation = 0.0f;
  ModelPosition = modelPosition;
  ModelVelocity = Vector3.Zero;
 }

 // Load model and set view/projection matrices.
 public void LoadContent(Model theSpaceShipModel, Matrix viewMatrix, Matrix projectionMatrix)
 {
  // Same code as previous post.
 }

 // Update rotate, move and warp if actions are invoked.
 public void Update(Single rotate, Single move, Boolean warp)
 {
  // Rotate.
  if (rotate != 0)
  {
   const Single scale = 0.10f;
   ModelRotation -= rotate * scale;
  }

  // Move.
  if (move != 0)
  {
   // Create some velocity if move action invoked.
   Vector3 modelVelocityAdd = Vector3.Zero;

   // Find out thrust direction using rotation.
   Single sin = -(Single)Math.Sin(ModelRotation);
   Single cos = -(Single)Math.Cos(ModelRotation);

   modelVelocityAdd.X = sin;
   modelVelocityAdd.Z = cos;

   // Scale direction by the amount of movement.
   modelVelocityAdd *= move;

   // Finally, add this vector to our velocity.
   ModelVelocity += modelVelocityAdd;
  }

  // Warp.
  if (warp)
  {
   ModelPosition = Vector3.Zero;
   ModelVelocity = Vector3.Zero;
   ModelRotation = 0.0f;
  }

  // Add velocity to position and bleed off velocity over time.
  ModelPosition += ModelVelocity;
  ModelVelocity *= 0.97f;
 }

 // Draw model.
 public void Draw()
 {
  // Same code as previous post.
 }

 public Single ModelRotation { get; private set; }
 public virtual Vector3 ModelPosition { get; private set; }
 public Vector3 ModelVelocity { get; private set; }
}
Next, update the Game Object Manager: detect input and set the rotate, move and warp values:
GAME OBJECT MANAGER
public class GameObjectManager : IGameObjectManager
{
 // GameObjectManager has dependency on CameraManager, ContentManager, InputManager and SpaceShip.
 private readonly ICameraManager cameraManager;
 private readonly IContentManager contentManager;
 private readonly IInputManager inputManager;
 private readonly SpaceShip spaceShip;

 public GameObjectManager(ICameraManager cameraManager, IContentManager contentManager, IInputManager inputManager, SpaceShip spaceShip)
 {
  this.cameraManager = cameraManager;
  this.contentManager = contentManager;
  this.inputManager = inputManager;
  this.spaceShip = spaceShip;
 }

 // Load content for each game object.
 public void LoadContent()
 {
  spaceShip.LoadContent(contentManager.SpaceShipModel, cameraManager.ViewMatrix, cameraManager.ProjectionMatrix);
 }

 // Update each game object.
 public void Update(GameTime gameTime)
 {
  Single rotate = inputManager.Rotate();
  Single move = inputManager.Move();
  Boolean warp = inputManager.Warp();

  spaceShip.Update(rotate, move, warp);
 }

 // Draw each game object.
 public void Draw()
 {
  spaceShip.Draw();
 }

 public SpaceShip SpaceShip { get { return spaceShip; } }
}
Finally, input detection: each device will have its own rotate, move and warp implementation:
INPUT MANAGER
public class InputManager : IInputManager
{
 // InputManager has dependency on InputFactory.
 private readonly AInputFactory inputFactory;

 public InputManager(AInputFactory inputFactory)
 {
  this.inputFactory = inputFactory;
 }

 public Single Rotate() { return inputFactory.Rotate(); }
 public Single Move() { return inputFactory.Move(); }
 public Boolean Warp() { return inputFactory.Warp(); }
}
INPUT FACTORY
public abstract class AInputFactory
{
 public abstract Single Rotate();
 public abstract Single Move();
 public abstract Boolean Warp();
}

public class PhoneInputFactory : AInputFactory
{
 public override Single Rotate() { // Logic goes here. }
 public override Single Move() { // Logic goes here. }
 public override Boolean Warp() { // Logic goes here. }
}

public class WorkInputFactory : AInputFactory
{
 public override Single Rotate() { // Logic goes here. }
 public override Single Move() { // Logic goes here. }
 public override Boolean Warp() { // Logic goes here. }
}

public class XboxInputFactory : AInputFactory
{
 public override Single Rotate() { // Logic goes here. }
 public override Single Move() { // Logic goes here. }
 public override Boolean Warp() { // Logic goes here. }
}

Unit Tests
Write the unit tests, one for each action: Rotate Left, Rotate Right, Move Forward and Warp Center.

First, add New Windows Game Library project to the solution; this project will contain the unit tests.
Next, add references to the following managed libraries: NUnit Framework and Rhino Mocks.

Next, add one test fixture for the system under test: Game Object Manager
Note: external dependencies are broken and replaced by mock objects:
[TestFixture]
public class GameObjectManagerTests
{
 // System under test.
 private IGameObjectManager gameObjectManager;

 private ICameraManager cameraManager;
 private IContentManager contentManager;
 private IInputManager inputManager;
 private SpaceShip spaceShip;
 private readonly GameTime gameTime = new GameTime();

 [SetUp]
 public void SetUp()
 {
  cameraManager = MockRepository.GenerateStub<ICameraManager>();
  contentManager = MockRepository.GenerateStub<IContentManager>();
  inputManager = MockRepository.GenerateStub<IInputManager>();
  spaceShip = new SpaceShip();

  gameObjectManager = new GameObjectManager(
   cameraManager,
   contentManager,
   inputManager,
   spaceShip);
 }
}
Test #1: Rotate Left
  • Simulate input from the controller to return the Rotate Left action
  • Update the Game Object Manager which updates the SpaceShip
  • Assert the rotation of the SpaceShip updates correctly
[Test]
public void Left()
{
 // Arrange.
 inputManager.Stub(im => im.Rotate()).Return(-1);

 // Act.
 gameObjectManager.Update(gameTime);

 // Assert.
 Assert.AreEqual(0.1f, gameObjectManager.SpaceShip.ModelRotation);
}
Test #2: Rotate Right
  • Simulate input from the controller to return the Rotate Right action
  • Update the Game Object Manager which updates the SpaceShip
  • Assert the rotation of the SpaceShip updates correctly
[Test]
public void Right()
{
 // Arrange.
 inputManager.Stub(im => im.Rotate()).Return(1);

 // Act.
 gameObjectManager.Update(gameTime);

 // Assert.
 Assert.AreEqual(-0.1f, gameObjectManager.SpaceShip.ModelRotation);
}
Test #3: Move Forward
  • Simulate input from the controller to return the Move Forward action
  • Update the Game Object Manager which updates the SpaceShip
  • Assert the position of the SpaceShip updates correctly
[Test]
public void Move()
{
 // Arrange.
 inputManager.Stub(im => im.Move()).Return(1);

 // Act.
 gameObjectManager.Update(gameTime);

 // Assert.
 Assert.AreEqual(-1.0f, gameObjectManager.SpaceShip.ModelPosition.Z);
}
Test #4: Warp Center
  • Simulate input from the controller to return the Warp Center action
  • Update the Game Object Manager which updates the SpaceShip
  • Assert the position of the SpaceShip updates correctly
[Test]
public void Warp()
{
 // Arrange.
 Vector3 modelPostion = new Vector3(10, 20, 30);
 spaceShip = new SpaceShip(modelPostion);

 gameObjectManager = new GameObjectManager(
  cameraManager,
  contentManager,
  inputManager,
  spaceShip);

 inputManager.Stub(im => im.Warp()).Return(true);

 // Act.
 gameObjectManager.Update(gameTime);

 // Assert.
 Assert.AreEqual(Vector3.Zero, gameObjectManager.SpaceShip.ModelPosition);
}
Download code sample here.

Summary
The revised Going Beyond tutorial demonstrates how to integrate Unit Tests into an existing code base.
However, simply adding unit tests after the code is written does not guarantee bug free code!

For example: subtle bugs may be introduced in code that are not caught when tested in isolation simply because the tests may return false positive results.

Unit tests state what you expect the code to do. Therefore, a better approach is to write the tests first: Writing the test before the code should uncover issues quicker because assertions in the test can fail.

The practice of writing unit tests before the objects they test is called: Test Driven Development.
This will be the topic in the next post.

Tuesday, March 1, 2011

XNA and an IoC Container

In the previous post, we discussed the topic of XNA and Dependency Injection.
Now, let's build on this information to discuss an IoC Container with XNA.

Note: this post includes complete code sample on CodePlex.
Download code sample here.

IoC Container
An IoC Container is a framework component that automatically resolves all dependent references for an object: when an object is constructed, the container will instantiate all dependent objects automatically and injects them into the source object accordingly.

There are many IoC containers available to .NET developers:
However, Ninject is currently the only IoC container that is compatible with the .NET Compact Framework and will work on Windows Phone 7 and Xbox 360.

Example
As an example, let's revise the Going Beyond tutorial to demonstrate XNA and an IoC Container.

Sample
Download the code sample from the previous post; the IoC Container will be added to this code.
All logic to resolve dependent component references can be encapulated into a single object:

IOC CONTAINER
public static class IoCContainer
{
 private static IKernel kernel;

 public static T Resolve<T>()
 {
  if (null == kernel)
  {
   INinjectModule staticModule = new StaticModule();
   INinjectModule[] modules = new[] { staticModule };

   kernel = new StandardKernel(modules);
  }

  return kernel.Get<T>();
 }

 public static void Release()
 {
  if (null == kernel)
  {
   return;
  }

  kernel.Dispose();
  kernel = null;
 }
}
Next, build a module to configure the bindings and manage the lifetime of all component references:
STATIC MODULE
public class StaticModule : NinjectModule
{
 public override void Load()
 {
  Bind<IGameManager>().To<GameManager>().InSingletonScope();
  Bind<ICameraManager>().To<CameraManager>().InSingletonScope();
  Bind<IContentManager>().To<ContentManager>().InSingletonScope();
  Bind<IGameObjectManager>().To<GameObjectManager>().InSingletonScope();
  Bind<IGraphicsManager>().To<GraphicsManager>().InSingletonScope();
  Bind<IScreenManager>().To<ScreenManager>().InSingletonScope();
 }
}
Next, invoke the IoC Container to construct a single instance of the GameManager component:
GAME FACTORY
public static class GameFactory
{
 private static IGameManager gameManager;

 public static IGameManager GetGameManager()
 {
  return gameManager ?? (gameManager = IoCContainer.Resolve<IGameManager>());
 }

 public static void Release()
 {
  IoCContainer.Release();
 }
}
Finally, dispose of the IoC Container when the game exits:
GAME MANAGER
public class GameManager : IGameManager
{
 // Same code as previous post.

 // Exit game.
 public void Exit()
 {
  GameFactory.Release();
 }
}
GAME
public class MyGame : Game
{
 // Same code as previous post.

 protected override void OnExiting(object sender, EventArgs args)
 {
  gameManager.Exit();
  base.OnExiting(sender, args);
 }
}
Execute the updated game code: the output should be identical to the previous post.

Device Factory
In an older post, we discussed the topic of 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.

Let's complete the sample by extending the current code base to target all devices currently available in
XNA 4.0: Windows PC, Windows Phone 7 and Xbox 360.

First, build the Device Factory abstract base class and all concrete implementation classes:
DEVICE FACTORY
public abstract class ADeviceFactory
{
 // GraphicsManager.
 public Int32 PreferredBackBufferWidth { get; protected set; }
 public Int32 PreferredBackBufferHeight { get; protected set; }
 public Boolean IsFullScreen { get; protected set; }

 // ContentManager.
 public String RootDirectory { get; protected set; }
}

public class PhoneDeviceFactory : ADeviceFactory
{
 public PhoneDeviceFactory()
 {
  PreferredBackBufferWidth = 800;
  PreferredBackBufferHeight = 480;
  IsFullScreen = true;
  RootDirectory = "Content";
 }
}

public class WorkDeviceFactory : ADeviceFactory
{
 public WorkDeviceFactory()
 {
  PreferredBackBufferWidth = 1280;
  PreferredBackBufferHeight = 720;
  IsFullScreen = false;
  RootDirectory = "Content";
 }
}

public class XboxDeviceFactory : ADeviceFactory
{
 public XboxDeviceFactory()
 {
  PreferredBackBufferWidth = 1280;
  PreferredBackBufferHeight = 720;
  IsFullScreen = false;
  RootDirectory = "Content";
 }
}
Next, build a Device Manager to delegate all work to the Device Factory:
DEVICE MANAGER
public class DeviceManager : IDeviceManager
{
 // DeviceManager has dependency on DeviceFactory.
 private readonly ADeviceFactory deviceFactory;

 public DeviceManager(ADeviceFactory deviceFactory)
 {
  this.deviceFactory = deviceFactory;
 }

 public ADeviceFactory DeviceFactory
 {
  get { return deviceFactory; }
 }
}
Note: build an Input Factory and Input Manager; these will be placeholders available for future posts:
INPUT FACTORY
public abstract class AInputFactory
{
}
public class PhoneInputFactory : AInputFactory
{
}
public class WorkInputFactory : AInputFactory
{
}
public class XboxInputFactory : AInputFactory
{
}
INPUT MANAGER
public class InputManager : IInputManager
{
}
Next, build a module to configure the bindings and manage the lifetime of all device specific components:
DYNAMIC MODULE
 public class DynamicModule : NinjectModule
 {
  public override void Load()
  {
#if WINDOWS_PHONE
   Bind<ADeviceFactory>().To<PhoneDeviceFactory>().InSingletonScope();
   Bind<AInputFactory>().To<PhoneInputFactory>().InSingletonScope();
#elif WINDOWS
   Bind<ADeviceFactory>().To<WorkDeviceFactory>().InSingletonScope();
   Bind<AInputFactory>().To<WorkInputFactory>().InSingletonScope();
#elif XBOX
   Bind<ADeviceFactory>().To<XboxDeviceFactory>().InSingletonScope();
   Bind<AInputFactory>().To<XboxInputFactory>().InSingletonScope();
#else
   throw new ArgumentOutOfRangeException("DynamicModule");
#endif
  }
 }
Next, update the IoC Container:
IOC CONTAINER
public static class IoCContainer
{
 private static IKernel kernel;

 public static T Resolve()
 {
  if (null == kernel)
  {
   INinjectModule staticModule = new StaticModule();
   INinjectModule dynamicModule = new DynamicModule();

   INinjectModule[] modules = new[] { staticModule, dynamicModule };
   kernel = new StandardKernel(modules);
  }

  return kernel.Get();
 }

 public static void Release()
 {
  if (null == kernel)
  {
   return;
  }

  kernel.Dispose();
  kernel = null;
 }
}
Finally, inject all device specific components using constructor injection technique:
CONTENT MANAGER
public class ContentManager : IContentManager
{
 // ContentManager has dependency on DeviceManager.
 private readonly IDeviceManager deviceManager;
 private XnaContentManager content;

 public ContentManager(IDeviceManager deviceManager)
 {
  this.deviceManager = deviceManager;
 }

 // Load all content.
 public void LoadContent(XnaContentManager xnaContent)
 {
  if (null != content)
  {
   return;
  }

  content = xnaContent;
  content.RootDirectory = deviceManager.DeviceFactory.RootDirectory;
  SpaceShipModel = content.Load<Model>("Models/p1_wedge");
 }

 // Unload all content.
 public void UnloadContent()
 {
  if (null == content)
  {
   return;
  }

  content.Unload();
 }

 public Model SpaceShipModel { get; private set; }
}
GRAPHICS MANAGER
public class GraphicsManager : IGraphicsManager
{
 // GraphicsManager has dependency on DeviceManager.
 private readonly IDeviceManager deviceManager;
 private XnaGraphicsDeviceManager graphics;

 public GraphicsManager(IDeviceManager deviceManager)
 {
  this.deviceManager = deviceManager;
 }

 // Initialize all graphics properties.
 public void Initialize(XnaGraphicsDeviceManager xnaGraphics)
 {
  if (null != graphics)
  {
   return;
  }

  graphics = xnaGraphics;
  graphics.PreferredBackBufferWidth = deviceManager.DeviceFactory.PreferredBackBufferWidth;
  graphics.PreferredBackBufferHeight = deviceManager.DeviceFactory.PreferredBackBufferHeight;
  graphics.IsFullScreen = deviceManager.DeviceFactory.IsFullScreen;
  graphics.ApplyChanges();

  GraphicsDevice = graphics.GraphicsDevice;
  SpriteBatch = new SpriteBatch(GraphicsDevice);
 }

 public GraphicsDevice GraphicsDevice { get; private set; }
 public Single AspectRatio { get { return GraphicsDevice.Viewport.AspectRatio; } }
 public SpriteBatch SpriteBatch { get; private set; }
}
Download code sample here.

Summary
The revised Going Beyond example demonstrates how to add an IoC Container to an existing code base. Once the bindings for each game component have been configured, the IoC Container will automatically resolve all dependent references for an object.

Therefore, the code base is now in a testable state: each game component is now able to be tested in isolation: Unit Testing. This will be the topic in the next post.

Monday, February 14, 2011

XNA and Dependency Injection

In the previous post, we discussed the topic of XNA and Agile Software Development.
Now, let's build on this information to discuss Dependency Injection with XNA.

Note: this post includes complete code sample on CodePlex.
Download code sample here.

Dependency Injection
Dependency Injection is a simple pattern to loosely couple objects and break their dependencies.
The resulting design principle, Dependency Inversion, states: Depend upon abstractions.
Do not depend upon concrete classes.


By coupling an object to an interface instead of a specific concrete implementation, you have the ability to use any implementation with minimal change and risk. This concept is important, especially when testing an object in isolation (unit testing).

Example
As an example, let's revise the Going Beyond tutorial to demonstrate XNA and Dependency Injection.

First, isolate the components used throughout the tutorial:
Component
CameraManager
ContentManager
GameObjectManager
GraphicsManager
ScreenManager
Responsibility
manages fixed camera
manages all game content
manages all game objects
manages all graphics
manages all screens
Information
view / projection matrices
currently only 1x model
currently only 1x spaceship
all graphics properties
currently only 1x screen

Next, identify the dependencies between the components:
Component
CameraManager
GameObjectManager
GameObjectManager
ScreenManager
ScreenManager
Dependency
depends on GraphicsManager
depends on CameraManager
depends on ContentManager
depends on GameObjectManager
depends on GraphicsManager
Information
aspect ratio on graphics device
game object view / projection
load game object content
update / draw game objects
clear graphics device

Sample
The following code sample refactors the Going Beyond tutorial to render a 3D model on screen.
All logic to load, update and draw the model can be encapsulated into a single game object:

SPACE SHIP
public class SpaceShip
{
 private Model spaceShipModel;
 private Matrix[] transforms;

 public SpaceShip()
 {
  ModelRotation = 0.0f;
  ModelPosition = Vector3.Zero;
  ModelVelocity = Vector3.Zero;
 }

 // Load model and set view/projection matrices.
 public void LoadContent(Model theSpaceShipModel, Matrix viewMatrix, Matrix projectionMatrix)
 {
  spaceShipModel = theSpaceShipModel;
  transforms = new Matrix[spaceShipModel.Bones.Count];
  spaceShipModel.CopyAbsoluteBoneTransformsTo(transforms);

  foreach (BasicEffect effect in spaceShipModel.Meshes.SelectMany(mesh => mesh.Effects.Cast<BasicEffect>()))
  {
   effect.EnableDefaultLighting();
   effect.View = viewMatrix;
   effect.Projection = projectionMatrix;
  }
 }

 // Update angle of rotation.
 public void Update(GameTime gameTime)
 {
  Single temps = MathHelper.ToRadians(0.05f);
  Single delta = (Single)gameTime.ElapsedGameTime.TotalMilliseconds;
  ModelRotation -= delta * temps;
 }

 // Draw model.
 public void Draw()
 {
  foreach (ModelMesh mesh in spaceShipModel.Meshes)
  {
   foreach (BasicEffect effect in mesh.Effects)
   {
    effect.World = transforms[mesh.ParentBone.Index]
     * Matrix.CreateRotationY(ModelRotation)
     * Matrix.CreateTranslation(ModelPosition);
   }

   mesh.Draw();
  }
 }

 public Single ModelRotation { get; private set; }
 public Vector3 ModelPosition { get; private set; }
 public Vector3 ModelVelocity { get; private set; }
}
Next, build the components that do not have any dependencies:
CONTENT MANAGER
using XnaContentManager = Microsoft.Xna.Framework.Content.ContentManager;

public class ContentManager : IContentManager
{
 private XnaContentManager content;

 // Load all content.
 public void LoadContent(XnaContentManager xnaContent)
 {
  if (null != content)
  {
   return;
  }

  content = xnaContent;
  content.RootDirectory = "Content";
  SpaceShipModel = content.Load<Model>("Models/p1_wedge");
 }

 // Unload all content.
 public void UnloadContent()
 {
  if (null == content)
  {
   return;
  }

  content.Unload();
 }

 public Model SpaceShipModel { get; private set; }
}
GRAPHICS MANAGER
using XnaGraphicsDeviceManager = Microsoft.Xna.Framework.GraphicsDeviceManager;

public class GraphicsManager : IGraphicsManager
{
 private XnaGraphicsDeviceManager graphics;

 // Initialize all graphics properties.
 public void Initialize(XnaGraphicsDeviceManager xnaGraphics)
 {
  if (null != graphics)
  {
   return;
  }

  graphics = xnaGraphics;
  graphics.PreferredBackBufferWidth = 800;
  graphics.PreferredBackBufferHeight = 480;
  graphics.IsFullScreen = false;
  graphics.ApplyChanges();

  GraphicsDevice = graphics.GraphicsDevice;
  SpriteBatch = new SpriteBatch(GraphicsDevice);
 }

 public GraphicsDevice GraphicsDevice { get; private set; }
 public Single AspectRatio { get { return GraphicsDevice.Viewport.AspectRatio; } }
 public SpriteBatch SpriteBatch { get; private set; }
} 
Next, build the the remaining components that do have dependencies; here each dependent component is injected manually using constructor injection technique:

CAMERA MANAGER
public class CameraManager : ICameraManager
{
 // CameraManager has dependency on GraphicsManager.
 private readonly IGraphicsManager graphicsManager;

 public CameraManager(IGraphicsManager graphicsManager)
 {
  this.graphicsManager = graphicsManager;
 }

 // Initialize camera view/projection matrices.
 public void Initialize(Vector3 cameraPosition)
 {
  ViewMatrix = Matrix.CreateLookAt(cameraPosition, Vector3.Zero, Vector3.Up);
  ProjectionMatrix = Matrix.CreatePerspectiveFieldOfView(MathHelper.PiOver4, graphicsManager.AspectRatio, 1.0f, 10000.0f);
 }

 public Matrix ViewMatrix { get; private set; }
 public Matrix ProjectionMatrix { get; private set; }
}
GAME OBJECT MANAGER
public class GameObjectManager : IGameObjectManager
{
 // GameObjectManager has dependency on CameraManager and ContentManager.
 private readonly ICameraManager cameraManager;
 private readonly IContentManager contentManager;
 private readonly SpaceShip spaceShip;

 public GameObjectManager(ICameraManager cameraManager, IContentManager contentManager)
 {
  this.cameraManager = cameraManager;
  this.contentManager = contentManager;
  spaceShip = new SpaceShip();
 }

 // Load content for each game object.
 public void LoadContent()
 {
  spaceShip.LoadContent(contentManager.SpaceShipModel, cameraManager.ViewMatrix, cameraManager.ProjectionMatrix);
 }

 // Update each game object.
 public void Update(GameTime gameTime)
 {
  spaceShip.Update(gameTime);
 }

 // Draw each game object.
 public void Draw()
 {
  spaceShip.Draw();
 }
}
SCREEN MANAGER
public class ScreenManager : IScreenManager
{
 // ScreenManager has dependency on GameObjectManager and GraphicsManager.
 private readonly IGameObjectManager gameObjectManager;
 private readonly IGraphicsManager graphicsManager;

 public ScreenManager(IGameObjectManager gameObjectManager, IGraphicsManager graphicsManager)
 {
  this.gameObjectManager = gameObjectManager;
  this.graphicsManager = graphicsManager;
 }

 // Update each game object using GameObjectManager.
 public void Update(GameTime gameTime)
 {
  gameObjectManager.Update(gameTime);
 }

 // Draw each game object using GameObjectManager.
 public void Draw()
 {
  graphicsManager.GraphicsDevice.Clear(Color.Black);
  gameObjectManager.Draw();
 }
}
Finally, build a GameManager component to manage all interaction between the main game class and each game component listed above. Again, each dependent component is injected manually using constructor injection technique:

GAME MANAGER
public class GameManager : IGameManager
{
 private readonly ICameraManager cameraManager;
 private readonly IContentManager contentManager;
 private readonly IGameObjectManager gameObjectManager;
 private readonly IGraphicsManager graphicsManager;
 private readonly IScreenManager screenManager;

 public GameManager(
  ICameraManager cameraManager,
  IContentManager contentManager,
  IGameObjectManager gameObjectManager,
  IGraphicsManager graphicsManager,
  IScreenManager screenManager
  )
 {
  this.cameraManager = cameraManager;
  this.contentManager = contentManager;
  this.gameObjectManager = gameObjectManager;
  this.graphicsManager = graphicsManager;
  this.screenManager = screenManager;
 }

 // Initialize graphics and camera.
 public void Initialize(GraphicsDeviceManager graphics)
 {
  graphicsManager.Initialize(graphics);
  cameraManager.Initialize(new Vector3(0.0f, 50.0f, 5000.0f));
 }

 // Load all content.
 public void LoadContent(XnaContentManager content)
 {
  contentManager.LoadContent(content);
  gameObjectManager.LoadContent();
 }

 // Unload all content.
 public void UnloadContent()
 {
  contentManager.UnloadContent();
 }

 // Update each screen.
 public void Update(GameTime gameTime)
 {
  screenManager.Update(gameTime);
 }

 // Draw each screen.
 public void Draw()
 {
  screenManager.Draw();
 }
}
For simplicity, build a GameFactory to construct a single instance of the GameMananger component:
GAME FACTORY
public static class GameFactory
{
 private static IGameManager gameManager;

 public static IGameManager GetGameManager()
 {
  if (null == gameManager)
  {
   IContentManager contentManager = new ContentManager();
   IGraphicsManager graphicsManager = new GraphicsManager();
   ICameraManager cameraManager = new CameraManager(graphicsManager);
   IGameObjectManager gameObjectManager = new GameObjectManager(cameraManager, contentManager);
   IScreenManager screenManager = new ScreenManager(gameObjectManager, graphicsManager);

   gameManager = new GameManager(
    cameraManager,
    contentManager,
    gameObjectManager,
    graphicsManager,
    screenManager
    );
  }

  return gameManager;
 }
}
For completeness, here is the main game class; the GameManager now manages all game actions:
GAME
public class MyGame : Game
{
 private readonly GraphicsDeviceManager graphics;
 private readonly IGameManager gameManager;

 public MyGame()
 {
  graphics = new GraphicsDeviceManager(this);
  gameManager = GameFactory.GetGameManager();
 }

 protected override void Initialize()
 {
  gameManager.Initialize(graphics);
  base.Initialize();
 }

 protected override void LoadContent()
 {
  gameManager.LoadContent(Content);
  base.LoadContent();
 }

 protected override void UnloadContent()
 {
  gameManager.UnloadContent();
  base.UnloadContent();
 }

 protected override void Update(GameTime gameTime)
 {
  if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed ||
   Keyboard.GetState().IsKeyDown(Keys.Escape))
  {
   Exit();
  }
  gameManager.Update(gameTime);
  base.Update(gameTime);
 }

 protected override void Draw(GameTime gameTime)
 {
  gameManager.Draw();
  base.Draw(gameTime);
 }
}
Download code sample here.

Summary
The revised Going Beyond example demonstrates how to isolate components using dependency injection:
Game components are able to be tested in isolation as dependencies can be replaced by mock objects.

The biggest drawback from the code sample above, however, is that all dependent components must be constructed manually in the factory before they can be injected.

Fortunately, there is a framework component available to developers that resolves this issue:
The IoC Container. This will be the topic in the next post.

Tuesday, February 1, 2011

XNA and Agile Software Development

Agile development is a modern approach to software engineering that provides an iterative incremental framework for managing complex work. Efficiency is key: by minimizing rework and debugging, teams can more rapidly respond to changing business requirements and improve quality at the same time.

Game development, by nature, is complex and has many specialized disciplines:
  • Core Systems: engine configuration, math library, localization
  • Resources (Game Assets): audio, fonts, models, textures
  • Human Input Devices (HID): input detection
  • Collision & Physics: rigid bodies
  • Online Multiplayer: networking
  • Front End: heads-up display, in-game menus, visual effects
  • Game Play Foundations: event messaging, finite state machine
  • Game Specific Subsystems: rendering, player mechanics, cameras, AI
Therefore, each game may have many components working together and subsystems interacting with one another, many of which may depend on other components and subsystems too.

Consequently, the task of coding and testing game components in isolation can be very challenging due to the tightly coupled nature of these dependencies.

Example
Asteroids: in this simple game, the player controls a spaceship depending on input from the controller.
In order to test the spaceship's rotate and move methods in isolation, the external dependency on the controller must be broken.

Dependency Injection and Inversion of Control (IoC)
When an object instantiates another object that it depends on then this leads to poor design because it promotes tight coupling between the objects. Tightly coupled code cannot be changed easily without consequences: changes made to one object may cause other objects to break.

A better approach is to break dependencies between objects and promote loose coupling:
Loose coupling leads to better design as the software is less likely to break.

Dependency Injection is a simple pattern to loosely couple objects and break their dependencies.
The resulting design principle, Dependency Inversion, states: Depend upon abstractions.
Do not depend upon concrete classes.


By coupling an object to an interface instead of a specific concrete implementation, you have the ability to use any implementation with minimal change and risk. This concept is important, especially when testing an object in isolation (unit testing).

Inversion of Control (IoC) is a framework characteristic whereby objects, which depend on other objects, do not need to instantiate those objects; instead they get the objects they need from an external source.

IoC Container
An IoC Container is a framework component that automatically resolves all dependent references for an object: when an object is constructed, the container will instantiate all dependent objects automatically and injects them into the source object accordingly.

There are many IoC containers available to .NET developers:
However, Ninject is currently the only IoC container that is compatible with the .NET Compact Framework and will work on Windows Phone 7 and Xbox 360.

Unit Testing
Unit testing is the practice in which individual units of source code are tested in isolation. Consequently, unit tests do not measure how objects interact with dependent objects; these are integration tests.

In order to successfully unit test an individual game component, external dependencies are broken, and replaced by mock objects: fake objects that emulate real classes and help test expectations about how that class should function.

Therefore, clean unit tests should be written F.I.R.S.T:
Fast
Independent
Repeatable
Self-validating
Timely
Tests should be fast
Tests should not depend on each other
Tests should be repeatable in any environment
Tests should have a Boolean output: either they pass or fail
Tests should be written in a timely fashion

Test Driven Development (TDD)
Test driven development (TDD) is similar to unit testing except the unit tests are written before the objects they test. TDD is gaining as a development best practice because objects are designed with testability in mind: an object and its dependencies must be loosely coupled from the outset.

TDD practitioners follow these three laws:
First Law:
Second Law:
Third Law:
You may not write production code unless you’ve first written a failing unit test
You may not write more of a unit test than is sufficient to fail
You may not write more production code than is sufficient to make the failing unit test pass

Extreme Programming
Extreme Programming is a method of agile software development which advocates frequent releases with short development cycles. The focus on delivering business value within each iteration leads to increased quality and lower overall total cost.

Therefore, it seems only relevant to try and integrate agile methodologies into XNA game development. As an exercise, I would like to prototype the following agile techniques accordingly:
In conclusion, it will be interesting to see if agile development has the potential to scale using XNA!

Saturday, January 1, 2011

Retrospective II

Last year, I conducted a simple retrospective for 2009. Therefore, here is a retrospective for 2010.

2010 Achievements
Note: receiving an ITIN outside United States is an achievement!

2011 Objectives
  • Deliver game project for Windows Phone 7 and Xbox 360
  • Complete bank and tax information on the App Hub
  • Buy Xbox Kinect if / when APIs available
  • Integrate into game development:
    • Test driven development
    • Dependency injection
    • An IoC Container
    • Unit testing

In conclusion, 2010 was a turbulent year for independent game developers: November saw Indie Games hidden under the Specialty Shops as part of the Xbox dashboard update. Consequently, developers reported greatly diminished sales and prompted the campaign to Save XBLIG.

Fortunately, Microsoft restored Indie Games to the Game Marketplace by the end-of-the-month.

In fact, December saw the launch of the Indie Games Winter Uprising, in order to improve the quality of games on the channel. By the end-of-the-year, the Winter Uprising achieved a spotlight on the dashboard to further promote Indie Games on Xbox LIVE Marketplace.

Therefore, year 2011 has the potential to be another significant year for Indie Games.
One final goal, as always: write more game code, write lots more game code J