Dream Build Play 2009
I managed to make the deadline for entering the Dream Build Play 2009 competition. The results are expected to be announced by the end of the month. Based on the quality of entries this year I’m not holding out a huge amount of hope of actually winning. Regardless, it was a great experience and I learned quite a bit in the process.
As part of the contest submission we wrote up a game description including play instructions and some comments on the technical design, as well as a video trailer. The video is below, and the documentation I submitted follows. Many of the other entries have posted videos in the Dream Build Play 2009 YouTube group. And you can see all of the contest entries in the Dream Build Play Gallery.
I still have a few more things to do on the game before I put it up for sale on the XBox, but I’m going to take a bit of a break before continuing on. I should have more time to update this blog as well. Thanks for reading – hope you enjoy the video.
Guardian
Game Play
The overriding premise of the game is to keep asteroids from hitting your planet, and alien ships from shooting it. Your planet will be damaged as it’s hit, and when the damage reaches the planet center the game is over. You’re competing for high score, with the top ten high scores are tracked locally.
You command a satellite that constantly orbits the planet. Pressing A fires your selected primary weapon from the satellite towards the red target indicator that you move with the left thumbstick to aim your shots. You have to be careful to time your shots so the planet isn’t in between the satellite and the target. Your main weapon is the Laser Canon and has infinite shots available. The Plasma Canon is more powerful and the shots move faster. The Rail Gun is an instantaneous kill, and will destroy anything in its path, including taking out a large portion of your planet if it’s in the way. You will receive large cumulative bonuses for killing multiple enemies with a single Rail Gun shot. Each primary weapon has a different charge rate which limits how often you can fire. As mentioned, the Laser Canon has infinite shots, but all other weapons require ammunition.
Pressing Y fires your selected secondary weapon. These weapons fire from the surface of the planet. Missiles will automatically target the asteroid or enemy ship closest to the red target – it takes a second or two for the missile to lock on. Nuclear Missiles will target the actual red target location, so you can fire them at a point in space and use the large blast radius to take out multiple targets. The BG4143 will destroy everything on the screen by sending out a shockwave with an ever increasing radius.
Alien ships will drop a powerup after destruction. You grab the powerup by moving the target close by and using X to activate the planetary tractor beam. The beam will slowly pull the powerup to the planet, after which it will be used or automatically added to your inventory. Powerups can add energy to your shields or primary weapon, add maximum shield/weapon energy, and increase shield/weapon charge rate. Powerups will also make ammunition available for the various secondary weapons.
You cycle your primary weapon by pressing the Right trigger, and cycle the secondary weapon using the Left trigger. The right shoulder button will generate a new background at any time, and the left shoulder button displays your current weapon inventory during game play.
Shields work on their own with no intervention. They will protect your planet for awhile but have a slow charge rate which can be increased by powerups. Once the shield power is used up asteroids or enemy fire will damage your planet. However the shield will continue to recharge as long as nothing is hitting it.
There are 32 asteroids in each wave, and 0 to 3 enemy ships. There are also bonus asteroids and comets that will move by your planet quickly. These can be difficult to hit, but you’ll receive a bonus score for destroying them. They will never hit your planet, but they do come in close enough to hit the satellite and destroy it. The asteroids and ships start out fairly slowly, but they speed up over time until they’re moving quite rapidly.
Development and Design
A limited version of Guardian was originally created for the iPhone, but I wasn’t happy developing on that platform so I made the decision to port it to XNA and XBox and add much of the functionality I had originally planned for the iPhone.
Most of the game uses basic 2D technology: Sprite sheets, particle systems, state machines, and the like. Collision detection is mostly accomplished through point-in-circle tests. However the planetary collision detection uses pixel tests since the planet is eaten away throughout the game.
Some of the more interesting technicalities are described in the following sections.
Background Nebula
The background nebulae are generated using a pixel shader which uses fractal brownian motion and other procedural techniques to build a random cloud and star texture. Each time you see a new background it was generated in real time. The backgrounds can actually be animated at 60fps to get some very nice moving nebula effects, but combining it with the rest of the game dropped me down to 30fps. At some point I plan to optimize it some more.
It is also interesting to note that the backgrounds are generated entirely on the GPU and exist entirely in video memory.
Planet Generation
The planets are also procedurally generated, and are actually 3D. The basic spherical structure is a cube, and a mapping function is used to move each vertex out to the sphere’s radius, and then the noise functions are used to add the height value. A second sphere is used for the ocean areas. Each time the game is started you get a new planet. In future versions I plan to allow regenerating the planet, as well as having different texture sets to allow for non-Earth type planets.
Generating the planet in 3D allowed me to show the planet rotating in the menu areas, with a seamless transition to the game play area by simply moving the camera out to the proper location using the SmoothStep function. The planet displayed during game play is still 3D, and can actually be rotated, but it looks kind of strange since the craters don’t move with it.
Planet Craters
The craters are created by drawing one of several random crater sprites into a mask texture each time damage is done to the planet. The mask texture holds the cumulative result of each crater application. Before drawing the planet the mask is used to set the stencil buffer, then the planet is drawn with the craters masked out.
Yet Another Guardian Progress Video
Things are coming along nicely with Guardian. The Dream Build Play entry deadline is fast approaching, but I think I’m in pretty good shape to get my entry completed. The video shows most of the functionality. Pretty much all that’s left now is fleshing out some of the graphics, and adding a few more weapons. Then I can start getting some sleep.
XNA Game Project
Here’s a video of the XNA game I’ve been working on. It’s a port of the iPhone version with some additional functionality planned.
Simplified XNA Message Boxes
Shawn Hargreaves brings up the subject of how annoying async coding can be. Calling a “begin” method, dealing with the completion callback function, handling the results – it’s all very ugly to keep track of, and often leads to very ugly code.
He wants to be able to write code like this (and so do I)…
int? button = Guide.ShowMessageBox("Save Game",
"Do you want to save your progress?",
new string[] { "OK", "Cancel" },
0, MessageBoxIcon.None);
if (button == 0)
{
StorageDevice storageDevice = Guide.ShowStorageDeviceSelector();
if (storageDevice != null)
{
using (StorageContainer storageContainer = storageDevice.OpenContainer("foo"))
{
...
}
}
}
It turns out that making async code work almost like this isn’t too bad to do. It basically involves creating a static class to encapsulate all of the various things you need to keep track of. Here is the fairly well commented code for the static class.
class SimpleMessageBox
{
private static int? dialogResult = null;
public static bool Showing { get; set; }
public static int? ShowMessageBox(string title, string text, IEnumerable buttons, int focusButton, MessageBoxIcon icon)
{
// don't do anything if the guide is visible - one issue this handles is showing dialogs in quick
// succession, we have to wait for the guide to go away before the next dialog can display
if (Guide.IsVisible) return null;
// if we have a result then we're all done and we want to return it
if (dialogResult != null)
{
// preserve the result
int? saveResult = dialogResult;
// reset everything for the next message box
dialogResult = null;
Showing = false;
// return the result
return saveResult;
}
// return nothing if the message box is still being displayed
if (Showing) return null;
// otherwise show it
Showing = true;
Guide.BeginShowMessageBox(title, text, buttons, focusButton, icon, MessageBoxEnd, null);
return null;
}
private static void MessageBoxEnd(IAsyncResult result)
{
dialogResult = Guide.EndShowMessageBox(result);
// if no button was pressed then we want the result to be -1
if (dialogResult == null)
dialogResult = -1;
}
Using the class involves calling SimpleMessageBox.ShowMessage(…) in your Update() method. You continue to call it each frame until it returns a result. This does require some game state information (i.e. your game state is SaveGameState or something similar) so it takes a little extra work, but you have to keep track of those sorts of states anyway.
Here’s a sample of the usage:
protected override void Update(GameTime gameTime)
{
base.Update(gameTime);
if (saveGame)
{
// show the message box - we end up calling this each frame as long as we're in the saveGame state - it will
// return null until the user presses a button or closes the guide - it returns -1 if the guide
// is closed, otherwise it returns the button number
int? button = SimpleMessageBox.ShowMessageBox("Save Game", "Do you want to save your progress?",
new string[] { "OK", "Cancel", "Repeat" }, 0, MessageBoxIcon.None);
switch (button)
{
case -1:
message = "No Button";
saveGame = false;
break;
case 0:
message = "Saved";
saveGame = false;
break;
case 1:
message = "Cancelled";
saveGame = false;
break;
case 2:
message = "Repeat";
break;
}
}
}
I haven’t use this code in a real project yet (just the sample), but it seems like it would work in quite a few situations. It’s a bit different than doing a message box in Windows since you have to realize you’re calling the ShowMessageBox method each frame. That aside, you can almost imagine that you’re using a blocking message box function.
Lens Flare Occlusion Using Texture Masking and XNA
I have an article posted on Ziggyware that discusses an alternate method to hardware occlusion queries for checking sun visibility to control lens flare intensity. The article is part of a contest so I can’t post it here until the contest has been over for awhile. I can link to it however.
Lens Flare Occlusion Using Texture Masking and XNA
Hope everyone enjoys it.
Sprite Splitting with SpriteBatch
Someone over in the XNA forums asked a question about how to make sprite explosions like those in the old Defender arcade game, where the sprite is broken into pieces and exploded everywhere.
This effect can be done using nothing more than the XNA SpriteBatch class. One of the overloaded Draw() methods allows you to pass a source rectangle. When drawing a sprite you can use the source rectangle to grab just a part of it. So it’s a simple matter to use multiple draw calls on a single sprite to draw little pieces of it, like so:
// draw parts of the sprite
int xInc = 8;
int yInc = 8;
float spacing = 1.5f;
// draw parts of the sprite
for (int x = 0; x < face.Width; x += xInc)
for (int y = 0; y < face.Height; y += yInc)
{
Vector2 position = new Vector2(100 + x * spacing, 150 + y * spacing);
Rectangle source = new Rectangle(x, y, xInc, yInc);
spriteBatch.Draw(face, position, source, Color.White);
}
“Multiple draw calls” sounds bad, but SpriteBatch is able to batch up the draw calls so you shouldn’t notice any real effect on performance.
You can download a sample XNA project to see this in action. The project also includes a SpriteExploder class that will automatically explode your sprite into multiple pieces and throw them about the screen.

