We Are Bugs Refactored And Source Released

 

WeAreBugsLogo (click to play)


My Mix 10k Challenge entry, We Are Bugs, didn’t win any prizes, but I had a lot of fun developing it and thought others might enjoy  tinkering with it themselves or might be able to learn from seeing how a simple Silverlight game is put together.

I have spent a fair amount of time completely refactoring the source code for We Are Bugs to make it more structured and easier to understand.  (The original code was optimized for size and not pretty.)

For this refactored version I used a simple Model-View-Controller pattern, similar to what Joel Neubeck describes in his Developing a casual game with Silverlight 2 articles.  I also used the state pattern to keep the different game states organized.

I’ve released the code for the refactored version of We Are Bugs on Codeplex. You can find it here: http://www.codeplex.com/WeAreBugs

Following are some of the areas in code worth mentioning briefly.

Controller

The controller controls the navigation between game screens, owns the render loop which runs continuously to update the bug positions, and controls transitions between the various game states. If you want to follow through the code execution, this is the place to start.

Here is the class view for the controller

CropperCapture[7] 

Bug Models, AgentModel, and the DynamicModel base class

The bugs in the game all derive from AgentModel, which in turn derives from DynamicModel. As you can see in the class diagram below, the “food” also derives from AgentModel.  This is because at some point I think I will want the food to animate in some fashion or another. Possibly the “food” is another small bug that tries not to be eaten.

CropperCapture[12]

The DynamicModel base contains all the basic functionality for managing position and orientation. It uses a set of matices for this purpose and exposes a single RenderTransform that can be used by the Views to update themselves.(see below)

From the EnemyView:

public void Update(){    RenderTransform = _enemyModel.RenderTransform;    UpdateEnemyExcitement();}

One of the key things required for the bug movement was the ability to align a bugs forward direction with its velocity. To do this, I added a “Front” property to the DynamicModel.

The front property is a normalized vector that determines what direction the bug is facing.  With this, every update step, I can just set the Front property equal to the AgentModel’s velocity vector to get the affect I needed.

From the AgentModel.Update() method:

Front = Mathematics.Normalize(velocity);

During the update tick a little bit of matrix trickery aligns the bug with the direction of the Front vector.

The AgentModel class contains some higher level movement concepts like SteeringForce, Velocity, and MaxSpeed.  It also contains a list of Behaviors.

These Behaviors are often referred to as Steering Behaviors and are described in great detail with examples here: http://www.red3d.com/cwr/steer/

The Behaviors in We Are Bugs all implement a common interface called IBehavior. (see below)

CropperCapture[13]

As you can see above, We Are Bugs only uses 3 steering behaviors.

SeekPointBehavior is used to make the Bug chase the mouse pointer.

PursueAgentBehavior is used to make the enemy bugs chase the “good” bug.

SeperationBehavior is used to keep all the enemy bugs from bunching up and overlapping eachother.

The bug Models themselves are very light weight as they get almost all there functionality from the AgentModel and DynamicModel base classes.  In fact, the EnemyModel is the only bug model that has any additional properties.

The EnemyModel has a single “Excitement” property which is set by the GameModel.Update() method. The value of the property is based on how close the enemy is to the bug it’s chasing.  The EnemyView then uses this Excitement property to turn the Enemy red when it gets close to the “good” bug.

Game Model and Game States

One of the largest challenges I have when developing a game is keeping the core game object from blowing-up in complexity.  There are usually a lot of game-states to manage and more often then not the core game object ends up a big pile of stink!

For We Are Bugs, I decided to try and hold back some of the code-stench by using the state pattern.  (I won’t go into this in detail you can learn about it here: http://www.dofactory.com/Patterns/PatternState.aspx)

The GameStates in We Are Bugs can kind of be thought of as mini-controllers for the GameModel.  They contain a reference back to the GameModel and use this reference to make the GameModel do what it(the GameState) requires.

CropperCapture[14]

As can be seen above, the State base class contains 3 methods (not counting the constructor): Enter, Exit, and Update.

Enter allows the state to set things up as it becomes the active state.

Update is what gives the State dynamic, ongoing control of the GameModel during render time.

Exit allows the state to clean house when it’s finished.

GameStates are set by calling SetState on the GameModel class and passing in a State object. (see below)

public void SetState(State state){    if (_state != null)    {        _state.Exit();    }     _state = state;     _state.Enter(); }

We Are Bugs has 4 games states.

Note: The textual display of information is not considered part of what I’m calling game states.  The game state really just entails what the “bugs” are doing in the background. The text on the screen is actually overlaid on to the game.

StartState is what you see when the game first loads up. In this state, there is a single bug that randomly moves about the screen by itself (no user input)

ReadyState centers the bug and prevents movement while the instructions for the game are displayed.

PlayState (suprise, suprise) is the state where the core game-play takes  place

GameOverState starts as soon as you are eaten by one of the bad bugs.

Final Words

This post does not describe the We Are Bugs code in complete detail, but hopefully it can act as a small guide as you look at the actual source.

As mentioned above you can download the source here: http://www.codeplex.com/WeAreBugs

Source Code Terms of Use

Feel free to do pretty much whatever you want with the source.  Learn from it, extend the game, make derivative games, etc…  I don’t require anything specific, but a shout-out to Farseer Games is always nice. :-)

Also, if you do something interesting with the code please shoot me an email and let me know. I’d love to see it.

-Jeff Weber