Didgery is now on Indievania!

You want it? It’s yours my friend, as long as you have enough rupees. Actually, that’s not completely true. You see, Didgery is available on Indievania as a ‘pay what you think this game is worth’ download, so please check it out and throw a bit of cash my way if you have any lying around. Being an indie dev is tuff work you know, and any little bit helps! I have already made a dollar today! Momma’s so proud!

 

Sadly, a bit of bad news came in this morning in the form of email. Remember how I originally planned to release Didgery onto Desura? Well, it looks like the Desura staff think Didgery not a good fit:

HI Clinton,
I don’t think that Didgery would be a good fit for Desura. Card games do not seem to sell well among our users. For now we will have to pass on it, but thank you for considering Desura.
If you have any questions please don’t hesitate to ask.
Regards

 

It’s a bit of a bummer, as Desura was one of the first portals I ever thought to release on :( Awww well, happens I reckon.

….I just got a huge desire to read a lot of Sonic comics…. I need to start collecting those again….

 

Anyhow, thanks for all your support any who read this and decide to donate some money to the Clinton Cause. Have a good one!

 

Understanding the XNA LoadContent/UnloadContent Paradigm

An alternative title to this could be “Prefer separating the loading of graphical content (Textures, Vertex Buffers, Render Targets) from the loading of non graphical content.” The reason for this is not immediately obvious to beginners (or even those intermediate with XNA) but the purpose becomes clear when the possibility of a reset graphics device comes into the picture (when developing for the PC for example.) If you don’t do proper cleanup when a reset is triggered, the data will remain inside the graphics device and will build up with each reset. If this happens enough times the graphics card will run out of memory and your application will throw an OutOfVideoMemory exception.

It doesn’t take all that much to trigger a reset either. On PC games it is typical to provide the user with an option to set the resolution of the game. Guess what? If you change the resolution you effectively trigger a graphics device reset! This explains why some games take a long time to apply the resolution change; they have to unload everything from the graphics device, and then load it all back in! This is also why some games force you to restart the game to apply the option, as it is easier to force the user to take some action than to retrofit their engine design to get all the loading and unloading internals correct.

But what if you don’t want the user to have to exit and then restart the game? Perhaps you are one of them fancy-pants people and you want the resolution change to be applied in-game. This is easily possible IF you design your game from the get-go to expect this sort of behavior. Basically, follow the rule above. If you need to load some sort of graphical content, don’t do it in the constructor. Instead, place it in the LoadContent() method if you are using the GameComponent structure. Make sure to also override the UnloadContent() method. This is where you will call Dispose() on all the content you loaded in LoadContent. Now here is what will happen. If a graphics device reset occurs, XNA will call all your UnloadContent methods (which frees all the data from the graphics device.) It will then call all the LoadContent methods to load all the graphics material back into the graphics device. Since everything has been unloaded, the stray data won’t be hanging around on the device and you won’t have to worry about that nasty OutOfVideoMemory exception! Effectively handling device resets also brings your game closer to the PC realm of things, as that is one of the mainstay worries you need to keep in mind when developing for the PC.

Happy coding!

Didgery

Ahhh yes…

Didgery is a game I have been working on for quite some time now. It’s the game I started right after I put Nut Harvest 360 on hold. I’ve put a lot of effort and design into the thing, and, personally, I think it shows. It’s a card/puzzler game slated for release sometime in August for the Xbox 360. It was coded using C# and Microsoft’s excellent XNA framework.
I think Didgery is the last puzzle game I make in a while… I used to think that puzzle games would be the easiest things to make… You know, how hard could they be? You don’t necessarily need parallaxing layers, or physics, or tile maps, or editors or any of that fun. I now humbly completely disagree with my former self. Puzzlers have their own nightmarish little nuances. They are tied so heavily to logic and rules that programming it can become a nightmare if you aren’t careful. And bugs…ohhh, the bugs… That’s the worst part. I’ve had bugs in platforming games I’ve made and such, but they are relatively easy to spot, and generally not too hard to fix. The same thing can’t necessarily be said about puzzle games. The logic is tied so closely together that pulling one string to fix a bug may inadvertently cause the whole system to trip over itself in ways you couldn’t possibly comprehend.
I know why Bejeweled Twist took four years to make now…and that developed by PopCap, the king of all things puzzle.
Oh well, it’s almost over now. I’m on the downward slope of adding in bits and pieces and hunting down bugs.
Here is Didgery’s website. Have fun!

>Cryptic Error Messages on Stencil Buffer Clear

>

It has been a looong time since I lasted posted… Working on my game, school, and a newly acquired job have been eating away at my time. Anyway, I thought I would post something short and simple, but hopefully helpful.

The C# compiler is usually good about giving you detailed information on compiler/runtime errors, but there are those occasional times in which it gives you some really cryptic response that doesn’t help you in the least. I ran into one of those today when attempting to clear my stencil buffer. It crashed on this line:

Game.GraphicsDevice.Clear(ClearOptions.Stencil, Color.Black, 0, 0);

With the ever-so helpful error message: “An unexpected error has occurred.”

Well great, that tells me everything I need to know to fix the problem! (Extreme sarcasm intended)

After messing around for a bit I found that my problem lay in the fact that I hadn’t created my stencil buffer at startup! So if you are running into this problem, add this code to your Game1 constructor:

graphics.PreferredDepthStencilFormat = DepthFormat.Depth24Stencil8Single;

That will make sure you have a stencil buffer ready to use, and thus the cryptic error message should go away.

>Those Sly Little Garbage Collection Issues

>

Do you hate garbage? I do, I hate it a lot. There’s nothing more dissatisfying than playing your game and then HITCH, the garbage collector kicks in and takes a big-juicy bite from your framerate. I recently got through doing a major refactoring to my game engine (now it’s actually suited for some platformer action) and became interested in how much garbage was being generated. To find some of the basic stuff causing garbage I created a test scenario that told my game engine to render a lot of stuff at once. After some scrutiny with the XNA Framework Remote Performance Monitor I was able to find (and document) a majority of the garbage-generating sections of my engine. The results were terrifying. 7 Garbage Collections lasting roughly 80 milliseconds were occurring every frame. In other words, a majority of my CPU time was spent simply cleaning up after my engine! Not good. So I got on my classic programmer mind set and began commenting things out until I could hone down into the source of garbage. After I got most of the core code cleaned up I ran my work-in-progress game (Nut Harvest 360) to what else I could find out. A lot of things I discovered surprised me.

Iterating though a Current Technique Passes using foreach generates garbage:

This was a tough one. I had nearly all my code commented out that I thought would cause garbage, but yet the Perf. Monitor told me that boxing was happening somewhere.

So I continued searching (ludicrously commenting out additional statements), until I was left with my Primitive Rendering Class. All it was doing was iterating over an EffectPass collection like so:

foreach (EffectPass pass in PBBasicShader.CurrentTechnique.Passes)

{

Pass.Begin();

Game.GraphicsDevice.VertexDeclaration = this.vertices;

Game.GraphicsDevice.DrawUserPrimitives(type, this.elements, 0, this.NumOfPrimitivesToRender);

Pass.End()

}

Pretty normal eh? So after scratching my head for a second I disabled the body of the code. But there was still boxing! I was getting discouraged at this point. Surely it couldn’t be the foreach could it? A moment of doubt passed. I commented out the foreach and… the boxing problem went away! I never thought that iterating over an EffectPass collection would generate garbage, (I mean, several XNA books I have use this technique) but tests confirmed that it does. After rewriting the above as:

for (int i = 0; i < technique.Passes.Count; ++i)

{

PBBasicShader.CurrentTechnique.Passes[i].Begin();

Game.GraphicsDevice.VertexDeclaration = this.vertices;

Game.GraphicsDevice.DrawUserPrimitives(type, this.elements, 0, this.NumOfPrimitivesToRender);

PBBasicShader.CurrentTechnique.Passes[i].End();

}

The boxing/garbage problem when away! I found the same problem in my ParticleSystem. After I swithced to a regular for instead of a foreach I no longer received boxed value types.

Be very careful when it comes to boxing. (If you don’t know what boxing is take a look here.) Some of the most simple methods that you think don’t box actually do. I dug into my Camera class and found that the statements Vector2.Equals(val, val2) was generating garbage. How could a comparision between two Vector2’s result in garbage?, I thought. Well, I looked at the Equals definition and found that it actually takes a reference of two Objects. The Vector2’s were being boxed into an Object, and then compared, when resulted in garbage, and thus garbage collections. I changed this to the val.Equals(val2) method and removed the boxing problems.

Anytime you use the new keyword you are generating garbage (unless it’s a value type such as an int, struct, etc.) This was my largest problem next to boxing. I had too many methods that were dynmanically creating arrays every time they were called (often every frame.) This was remidied by removing the array from the method and instead have the method accept an array by ref. This puts a bit more work into the calling code (as you specifically have to set up an array in every class that uses the method) but it’s worth it in terms of how much garbage you are saving yourself.

In my InputManager I found that having a list of enumeration types causes boxing each time a value is added.

The problem code was these two lines:

List connectedControllers = new List (MAX_CONTROLLERS);

connectedControllers.Add(PlayerIndex.One);

I don’t really understand why…perhaps the list does some internal operations? I read on Shawn’s blog that using an enum as a key in a Dictionary causes boxing due to internal operations, so perhaps this is something similar. This was remidied by making the List accept ints and casting the PlayerIndex value to an int before storing it into the array.

Solution:

List connectedControllers = new List(MAX_CONTROLLERS);

connectedControllers.Add((int)PlayerIndex.One);

Be very wary of using Linq extensions, as a majority of them box values in a heartbeat. If its possible to make your own method, than it may be best to do so. I was making some heavy use of the Linq function Except (returns an array of all the data in the first set not present in the second set.) I was able to reduce garbage and boxing by creating my own function.

Problem:

IEnumerable set3 = set1.Except (set2);

Solution:

private void SetDifference(List < T > set1 , List < T > set2, ref List setDifference)

{

if (setDifference == null)

return;

setDifference.Clear();

foreach (T obj in set1)

if (!set2.Contains(obj))

setDifference.Add(obj);

}

SetDifference (set1, set2, ref set3);

Here is one that broke my heart: Using the List sort functionality produces garbage! This was (and still is) a baddie for me, as I sort all of my objects each frame multiple times before drawing them (once for their Update Order and once for their Draw Order.) The only way to get around this is to either use an array or to create your own sort method. (Please note that casting your List to an Array to Sort is a very very bad idea, as calling ToArray() or ToList() creates a new array and then returns it, resulting in garbage.

Well there ya go, a few general performance tidbits to keep in mind. I hope they prove useful.