Change of Plans

It turns out that designing and developing a game is a huuuuuuuuge process although manageable. But it would take several hundred posts with the speed im explaining at the moment, so instead of step-by-step going through the development this blog series will instead cover key topics, concepts and progress during the process.

Most of the groundwork of the game is done. It’s working, you can build-, upgrade- and sell towers, fight off mobs, play several modes such as Tower Wars, Tower Defence and to come Tower Siege. However, I’ve decided to port the game from WinForms to XNA which will involve, well, actually learning XNA first, so it’ll be a bit getting accustomed to the framework.

Stay tuned though! I’ll soon have a few screenshots ready for display.

Hardest Bug I’ve Encountered

So I’m working on the tower defence (which is progressing a lot better than this blog), and I make use of the XmlReader to load settings, creatures, environment and towers when a map is started. Everything works flawlessly on both my developer- and test computer. To get feedback I send a rough version of the program to a few friends for testing. And there it goes, a strange bug was reported back to me. Apparently a few machines have the creatures running far, far too fast. Everything else goes at a normal speed, except for the mobs whom run from the start to goal in less than three second instead of taking the usual 30-45 seconds making the game totally unplayable.

I spent a few hours trying to reproduce the bug at my own computer, but eventually I gave up and instead I decided that I would build a feature into the program that would print out specific values to a file during the the game and shipped this feature to the tester. While looking through the value dumps returned by the tester everything was still looking as it should.

At a loss of what is causing the bug, I start to notice that all the reported incidents of this obscure bug comes from countries/windows language version that uses a comma as decimal separator instead of a full stop. In my testers cases, Norway.

Right there it hits me, the XmlReader must be parsing the files using the standard windows language culture! And yes indeed it was, this little line was causing all the trouble:

object readData = reader.ReadContentAsObject();

Instead of parsing the creature speed as 1.5, it decided to use the local culture instead parsing it as 15! The solution was simple, though, once the bug was found. Forcing the XmlReader to parse using english notation:

CultureInfo correctCulture = CultureInfo.CreateSpecificCulture("en-US"); ' return (T)Convert.ChangeType(readData, typeof(T), correctCulture.NumberFormat);

Bug was corrected, and now the game should work on all cultures. My first, rough, introduction to globalization and localization

Qua TD III: Class Design Part 1

So, designing the game. We’ll jump right into it by establishing a domain language which afterwards hopefully will help us identify the major classes needed in the program. By reading the description in the first post there are a few key words:

  • Map: The environment in which everything exists;
  • Mob: Creatures who run through the map from a starting point trying to reach the finish line;
  • Tower: Defensive building trying to shoot up the mobs before they reach their goal;
  • Wave: A group of related mobs spawning together over a small period of time
  • Bullet: Towers will be able to shoot at the mobs, while various shooting mechanisms will be implemented at least some of the towers will be shooting “bullets” at the mobs, and this class will represent a single bullet.

We will be translating all the above defined terms into classes, except for the map which will, for now, be handled as an multidimensional array. Furthermore we will need some classes to manage the above. I’ve chosen to create the following classes to handle this:

  1. Level: Will handle how a single game (level) progresses. It will contain information about which towers has been built, which mobs are currently on the map and so forth.
  2. SpawnCenter: Will handle spawning mobs throughout a level. There will be implemented several different ways of spawning mobs.
  3. Texture/Mob/Tower-manager classes will be created as factory pattern classes to create respectively mobs and towers and to maintain the list of textures used inside a single level.

For now the above classes will do. More will be added along the way as the need for the arises.

Lets get our hands dirty and start designing our classes. The first three classes to be designed is Mob, Tower and Bullet since these three all share one common trait: They’re all objects being moved and rendered directly to the screen. For this reason they’ll all inherit from the same base class. Lets call this base class for ScreenObject. An object being displayed on the screen have a very simple signature. It needs a location where it is to be rendered, a texture that will be rendered at the specific location and a method for actually drawing the screen object. I’ve chosen that instead of having a reference to the actual texture each screen object will simple have an integer representing which texture that should be rendered. This will all start to make sense as we start to work on the texture manager class later on. For now our base class looks like this:

ScreenObject

Download Link for ScreenObject.cs:  ScreenObject.cs

Next up we’ll cover the design of the Tower, Mob and Bullet class.

Qua TD II: The Game Loop

Picking up from the specifications of the TD in the last post we’ll continue with a discussion and implementation of a game loop for the game in this post.

As I’m hoping to put together the project in such way that it’s possible to visually see how the game evolves as early in the process as possible, I’m going to start out talking about the choice of game loop. Since the game is to be written using Windows Forms I figured that the project will be using one of the following three game loops methods:

  • A simple while loop that makes use DoEvents;
  • use a timer with a high frequency of ticks;
  • or abuse the Application.Idle event alongside with the PeekMessage API.

In my opinion, the two first options can quickly be described as utterly royal fail

FAIL

FAIL

but I’ll go through all three methods explaining why I eventually end up with my choice of game loop.

DoEvents()

DoEvents (DE) is properly by far the easiest solution to a working game loop as it can be coded in a single line. You can setup a while loop and put a DE call into it and you’re basically done… However, there are several disadvantages to using this approach. When calling DE in a loop, resources are being allocated by the call that the garbage collector is not capable of cleaning up which means that you’ll be facing performance issues at some point. There has even been reports of memory leaks as bad as 1 MB / 5 seconds when visual styles is enabled. Overall this solution is bad for performance but easily implemented.

Timers

Timers are bad! The timer classes in .NET (and most other timers for that matter) has the possibility of running out of sync when the machine is under heavy performance loads or when the frequency of the computer changes due to power management features. Furthermore the timers in .NET will raise a tick event even if the previous tick method wasn’t done execution which means you could possibly get a game loop that was running on several different threads producing utterly unpredictable results so I would definitely avoid using timers as there really is not advantages to them used for this purpose and they weren’t created for this kind of use.

PeekMessage & Application.Idle

I find this solution by far the most efficient. Windows Forms are event driven and in it’s basic it has a while loop checking for incoming messages to the window such as to close, to move it and such. When you handle the Application.Idle event you’re sure that your form is not supposed to be doing anything else when entering the game loop. Inside your game loop PeekMessage allows you to make sure the the form is still idle while continuing to execute the game loop. By combining the two you get full responsiveness in your application without any memory leaks or other dirty solutions. So this IMO is by far the best solution as it takes advantage of the windows forms loop and does not lock up the application.

Creating the Game Loop

The first thing we’ll need to get a game loop up and running is the reference to PeekMessage. I’ve decided to encapsulate this in a static class called Win32. For those of you unfamiliar with PeekMessage what it does is to check if there is any incomming messages to the current form such as a request to close or move the form. If there is no such messages in the queue, it will return false. Thus everytime PeekMessage returns false, we are free to continue with the game loop:

namespace QuaTD.Utilities { using System; using System.Runtime.InteropServices; public static class Win32 { public const int PM_NOREMOVE = 0; [System.Security.SuppressUnmanagedCodeSecurity] [System.Runtime.InteropServices.DllImport("User32.dll", CharSet = CharSet.Auto)] public static extern bool PeekMessage( out peek_message msg, IntPtr hWnd, uint messageFilterMin, uint messageFilterMax, uint flags); [StructLayout(LayoutKind.Sequential)] public struct peek_message { public IntPtr hWnd; public IntPtr msg; public IntPtr wParam; public IntPtr lParam; public uint time; public System.Drawing.Point p; } } }

With that in place, we can now create a function IsAppIdle() that will use PeekMessage to check whether the application is available for doing more game looping.

public bool IsAppIdle() { Win32.peek_message msg; return !Win32.PeekMessage(out msg, IntPtr.Zero, 0, 0, Win32.PM_NOREMOVE); }

Now we’re ready to put together the actual game loop which will be started by the Application.Idle event, and will continue as long as the application is idle. Once the application again becomes idle, the game loop will continue.

First we must hook up the Application.Idle event which is raised everytime the form goes into an idle state (thus having no more messages in the queue to be processed) and we shall remember to unhook this event once our application closes to prevent memory leaks:

public GameForm() { InitializeComponent(); Application.Idle += new EventHandler(Application_Idle); this.FormClosing += new FormClosingEventHandler(GameForm_FormClosing); } void GameForm_FormClosing(object sender, FormClosingEventArgs e) { Application.Idle -= new EventHandler(Application_Idle); this.FormClosing -= new FormClosingEventHandler(GameForm_FormClosing); }

And the game loop itself:

void Application_Idle(object sender, EventArgs e) { do { if (ActiveForm != this) System.Threading.Thread.Sleep(200); GameLoop(); } while (this.IsAppIdle()); }

This concludes the choice and implementation of game loop for Qua TD. Modification to the game loop will eventually arise later on in the process, but at least now the basics are set for continuing the development of the game.

Qua Tower Defence I: Introduction

After my quick introduction I’ll rapidly followup with another post!

Lately I’ve been thinking of creating a simple desktop game. When pondering about which kind of the game I would create the arcade game Rampart came to mind. For those of you not aware this game introduced the very popular Tower Defence(TD) genre to the gaming community. Later on Blizzard created the environment that eventually lead to further development of the tower defence genre with the custom user created maps in the games Star Craft and Warcraft 3 where tower defence maps were seriously popularized. I’m a hugh fan of the genre as it not only has action and real time elements in it but it also has interesting strategic elements to – even better though, it is extremely extensible and customizable. There were created several dozens of different maps in especially Warcraft 3. The TD concept wasn’t just reimplemented; several new subclasses of tower defence was created. There were team tower defence, solo tower defence, race tower defences,  upgrading towers, advanced upgrading logic and mini games. All in all the tower defence genre properly became the most popular custom map type in WC3 alongside with DOTA.

Warcraft 3 Tower Defence

Warcraft 3 Tower Defence

So I decided to create a TD game. This is as much meant to be a personal learning experience with programming an actual game as it is to try the concept of blogging and writing programming guides/tutorials. I’ll try to fill the journey with interesting aspects of developing the game.

Let’s jump right into a loose specification for the game at hand. The game will be developed with simple graphics in a 2D environment, the major focus will be on funny and addictive game play and not on fancy visual effects or huge 3D worlds. The game will be tile based as usual in a tower defence. The player will be allowed to build towers that’s meant to kill the mobs before the reach their destination on the map. The game will allow several different game types among these maps where the player is supposed to create a maze for the mobs with smart placement of towers, but also maps where the player will create towers along the path where the mobs are moving.

There will be several different towers which will each have their own features such as fast, slowing and splash towers alongside with tower upgrades that will introduce a strategic element to the game. Just like the game will feature different tower setups there will be customizable mobs as well; boss mobs, slow mobs, fast mobs, invisible mobs and so on.

The game will be written using .NET Framework 3.5 in C# using Visual Studio 2008 Professional Edition. It should be fully compatible with VS 2008 Express Edition though. In the coming time several key points in the development of the game will be presented. These include: The game loop, mob path finding, general program design, extendability and rendering  so stay tuned!

First Post – Kek

My first post – wauw.

In this blog I’ll be writing mostly about technical aspects encountered while programming various projects or crazy ideas. As opposed to on Coding Horror there won’t be much posting about everyday programming phenomens, and it properly won’t be updated quite as often; nor get quite as many views.

For a living I’m studying at Denmark’s Technical University for my degree as a bachelor in computer science. I’ve an (un)healthy interest in the software aspect of computing. I’m an avid PC gamer, programmer and everyday user of computers. I consider myself rather experienced with .NET and especially VB- and C#.

Follow

Get every new post delivered to your Inbox.