Pandemonium

September 19, 2010

Efficient Development – part five

Filed under: Games Development — bittermanandy @ 6:27 pm

So, as promised: a more positive post, and this one also offers something more concrete than recent posts have tended towards: another component in the Kensei.Dev library, about which I have written before.

I recently found myself needing to add logging to Pandemonium, to aid with debugging. The idea of logging is to write text to the output window and/or a file, to explain what the code is doing. It is then possible the examine the logs to see what happened and when, to identify for example why something went wrong. .NET provides Diagnostics.Trace but it is somewhat limited in scope, so a more powerful logging framework can offer much more control over what is logged.

Initially I planned to create my own logging framework from the ground up, but I suspected that I would merely be repeating what is already available – and indeed about five seconds on Google pointed me in the direction of this. DotNetLog (also known as BitFactory.Logging, also known as Termite) is quite an elegant framework: you can send output to any number of loggers of which there are many different types, and each can be formatted individually. It costs $5 but that’s almost as good as being free, so I wasn’t too concerned by that.

If there is one unfortunate restriction to DotNetLog, it is that it doesn’t work on Xbox 360 (you may have gathered I’m not at all bothered about Windows Phone 7) as it isn’t consciously intended for XNA games. Therefore, I decided that rather than litter my code with references to BitFactory.Logger (all surrounded with #if WINDOWS) I would create a Kensei.Dev.Logger static class, which would be the only area of code that would refer to BitFactory at all. There are a number of other advantages to such a facade, such as those mentioned here (an article from which I borrowed a number of ideas).

Within just a few minutes Kensei.Dev.Logger was up and running, and sending log output to both the console (visible in the Output window in Visual Studio), for monitoring while the game is running, and a file, for analysis later. Generally of course, the console logging would be disabled in your Release build, and file logging would also be disabled but with the option of being enabled via a command line switch, so if your players are having technical problems you can tell them to enable logging, play the game until the problem occurs, then send you the logs.

So far so ordinary – nothing new as of yet. But I had a few further ideas of how this logging framework could be extended to be more useful.

FrameCount and LocalFrameCount

By default, DotNetLog writes out each log entry in a format similar to the following:

[Pandemonium] -- {Kensei} --<Info> -- 19/09/2010 17:13:44 -- Initialised logger.

That’s the application name, followed by the log category, then the log level, then the time of the log entry, and finally the actual log message itself. It’s really easy to write a Formatter of your own (derived from BitFactory.LogEntryFormatter) to display this in a more pleasing format, but what really bugged me was that the time shown just isn’t very useful. A Windows service might want to know the date and time to the nearest second, but for a game such information is simply not very helpful. It would usually be much more useful to track the number of frames since the game was started (or the most recent level change) and log that, instead of the time.

Initially it seemed there was no way to do this, but a quick email to the framework’s authors (and an equally quick reply) showed the way forward. First, I had to define my own FrameBasedLogEntry type, derived from LogEntry:

private class FrameBasedLogEntry : LogEntry

{

    // Constructors not shown

    public uint FrameCount { get; set; }

    public uint LocalFrameCount { get; set; }

}

Then, I had to create my own Logger and override the function that normally created a LogEntry, getting it to create a FrameBasedLogEntry instead, filling in the FrameCount and LocalFrameCount values (with the total number of frames since the game started, and the number of frames since the last level change, respectively).

private class FrameBasedCompositeLogger : CompositeLogger

{

    protected override LogEntry CreateLogEntry

        ( LogSeverity aSeverity, object aCategory, object anObject )

    {

        return new FrameBasedLogEntry(

            aSeverity, Application, aCategory, anObject.ToString(),

            Logger.FrameCount, Logger.LocalFrameCount );

    }

}

Finally, I had to create my own FrameBasedLogEntryFormatter derived from LogEntryFormatter, and tell the various Loggers I was using, to use it for formatting.

private class FrameBasedLogEntryFormatter : LogEntryFormatter

{

    protected override string AsString( LogEntry aLogEntry )

    {

        FrameBasedLogEntry frameLogEntry = aLogEntry as FrameBasedLogEntry;

 

        if ( frameLogEntry != null )

        {

            return String.Format( “[{0}/{1}] [{2}] [{3}] {4}”,

                frameLogEntry.FrameCount,

                frameLogEntry.LocalFrameCount,

                frameLogEntry.SeverityString,

                frameLogEntry.Category ?? “”,

                frameLogEntry.Message ?? “” );

        }

        else

        {

            return String.Format( “{0} – [{1}] [{2}] {3}”,

                aLogEntry.Date.ToShortTimeString(),

                aLogEntry.SeverityString,

                aLogEntry.Category ?? “”,

                aLogEntry.Message ?? “” );

        }

    }

}

Easy! Now all log entries were formatted with the frame count instead of the time, something like as follows:

[47563/1489] [Info] [Kensei] Silver star 42 collected.

LoggerForm

The really clever bit was still to come. You may remember from my earlier discussion of Kensei.Dev.Options and Kensei.Dev.Command that these components offer dialog boxes, so that changing an option is as simple as clicking a checkbox, and entering a command simply involves typing it and hitting Return – all while minimally affecting the game itself. I wanted to do the same for Kensei.Dev.Logger, and furthermore to easily allow the option to disable certain categories from displaying in the logger at all (so you know if the bug you are looking for is in your audio code, for example, you can disable all logging except from the “Audio” category).

You can view my code later to see exactly how I built up the form (using the standard form designer as a basis, of course) but the interesting part was to create a new DialogBoxLogger type, derived from BitFactory.Logging.Logger. Instead of overriding the WriteToLog function, which would only allow me to modify a preformatted string, I overrode the DoLog function, to enable me to work with the LogEntry object itself (really of course a FrameBasedLogEntry). This sent the LogEntry to the form, where I was able to use the Category information to populate a CheckedListBox, and only output the log entry if the corresponding category was checked; and also to change the colour of the log entry to make errors more obvious.
 The Logger dialog shows all logging and allows different categories to be enabled.

I confess, some of the above logging is not completely genuine; but hopefully this screenshot is enough to demonstrate what a powerful and clever tool this is. The whole time I’m debugging my game, I can have the logger dialog running alongside it so I can see exactly what is happening in the game at any one moment. At the same time, logging is still being routed to a log file in the executable folder, so if everything falls apart I can go back and work out what went wrong at my leisure:

[0/0] [Info] [Kensei] Starting LegendsOfXaerolyte version 1.0.0.0 at 19/09/2010 17:50:56.
[0/0] [Info] [Xaerolyte] Hello!
[987/987] [Info] [Kensei] New severity threshold: Debug
[2872/2872] [Debug] [Kensei] Beginning writing Pandemonium blog
[4129/4129] [Debug] [Kensei] Adding links to blog
[6359/6359] [Info] [Pandemonium] Loading game
[8124/8124] [Info] [Pandemonium] Changing level: The River Styx
[8688/8688] [Info] [Kensei] CommandResetLocalFrameCount
[8688/8688] [Info] [Kensei] Resetting local frame count at 19/09/2010 17:53:24
[10315/1627] [Info] [Pandemonium] Loaded level The River Styx
[12559/3871] [Error] [Audio] No sounds available!
[14088/5400] [Info] [AI] Calculating pi...
[18000/9312] [Info] [AI] Calculated pi to three trillion decimal places. Result: 3.14159265358979323846264338327950288419716939937510 ...
[21484/12796] [Debug] [Physics] Player bounced off rock

One possible improvement to the Dev Logger dialog would be to use a tab control, and enable different combinations of categories (and levels) on each tab. Thus you could have the first tab showing all normal logging, the second showing only the “AI” category but including verbose (Debug) logging, the third showing only errors from all categories, and so forth. I chose not to do that at this time, though may come back to it later.

Conclusion

It should be pretty obvious what a useful feature logging is. The DotNetLog logging framework is not only complete in its own right, and easy to wrap in a facade, it is also easily extensible and deliberately structured in such a way that users (eg. me!) can use it in ways that the original authors never expected. Judicious use of inheritance allowed me to take the framework and remould it in a way more appropriate for me, without needing (or indeed, being able) to rebuild the assembly itself.

I make Logger.cs available for download for you to do with as you will, in fact, you can officially do what the fuck you want with it. If you downloaded the rest of the Kensei.Dev code I made available previously it should fit right in with minimal effort (I have tweaked Kensei.Dev a bit since then, but not in any major way as far as I can recall); if not, it should be fairly simple to strip out the references to other Kensei.Dev components and/or replace them with your own equivalents as you see fit. Enjoy, and as always, please leave a comment if you have any feedback, questions or suggestions!

Advertisements

April 10, 2009

A View to a Thrill, Part One: Camera Concepts

Filed under: Games Development,Personal — bittermanandy @ 8:19 pm

I think it’s about time I wrote another article, don’t you?

The funny thing is that I’ve had a draft sitting half-completed for a few weeks now, and this isn’t it! In that draft, I’ve written about some nice (some may say, essential) features for your development tools, because that’s what I’ve been working on for Pandemonium lately. However, a post on the XNA Creators Forums the other day caught my eye, and reminded me of when I used to work on the in-game camera for Kameo, and then I put the disc in my 360 for old-times’ sake, and that inspired me to start this mini-series on third person cameras, based on what I learned during the development of that game. (I’ll almost certainly finish the tools article next, then come back to this mini-series, and so on like that for a while, dipping in an out of each. Note that I don’t promise this mini-series will finish, or even progress, quickly! But over time, it should add up to have some pretty cool ideas).

Incidentally, for those of you who haven’t played it, you can almost certainly pick up Kameo in the bargain bin nowadays and it’s well worth a look. It’s not without its flaws (some of the adventure sequences are a bit dull and the story doesn’t always make complete sense), but it’s still one of the most vibrant and refreshing titles available on the Xbox 360. The combat sequences are pretty good fun, it’s got some really memorable bosses, a phenomenal soundtrack, and (especially given that it was a launch title) it looks very pretty – I defy anyone not to watch dawn break over the Enchanted Kingdom and not go “wow”. It got some criticism at the time for being a bit short for the money, but by criminy it’s eight quid on Amazon now! Probably even cheaper somewhere else. Get involved.

The Very Beginning

Anyway with that bit of blatant and shameless advertising out of the way, let’s talk cameras, starting at the very beginning. The camera is what shows the player what is going on in any 3D game. The player never sees it, and they can’t always control it, but without it you’d be stuck. It is exactly analogous to a movie camera – it’s there to show the audience (the player) what the actors (the player’s avatar and other in-game characters) are doing. Everything in the game world that you see on the screen, you see from the camera’s point of view.

The mapping from the 3D game world to your 2D television screen is called a projection; I won’t go too deeply into the maths just yet (and in fact in XNA, DirectX, OpenGL and other 3D SDKs, functions exist to perform much of the maths for you) but basically a projection transforms a 3D vector in world space to a 2D vector in screen space. Fundamentally speaking there are two types of projection (hence, two types of game camera).

An Orthographic camera performs a parallel projection. Basically, this has the effect that something 2 metres tall 100 metres away, looks the same size on screen as something 2 metres tall 5 metres away, and the viewer can only tell which is closer by seeing which is drawn in front of the other. This is not how we are used to seeing the real world, so isn’t much used in games nowadays. That said, the old isometric games show what an orthographic projection looks like (even if they’re not truly rendered in 3D), and it’s sometimes used for user interfaces, maps and such like. In fact – if you’ve ever used a 3D modelling tool like Max, Maya, Milkshape, Blender etc., you’ve almost certainly used an orthographic projection in the “side-on” or “top-down” views. I won’t go into too much detail about these here though; if you’re interested, look up Matrix.CreateOrthographic in the XNA documentation.

Much more common in games is the Perspective camera, and that’s the type of camera I’m going to concentrate on in this series. In this projection, items closer to the camera are drawn much larger than items the same size that are further away, which matches human eyesight.

The Perspective Projection

We need to know a certain amount of information in order to be able to perform the perspective transformation. First is the field of view. This value represents how wide an angle the camera can see, and by convention is usually given as the vertical angle – the vertical field of view, or sometimes abbreviated to fovY. (Some modelling tools use the horizontal field of view instead, so be careful). Next is the aspect ratio. Computer screens are rarely square, and never circular (like the human eye can see), so the aspect ratio gives the width of the projection compared to the height of the projection.

Deciding on what values to use will depend on your game, but as a starting point, consider that the human eye has something like a 150 degree vertical field of view, and an aspect ratio of something like 1.15, ie. you can see more horizontally than vertically. However – nobody ever sits so close to a computer screen that it fills their entire field of view, and the angle from your eye to the top and bottom of your monitor is usually something like 45 degrees, so that’s a good starting point for your field of view; and the aspect ratio is easy. If your monitor or television is “standard” 4:3, the aspect ratio is 4/3 = 1.3333, while if it’s “widescreen” 16:9, the aspect ratio is 16/9 = 1.7777, etc. (And therefore, if the camera view only fills part of the screen in your game, the aspect ratio will simply be the width of the view window divided by the height). We’ll talk more later about what effect changing these values has – you can get some desirable special effects, and some undesirable bugs, by altering them.

Important note: I’ve used degrees for the field of view above, because that’s what most people are familiar with. Most 3D systems, including XNA, use radians for angles instead – and if you get funny results, it’s probably because you’re using the wrong units! You can use MathHelper.ToRadians to convert from degrees to radians, or some special values have predefined constants, for example 45 degrees is the same as MathHelper.PiOver4 radians.

There’s a couple more values needed for a perspective projection but, unlike field of view and aspect ratio, they don’t have a counterpart in the real world. Your eyes can see things right next to them, even touching them (I had a wasp walk over my eye, once – it was terrifying!) and, if nothing gets in the way and the light has time to get to you, infinitely far away as well. That gives an infinitely large range – and computers are very bad at handling infinity. To make life easier for the computer, we define a minimum and maximum distance – the near clip and far clip values – outside of which, we don’t want to draw anything. Choosing these values is very much game-dependent. In a game where a human is the main character, a near clip of 0.1 metres and a far clip of 1000 metres might be OK. In a game based around spaceships travelling light years in a few seconds, that wouldn’t work! Again, there is a relationship between the near clip and far clip distances that you don’t want to get wrong, and we’ll talk about that later.

I like to think of this as being like sitting in a dark room with one window. You sit in the room and look out. You can’t see anything in the room, it’s too dark (even if there’s something between you and the window – yeah, the analogy breaks a bit there) so the distance between you and the window is the near clip distance. Outside the room, you can only see things that pass behind the window – anything in the vertical field of view (the angle between your eyes and the top and bottom of the window) and the field of view modified by the aspect ratio (the ratio of the width of the window divided by the height. In your imagination, draw a line from your eye to the edges and corner of the window. Can you see that this would form a pyramid? Now extend the lines, out into the world beyond the window. Stop at your far clip distance. Now you have a really big pyramid. Take off the smaller pyramid (inside the room) and you’re left with a shape called a frustum, in this case, a view frustum. Everything inside this frustrum can be seen through the window – so everything in the view frustum in your game will be drawn to the screen. It looks a lot like the red shape shown here (based on original diagram here):

The view frustum of a perspective projection

The view frustum of a perspective projection

(Note, I’ve not shown the horizontal field of view, it should be obvious. However, the maths to calculate it isn’t… it’s not fovY * aspectRatio, as you might guess. It’s actually 2 * atan( tan( fovY/2) * aspectRatio ), for reasons of geometry. Aren’t you glad you wondered, now?)

The maths to perform the projection from items in the frustum onto the screen is a bit complicated, luckily, it’s all done with Vector3’s and Matrix’s, and XNA provides a function to generate the projection matrix (which performs the transformations of your perspective projection): Matrix.CreatePerspectiveFieldOfView, which takes as arguments the field of view, aspect ratio, near clip, and far clip, exactly as just described.

Defining the Camera View

So now we know how a view frustum performs a projection to draw things in the game world, onto the screen. But which things? Or to put it another way: how do we position the view frustum to show what we want? Answer: by defining the position and orientation of the camera.

It’s pretty obvious what the position means. If it were a “real” camera, like in a movie, it’s the point in space where the camera (or perhaps more specifically, the camera lens) is. You just need to make sure you put it somewhere sensible so the player can see what’s going on. (How? We’ll get to that!)

The orientation is fairly straightforward too. It’s the direction the camera is looking in – this gives us the camera’s forward vector, literally, the direction you’d move in to make the camera go forward. Obviously, you’ll want this to point at whatever the player wants to see, and again, we’ll talk about how later… Of course, you can hold a camera upside down (and, if you’re making a flight sim, your planes can fly upside down!) so we also need to know which way up the camera is being held: the up vector. Finally, it’s sometimes useful to know the right vector – think of your head. Your eyes are looking in front of you (the forward vector), the top of your head is usually towards the ceiling, unless you’re doing yoga or something (the up vector), so the right vector is pointing out of your right ear. These three vectors are mutually orthogonal, which is a posh way of saying there’s ninety degrees (or MathHelper.PiOver2 radians!) between each of them. (See diagram here).

 The tricky bit comes in deciding how to represent the orientation. (It’s important to understand the following are all different representations, and for any given orientation, it’s possible to represent it in any of the following ways). We can either simply pick a point in space, and say “the camera is looking at this point” – this is the target or look-at point.

Or, we can assume that the “natural” orientation of a camera is for the forward vector to be looking down the Z axis (known as -Z, -Vector3.UnitZ, or Vector3.Forward – remember XNA uses a right-handed coordinate system!) and the up vector is directly upward (known as +Y, Vector3.UnitY, or Vector3.Up). Of course this implies that the right vector is along the X axis (+X, Vector3.UnitX, or Vector3.Right). From this “natural” orientation, we can rotate it – either using angle values for yaw (rotating horizontally around the Y axis), pitch (rotating vertically around the X axis), and roll (rotating side to side around the Z axis), known as Euler angles (pronounced “oiler”), or by using a single Quaternion value. Each of these methods – Euler and Quaternion – have advantages and disadvantages (Euler is easy to understand, but can encounter issues in certain orientations that quaternions, to all intents and purposes, don’t) and which to use depends on your game. If you’re making a flight sim or other game in which the camera can roll a lot, use quaternions. Otherwise, either can be made to work, and Euler angles are certainly easier to conceptualise.

We can combine the position and orientation into a single view matrix for convenience, and no prizes for guessing that XNA makes it easy, via Matrix.CreateLookAt, Matrix.CreateFromYawPitchRoll, and Matrix.CreateFromQuaternion.

Our projection matrix and view matrix now tell us everything we need to know. When we went to draw something, we pass these matrices to the shader (sometimes along with the World matrix, which represents how the game world or object being drawn is transformed; in the case of the game world, it is usually Matrix.Identity) and it performs the complex transformation maths for us. Note that the projection matrix might not change much during gameplay, but that the view matrix might change in every frame that the camera moves.

So all that’s left is to work out where to put the camera, ie. what values to pass in, in order to get the appropriate view matrix. Should be easy! Right? Well… the number of games reviews where I’ve read “game X has a really bad camera”, and the fact I spent probably 40% of my time for three years coding Kameo’s camera (happily no reviews I saw complained about it), suggest it’s not that simple. (Don’t get too scared. Kameo had 11 player characters and over 20 camera modes. Your game will probably be a lot simpler!) So how can we decide where to position the camera?

Deciding the Camera Position

At a very high level, there are basically three ways to decide how to position and orientate the camera, and they arise from the way that in most cases, you either have something you want to look at, or somewhere you want to look from, or both. (If you have neither, and don’t know where you are or what you want to look at, well, good luck with that!).

First consider the case where you know where the camera is, but you don’t know what you want to look at, just a direction. The most obvious example of this is the first-person shooter. The camera is inside the player character’s head, and the player decides in which direction to look and move. Or, imagine a driving game or flight sim where the camera is placed inside the car or plane, looking out of the front window. This kind of camera is very simple: the position is known, and you can use Matrix.CreateFromYawPitchRoll (for example in a FPS) or Matrix.CreateFromQuaternion (for example in a flight-sim interior camera) to work out the rest of the view matrix.

Example: Halo.

Secondly, imagine you know where the camera is, and also know what to look at. An example might be a track-side camera in a racing game: it’s fixed in position, but as a car races past it turns to follow it. Or, imagine a security camera that follows the player (a bit like in Ico). It’s even easier if the camera is fixed in both position and orientation, like in the early Resident Evil games. Again, this kind of camera is very simple: the position is known, and you can use Matrix.CreateLookAt to work out the rest. (Of course, track-side cameras should have some inertia to follow the cars more naturally, and the camera in Ico has quite a few more complex features as well, but the basic functionality is very straightforward).

Example: Ico.

The final category (and by far the most interesting) is where you know what you want to look at, but not the position you want to look at it from. Many game genres fall into this category.

Sometimes, it’s fairly easy to work out where the camera should be. In an arcade racing game, the obvious target is the player’s car; and the player will want to see where they are driving. So, you need to position the camera somewhere behind and above the car, looking somewhere in front of it. Of course, you’ll want the camera to follow the car as it turns, and if the player reverses into a wall you need to make sure the camera doesn’t go on the other side of the wall, but still, this is pretty straightforward. (An example from a non-racing game might include the early Tomb Raiders, and I think the Gears of War over-the-shoulder camera probably belongs here as well).

Example: Project Gotham Racing 4.

Another example of this category is to be found in the RTS genre. Here, the camera looks at the units or terrain the player is interested in, but the player can control where it looks at them from. Assuming you position the camera high enough not to bump into buildings and trees, again, this is quite straightforward – store the look-at point and move it around the battlefield, then let the player control the angle they want to view it from, and position the camera a fixed distance in that direction.

Example: Age of Empires 3.

So finally we come to the most interesting cameras of all, and the ones I will be concentrating on in this mini-series: the third-person camera. In games of this kind, the camera and the player are controlled independently. The camera must move around the game world, giving a good view of the player character, while moving around and among the terrain the player moves around and among. There are some very difficult (and hence interesting) problems to overcome – how do you stop the camera going through walls? How do you ensure there is always a good view of the player? To what extent should you let the player control the camera position – and even more importantly, to what extent should you require them to? Games with cameras like this include platformers, like Mario or Banjo Kazooie; parkour-style action games like Prince of Persia; and adventures or RPGs like Fable, or, of course, Kameo.

Check out this screenshot of Kameo in action. She’s standing among the tall grass now, cheekily glancing back at the camera – but she could move in any direction and the camera would have to follow her. She could go for a swim, run around the tree, move right up to the edge of the cliff, go into the house; climb to the very top of the castle and jump off it. No matter what she does, the camera has to follow her, and show her doing it in a way the player can understand and react to. That’s not easy! But it is absolutely fascinating. I hope this series will demonstrate that, and you’ll find it entertaining and useful.

Anyway I’m moving house next week – so not sure when the next update will be – so, until next time, farewell from me…!

January 22, 2009

It’s not the size that counts

Filed under: Games Development,Games Industry,Personal,XNA — bittermanandy @ 10:37 pm

Indulge me as I walk down memory lane…

It was summer 2002 and I’d just landed my first professional job. (I’m still not sure how. I wasn’t very good back then. I like to think they saw that I’d become good, and I like to think I am good now. It might just have been luck!). I’d spent some time in the RnD department, to learn the ropes, become familiar with devkits (console hardware with added stuff to enable game development), and understand a bit about how the shared game engine worked; and then the time came to move onto a game team, of which there were five or six to choose from. The choice wasn’t freely given. Each team had different needs, so the question was asked: what did I want to work on? What did I want to specialise in?

I didn’t really know how to answer that. I was vaguely aware of the division between systems programming and gameplay programming, and knew that I preferred the former (I actually think the latter is better solved by a good data-driven system and a good designer, though I have worked with gameplay programmers who produced excellent results); but which system? And how would my choice affect my working day?

Games teams on “AAA” titles nowadays can easily have several tens of programmers. Clearly, if they all worked on whatever they fancied from day to day it would be a disaster. Each programmer therefore gets designated an area of responsibility. Generally speaking, the programming lead and the most senior programmers determine the overall architecture of the game early in development (or it may be mandated by the engine, particularly if it is middleware), and the programming team splits into several sub-teams, each led by a senior programmer who reports to the lead programmer. Examples of roles in the team (in no particular order) include:

Graphics: the celebrities of programming because they get to write code that produces awesome looking screenshots (or at least… code that lets the artists do so). Every time the publishers come for a visit, they’ll get led into the graphics programmers’ office and shown all the latest particle-laden explosions on flashy HDTVs. Graphics programmers spend a lot of time writing shaders, optimising the renderer, and talking with artists.
Networking: modern games are immensely complex and with multiplayer online being practically compulsory nowadays, every game will have network specialists. They tend to spend all their time trying to teach other programmers how to write code that doesn’t break the online mode, for example by sending 600KB packets every frame or updating something on the local client but not the game server. They usually look a bit stressed.
Physics: even with middleware like Havok (or in XNA, JiglibX and the like) available, physics remains one of the most complicated things in a game because it affects just about everything else. One game I worked on had five physics programmers.
AI: most games have enemies or some kind of non-player entity. While scripting and other designer-facing tools mean AI is not as hard-coded as it once was, someone’s got to write the code that interprets the scripts – that’s the job of the AI coder.
Audio: given that the only two ways your game can influence the player is via the screen and the speakers, audio is half of every game. Unfortunately it’s the second half (because it doesn’t look good in screenshots) and all too often audio is neglected. Done well, it can turn a good game into a mind-shatteringly atmospheric epic. Audio coders spend a lot of time talking to the musicians and SFX engineers, and they’re usually slightly bitter that the graphics programmers get all the plaudits (and flashy HDTVs).
Tools: there might be twenty programmers on a team, but there might be ten designers, fifty artists, and five audio engineers (as well as testers, producers, marketing, translators…). You can’t just give them a copy of Photoshop and Maya and tell them to get on with it. Every game needs specific tools that enables these people to get their assets into the game and tweaked until fun and in my experience, the better the tools the better the finished game.  Historically tools were DOS-based and unreliable; increasingly, they’re now written in C#/.NET and actually work more often than not. Tools programmers are the unsung heroes of the programming team. Their work is almost never seen by the public, but without them, the game itself won’t get seen by the public either.
Systems: asset loading. The game camera. Multithreading. Save games. Text, and menus. Achievements. DVD file layout. TCR compliance (rules that the console makers require you to obey before your game can be released). Support for steering wheels, dance mats, webcams and chatpads. The build process (putting together versions of the game to give to artists, management and testing). A veritable pot pourri of tasks that no game can go without. Some of these tasks will be given to the most senior programmers because they’re critical to the game’s success. Others will be given to the most junior programmers because they’re relatively self-contained and can be developed in isolation. Most don’t get noticed, until you try to make a game without them!

There’s more, but that’s a good initial summary. (Just think – when you write an XNA game, you’re responsible for all of the above! Lucky XNA itself is brilliant at doing it loads of it for you). My first ever task on a game team was to write the game camera, and looking back I’m pretty proud of how it turned out. Very soon afterward I also took on the audio programming. Eventually, on that first game (I worked on it for three years – some were working on it for twice that), I was responsible for, or otherwise involved with, text and menus, localisation (making the game support other languages), asset loading, the build process, save games and TCR compliance. Later I’d work on asset optimisation and arranging files on the DVD, and probably some other stuff I’ve forgotten. So it became clear: my specialisation was that I was a Jack-of-all-trades. Hurrah!

With all these people working on different things, it’s critical that they don’t interfere with one another by writing over one another’s changes. This is achieved by use of a Source Control System. Basically, this keeps track of every code file and asset in the game, keeps records of how they change over time, and tries to ensure that if two people make changes at once, those changes are seamlessly merged together. Different teams use different products and approach this in different ways. Some examples using the codenames of games I worked on:

Game Two: used CVS for source control. This is an horrific abomination that should be scourged from the earth. A coder would make all the changes he wanted, send out an email to the team saying “please don’t commit”, commit all the files he’d changed, and send another email saying “OK to commit”. Inevitably he’d have missed something so the next coder to update would have to come and ask him to fix the problem before they could continue. Worst of all, the artists couldn’t get anything into the game without giving it to a programmer to commit it for them. This was frustrating for everyone involved and meant that changes to a level, for example, could take two or three days to get into the game. Putting together a build was an eight hour manual process; all too often it wouldn’t start until 5pm the night before a deadline. I’m not completely sure how we managed to get the game finished, and I’m stunned that it turned out as good as it did despite everything. This is How Not To Do It.

Pocket/Pikelet: an improvement in every area, these teams used Source Depot (basically the same as Perforce) for source control. No more emails to control who could commit – a tool that lived in every developer’s System Tray would lock out commits while someone was going through the process of updating, building the game, running the unit tests and committing. A separate build machine would then automatically update to that version, run the tests again and if they were passed make the build available to all the non-programmers – who, incidentally, had the tools available to do all their work without needing to go through a programmer. It was brilliant, broken builds and artist downtime were unheard of – the game was bulletproof throughout development. There was only one small problem. Updating, building, running unit tests and committing took half an hour or more. In a normal eight hour day, only sixteen programmers could do it – at most. With twenty programmers on the team, there’s an obvious problem and it got very frantic near deadlines – and leaving at least a day between committing meant that you’d commit too much at once, introducing bugs (which would fail the unit tests and delay your commit even longer). This was a problem, but in general this was the best system I’ve had the pleasure of working in.

Polished Turd (not the real codename, just what I call it): again this used Perforce for source control, except this time without a formal commit queue like Pocket/Pikelet. The commit queue had originally been introduced to stop CVS from breaking everything, but Perforce is so much better than CVS that actually things rarely break even if you’re free and easy with committing. It meant that you could fix a bug, commit your changes, fix another bug, commit your changes, and iterate very rapidly through your work. You’d update over lunch and overnight, or when you noticed someone had committed something you need. If we’d only had the same team build system, unit tests, build suite, and artists tools from Pocket/Pikelet this would have been the ideal way of working. (Unfortunately all those things didn’t exist so the game was unstable, the artists couldn’t do their job, and every deadline was a mad scramble to put together get something vaguely playable that lasted more than five minutes between crashes).

Now, most people reading this will be hobbyists working in XNA on their own. At the moment, that applies to me too. However, I’m uncomfortably aware that the big blue blobs and soulless grey polygons that currently represent the actors and props in my game won’t inspire other people to play my game – and I’m closer to being autistic than artistic. So sooner or later, I’m going to need other team members to make models, textures, animations and sound for me. (Any volunteers?) And, while I’m currently planning to save all the coding duties for myself (with the XNA Framework itself and the multitude of excellent community libraries out there, this is a realisitic proposition in a non-trivial game for really the first time this side of about 1998) many of you will no doubt be thinking of forming small coding teams, to split the work among you. (I don’t blame you. Just look at the list above. Even a simple game has a lot to do…) So – how well does XNA support medium-to-large game teams? And what would such a team require?

Source control is absolutely essential the moment your team grows larger than one. And, with a team of one or two, there’s only one choice – Perforce, which is free for up to two users, and so good I use it even though no-one’s forcing me to. Unfortunately, as soon as your team size hits three people, it’s something like $700 a license. Ouch. Worth absolutely every penny and more if you’re a pro developer with your outgoings covered by a publisher, but out of reach of everyone else. I am told that Subversion is good for a free product, but I look at the lack of atomic changelists and cringe. Probably the next best if you can’t afford Perforce though. There’s nothing here that’s different for XNA than if you were using C++ or any other language.

It will be essential to have a configuration of your game that allows your artists to put their assets into the game without waiting for you to do it for them. The XNA content pipeline is a wonderful, wonderful thing of great beauty, but by default it is tied into Visual Studio – the content pipeline build occurs just before you run your game, and that’s it. An artist doesn’t want Visual Studio, and he doesn’t want to restart the game every time he changes a texture – he should be able to save off the texture file and see it change in-game. So you need to provide them with a version of the game that runs on its own (perhaps in a WinForm) and a tool that hooks into the content pipeline and will let them build assets while the game is running, notify the game, and the game then reloads that asset. This is pretty easy for assets that already exist in a content project, but the tool will need to support adding to the content project (hidden from the artist) and even creating new ones. All this needs to hook into your source control system without your artist needing to learn to type “p4 -d -a -q -z” or whatever.

The content pipeline causes a few other problems too. (Though don’t think for a second that I’m knocking it. What it does is amazing). Big games tend to generate thousands, even hundreds of thousands of assets – and in the content pipeline, each of those is a different file. People often don’t realise that opening a file, even from a hard drive, can sometimes take as long as a quarter of a second. That doesn’t sound like much until you multiply it by a hundred thousand. (You can very easily see this for yourself by using WinZip to zip up one large file of say 10MB, then compare it to zipping up a thousand files of 10KB each – I guarantee the latter will be much slower). To give an XNA-related example: Kameo, Pocket and Pikelet all used XACT, the same audio tool as provided with XNA (and which I’ve used very extensively). Pocket, in particular, had well over 200 soundbanks which all needed loading at startup. Even though they were only between just 1 and 4KB each, this took a long time to load from the DVD – so long that the 20 second load time mandated by Xbox 360 TCRs seemed an impossibility. The fix was pretty simple: we altered the build process to package all those soundbanks into a single file, loaded the file into memory, and loaded the soundbanks from that memory. Instantly the problem was solved. The same solution won’t work in XNA: there’s no method to load soundbanks from memory. It expects each soundbank as a separate file, and that’s that. A big game in XNA would really struggle under such restrictions. (Loading on a background thread won’t help, 20 seconds of disk access is 20 seconds of disk access and that’s that, though admittedly an XNA game would be on a hard drive not a DVD which helps a lot). You’d have to plan ahead very carefully – in terms of the game design, not just code; which is hard, because designers don’t understand arbitrary restrictions from code, and nor should they have to – to ensure that there was never a need to load so many individual files all at once.

With these caveats in mind I’m convinced a medium-to-large game can realistically be made in XNA. The “poor performance” of C# compared to C++ is for the most part a myth, though to get the absolute 100% optimum out of the hardware might require C++ – but you could get at least 95% of the way there with C#, and 98% of all games don’t need 100% performance. It’s unfortunate that the biggest win for hobbyists and small-team endeavours – the brilliant content pipeline – appears to be the biggest limiting factor for large teams. The issue of when and how assets are built, and how they can be rapidly iterated without restarting the game, is definitely solvable, though with a fair bit of coding effort; the fact that so much of the pipeline relies on a one asset, one file relationship is trickier. A hundred-thousand-asset game would need a hundred thousand files, and loading times would be horrific.

So really large games might not be easy in XNA. Happily (?) few large games nowadays are single platform, and since XNA is not available on PS3 and Gamecube, I don’t think many large teams will be evaluating XNA anyway. Medium teams, independents, and small hobbyist teams can definitely have a field day with it (though profitability of XBLCG at least has yet to be proven). Just remember that the limiting factor for such games is content, and put a lot of effort into making your artists’ lives easy. If they can make a model, put it in your game, play with it, tweak it, play with it again, tweak it, play with it, and check it into source control, they’ll beg to be allowed to make more. If they have to send you the model and wait two days for you to send them a build with it in, they’ll give up within a week. Frankly – even if you’re working on your own, and doing all the code and art yourself, a little bit of work to make good tools will make your own life easier; and isn’t that what we all want?

January 21, 2009

Any requests?

Filed under: Games Development,Personal,XNA — bittermanandy @ 1:51 pm

Wow, it seems like an age since I posted. I guess that’s because it is! Fable 2 took up far more of my time than I expected, I’ve barely touched Nuts and Bolts, and I still have to complete Tomb Raider and Prince of Persia before March, when Empire: Total War is released. This doesn’t leave much time for any meaningful development on Pandemonium, though I have recently chucked together a few little prototypes of stuff I might one day make into fully-developed games.

Anyway I don’t know when it will be that I’ve done enough on Pandemonium to make an update worthwhile. But I don’t want to leave the blog stagnant, it’s still getting a fair number of hits every day and people must have expectations… so I’ll put the question out there: is there anything (preferably XNA-related) you want to read about? Check out the stuff I’ve already written to get an idea of the kinds of things I know. Clue: I’m not the man to ask about whizz-bang graphical effects, but if there’s anything else you’d like to see, just ask.

December 6, 2008

Foundations

Filed under: Games Development,XNA — bittermanandy @ 12:04 am

Wow, what a time. After having barely played a game all year, I spent weeks playing Fable 2 (very good, though could have been even better), and I’m about to get cracking on Banjo Kazooie: Nuts and Bolts (the last game I worked on before leaving Rare) and Banjo Kazooie XBLA. I’ll be getting Tomb Raider Underworld and the new Prince of Persia for Christmas, and sometime in January, I’ll be surrendering every waking moment to Empire: Total War (seriously – I plan to take a week off work when it comes out). I’ve not so much as had a spare second to check out the games on Xbox Live Community Games, which probably makes me a terrible hypocrite who will be punished in the afterlife. Frankly it’s beyond a joke. I don’t even have enough time to play all of these games, all coming out within two months of each other – never mind time for my other hobbies!

Fortunately the other day I managed to squeeze in a few hours with XNA and spent the time fixing up a few odds and ends I’d been meaning to look at for a while. Specifically, I rearranged the structure of my engine and game code, for clarity and useability. It’s well worth emphasising a couple of points here: first, while I’ve built up this structure after a fair bit of experience with professional game engines and a lot of careful thought, there are undoubtedly other ways of doing it. I encourage you to hunt around, look at what others have done, and deeply consider what will work for you. Second, this is very much a work in progress. I will undoubtedly be tweaking things yet further as time goes by, and I’ve had to make a few decisions “blind” – I’m pretty sure they’re the right choices but it’s entirely possible I’ll reverse them later as experience dictates.

So. At the highest level, the XNA code I write is split into two general groups: engine code (shared code, usable by more than one game, written in such a way as to be reasonably general purpose without being so abstract as to be useless); and game code and assets (specific to one particular game, though sometimes code can start life here before being moved into the engine later). In an ideal world, all your code would exist in the engine, and there would be no game-specific code at all. Games would be differentiated only by their assets – the single executable built by the engine would search for an XML file or similar, that would define what other assets to load, and by a combination of scripting and data-driven design, the game would run with no unique code at all. Realistically, that’s not an achievable goal, and a game will always have game-specific code. The trick is to find a balance.

(First a plea. Don’t “write an engine”. The XNA Framework is so close to being an engine that such a task is pointless, and you’ll also find that no-one will use it – because you won’t have solved the problems you’d encounter if you wrote a game. Hobbyist DirectX programmers all set out to write an engine, and barely any of them ever complete a game. In fact, it wouldn’t be bad advice to write a game first, then only when it’s finished, go back and look at how it can be separated into engine and game code, ready for your next game).

Anyway, let’s have a look at the folder structure of the engine and the games in turn. You’ll want to store all your stuff in a single folder – mine are in Documents\Code\XNA – Visual Studio will encourage you to put everything under the Documents\Visual Studio 2008 folder, but that’s a really bad idea because when Visual Studio 2010 and XNA 4.0 come out you’ll just have to move everything, which apart from being generally inconvenient can be a royal pain if you’re using source control!

Engine Folder Layout

My engine is codenamed Kensei, and is therefore stored in the Kensei folder. Here, you will find the Kensei.sln Visual Studio solution file, as well as my Kensei.FxCop project (with CustomDictionary.xml) and a couple of handy batch files which I’ll come to in a minute. Everything else is stored in subfolders, corresponding to the code projects that are referenced in Kensei.sln (which in turn correspond to the assemblies that can be used by my games).

Kensei – the “core” project containing the majority of the code I write. In here exists my audio engine, camera management code, handy development utility code, command pattern implementation, and everything else I’ll come up with as I add features. Each logical unit is stored in a subfolder of this folder, so for example my audio code exists in Documents\Code\XNA\Kensei\Kensei\Audio – but it’s all built together in a single C# project called Kensei. (I’ve worked on games where each logical module had its own project. It just meant we ended up with fifty-odd projects and fifty-odd assemblies where one would do. It might make it easier to keep things decoupled, but adds headaches via complexity, especially as C# makes circular references awkward or worse. Don’t bother).

Kensei.EmbeddedResources – there are a few things in the Kensei engine that require specific assets. For example, Kensei.Dev uses a font for simple text and a shader for simple shape rendering. At first, these assets had to be copied into the content project of each game prototype I created but that quickly became a pain. The answer (as Shawn Hargreaves describes expertly) is embedded resources.

Kensei.Pipeline and Kensei.Pipeline.Runtime – XNA makes working with assets an absolute dream and most non-trivial games will extend the content pipeline to support custom asset types. Kensei.Pipeline extends the content pipeline itself, while Kensei.Pipeline.Runtime acts as a bridge between the content pipeline and the game – again, Shawn explains in full.

DebugContentBuild – it’s an inevitable fact that all code has bugs, so I followed Stephen’s advice and created a project that vastly simplifies the process of debugging my content pipeline extensions. Basically, running this project attaches to MSBuild.exe and runs the content pipeline on the assets in its content project – allowing me to step into my Kensei.Pipeline code and see where it’s going wrong.

(Other Code Projects) – one of the things I love about the XNA community is the easy willingness with which people share their work. Make use of it! I don’t want to spend my hobby time reinventing the wheel or rewriting something someone else has already done perfectly well (unless, of course, it’s the main differentiating point of my game, or something I have a specific interest in doing or learning. Always in-source your USPs, but don’t even attempt to do everything yourself!). Therefore, my Kensei engine solution contains projects for JigLibX, the Curve Editor Control, and a few other public components, as well as code supplied with various books I own. Which books should you own? Start here!

External – of course, some code isn’t supplied with source, but as a standalone assembly. For example, I use Perforce for source control (accept no substitute! It’s the best there is, period – it’s so good, I use it even though I don’t have to, and I’ve not yet come across any other source control I’d say that about) and the rather wonderful P4.NET lets me write the ability to work with Perforce into my tools. This allows my game editor to automatically check out assets that I work on, for instance. This, and other such assemblies, are all stored in the External folder (with a handy text file so I don’t forget where I got them from…).

Now, with all these projects and assemblies floating about, each built into their own build directory, finding them from the individual games becomes awkward! It’s much easier when all the engine assemblies are in the same place. With this in mind, I wrote the following PostBuild.bat batch file. Every project in the solution runs this as a post-build step (details in the script itself). It copies the output files of the project into the bin folder, so when I create a new game, I only have to look in that one folder for all my references.

@echo off
rem ————————————————————————
rem Run this script as a Post Build Step from every Kensei library to be
rem used by a project or game outside of the Kensei solution.
rem It will place all built files into solution\bin\platform\configuration.
rem This will make them easier to find when adding references.
rem ————————————————————————
rem Post Build Step:
rem
rem call “$(SolutionDir)PostBuild.bat” “$(SolutionDir)” “$(PlatformName)” “$(ConfigurationName)” “$(TargetDir)” “$(TargetName)”
rem ————————————————————————

echo —- Post Build Copy —-
echo Copying %4%5.* to %1bin\%2\%3…
xcopy   %4%5.*   %1bin\%2\%3   /Y   /I   /F

Finally, with all these assemblies floating around, it’s nice to be able to clear everything out and know that a build will start completely afresh. (Why does “Clean” do nothing on a C# project? Alright, Visual Studio handles C# a hundred times better than C++, but I still sometimes want to know that everything that isn’t a source file has been deleted). So I wrote a CleanAll.Bat (warning, use at your own risk, especially if you make use of folders named ‘obj’ or ‘bin’):

@echo off
rem Script to completely start afresh without *anything* still hanging around from previous builds.
rem This is useful to, for example, check what would happen if it was checked out on a clean machine.

echo ——————————–
echo Delete Visual Studio local files
echo ——————————–

del /Q /S *.csproj.user
del /Q /S /AH *.suo

echo ————————————
echo Delete intermediate and output files
echo ————————————

FOR /R %%i IN (*) DO IF EXIST “%%i\..\obj” rmdir /Q /S “%%i\..\obj”
FOR /R %%i IN (*) DO IF EXIST “%%i\..\bin” rmdir /Q /S “%%i\..\bin”

echo.

That’s pretty much it for the Kensei engine (well, more or less, as you’ll see in a moment). After seven or eight years with playing around with Visual Studio and trying to arrange large game projects in a way that preserves my sanity, I’m pretty confident that this layout is the easiest to work with.

Game Folder Layout

The whole point of the above is to make creating new games prototypes quick and easy. I’ve got ten or twelve game ideas in my head right now, although Pandemonium remains my main focus, and every time I get a new one, I like to be able to spend one evening slapping something together that just works with a SpriteBatch (for 2D) or Kensei.Dev.Shapes (for 2D and 3D) without spending any time at all plugging the lower-level stuff together. So, all my games exist in the Documents\Code\XNA\Games folder, and reference assemblies in the Documents\Code\XNA\Kensei\bin and External folders. Taking Pandemonium as an example, Documents\Code\XNA\Games\Pandemonium contains (as you’ll have come to expect) the Pandemonium.sln Visual Studio solution, and the Pandemonium.FxCop file (and CustomDictionary.xml) as well. Then there are the following projects in the following folders – again you should be able to guess what they are, and they should be fairly self explanatory when read in combination with the above:

Pandemonium – the game itself. Of course, the content project and all assets are stored in here too.
Pandemonium.Pipeline – content pipeline extensions for the game.
Pandemonium.Pipeline.Runtime – a bridge between the two.

It really is as simple as that, and if I were just writing a quick prototype there would probably only be the first one.

Engine.Game

There’s one project I didn’t mention above in the Kensei engine. I’ve only just started doing things this way, and although so far it’s working well I’m a little concerned it may prove inflexible in the long run. I’d encourage you to experiment with it – after all, if a particular game finds it hard work fitting into this model, just don’t use it. It will save you a lot of time on those games that work alright with it.

Basically, I’ve created a project named Kensei.Game, and it contains a single class, Kensei.Game, which derives from Microsoft.Xna.Framework.Game. (Unimaginative names, I’m afraid…) If you’re wondering why it’s a separate project and not part of the Kensei project, that’s because it uses code from all the different assemblies and it was easier to keep it apart than try to prevent them from referencing one another in a circular manner. The idea is, that all of my games can inherit from Kensei.Game instead of (more directly) Microsoft.Xna.Framework.Game, and Kensei.Game can handle all of the things that each individual game would have to do for themselves.

Allow me to provide an example. Kensei.Game provides the following (sealed!) implementation of the Draw method: 

/// <summary>

/// This is called when the game should draw itself.

/// </summary>

/// <param name=”gameTime”>Provides a snapshot of timing values.</param>

protected sealed override void Draw( GameTime gameTime )

{

    // Prepare the game for drawing

 

    if ( Kensei.Dev.Options.GetOption( “Draw.Wireframe” ) )

    {

        GraphicsDevice.RenderState.FillMode = FillMode.WireFrame;

    }

 

    if ( Kensei.Dev.Options.GetOption( “Draw.CullModeNone” ) )

    {

        GraphicsDevice.RenderState.CullMode = CullMode.None;

    }

 

    Color clearColour = Color.Black;

 

    if ( Kensei.Dev.Options.GetOption( “Draw.CornflowerBlue”, Kensei.Dev.Options.BehaviourIfNotPresent.ReturnTrue ) )

    {

        clearColour = Color.CornflowerBlue;

    }

 

    GraphicsDevice.Clear( ClearOptions.Target | ClearOptions.DepthBuffer, clearColour, 1.0f, 0 );

 

    GraphicsDevice.RenderState.DepthBufferEnable = true;

    GraphicsDevice.RenderState.AlphaBlendEnable = false;

    GraphicsDevice.RenderState.AlphaTestEnable = false;

 

    // Perform game-specific drawing

 

    DrawGame( gameTime );

 

    // Complete drawing

 

    Kensei.Dev.Manager.Draw( GraphicsDevice,

        WorldViewProjectionMatrix,

        Window.ClientBounds.Width,

        Window.ClientBounds.Height ); 

    base.Draw( gameTime );

}

 

/// <summary>

/// This is called when the game should draw itself.

/// </summary>

/// <param name=”gameTime”>Provides a snapshot of timing values.</param>

protected abstract void DrawGame( GameTime gameTime );

What this means is that each individual game I write has much, much less to do in it’s (abstract) DrawGame method. I can’t forget to call base.Draw, and I always get the benefits of the same Kensei.Dev options and Kensei.Dev.DevText and Kensei.Dev.Shapes drawing – completely for free. The DrawGame method in Pandemonium is simply this (admittedly, it’s very much work in progress and there’s not much to draw yet, but you should get the idea of how little code there is to write per-game, or per-game-state when it’s a little more developed):

/// <summary>

/// This is called when the game should draw itself.

/// </summary>

/// <param name=”gameTime”>Provides a snapshot of timing values.</param>

protected override void DrawGame( GameTime gameTime )

{

    m_background.Draw( m_camPosition, ViewMatrix, ProjectionMatrix );

    m_angel.Draw( m_camPosition, ViewMatrix, ProjectionMatrix );

}

Update, Initialize and other methods are similarly simplified for the individual game, with as much complexity and common behaviour as is feasible moved into the engine.

Incidentally, when you have a base method that needs to do things before and/or after the derived method, I much prefer this pattern of having the base method (Draw here) as public, and have the base method call into protected virtual (or abstract) methods (DrawGame here). This is much superior than having a single protected function and relying on your more-derived class to remember to call the base version of the method. It’s too easy to forget, and too easy to get subtle bugs as a result! Of course, there is a cost. It may be, as I develop my games, that I discover I need to call some game-specific code after base.Draw (or base.Update, or what have you). That would become difficult or impossible in this pattern. If things turn out that way, I’ll have to change it. For now, I’m enjoying the simplicity of my game-specific methods. I can, quite literally, create a new XNA project, change the main class to inherit from Kensei.Game instead of Microsoft.Xna.Framework.Game, and I’ve got all the functionality of my Kensei engine instantly available. It’s very powerful.

(My original plan was going to be even more powerful; I’d create a simple project using Kensei.Game, and with all the necessary references to the Kensei\bin assemblies, and use that as the basis of a Visual Studio Project Template. Then, when creating a new project, I’d select “New… Kensei Game” instead of “New… Microsoft XNA Framework 3.0 Game”. It nearly worked! Everything was perfect, in fact, except that the Export Template wizard didn’t pick up the content project. That’s very unfortunate, and means I can’t use this trick as I’d wanted, but if anyone knows a way around it, please let me know.)

I think that’s enough for now. I hope what I’ve written makes sense, and gives you some ideas on how to structure your own engine and games, code and assets. I don’t claim for a second that this is the only way of doing it, and in fact if you’ve got some better ideas, I’d love to hear about them – leave a comment. This has been a fairly high-level view of the problem and my solution to it, and there are so many tradeoffs to be made at a lower level – something for a future article perhaps, though I’ve tried a number of different structures over the years, and have heard of still more without trying them out yet, and have yet to settle on a favourite. Something to experiment with, for sure. Anyway – let me know if this was useful to you.

October 18, 2008

There’s No “I” In “Team”

Filed under: Games Development,Personal — bittermanandy @ 12:57 am

I’m starting to get a little bit excited about “the new Xbox experience” and in particular (at last!) the live launch of the whole Community Games thing. It’s been a long time coming, and it still remains to be seen what solution XNA 3.0 will have for publishing games on Windows (which, in XNA 2.0, amounts to black magic and a reliance on extreme goodwill from your target audience); but I’m massively in favour of what Microsoft are trying to achieve here, and I still aim to get Pandemonium out there at some point.

There is one major issue that the system has that I really wish MS would do something to address. It’s a bit of a tricky one, to be sure, but the whole idea of making the 360 open to the hobbyist games development community hasn’t exactly been a walk in the park, so I’m sure they could do something if they tried.

The problem that Xbox 360 Community Games has is this: all games provide a free time-limited demo (so far so good) but all games must charge between 200 and 800 Microsoft Points for the full version. That is: you are not able to release your game for free.

Don’t get me wrong – money is a good thing! I don’t think many people will get rich from their Community Games, but there is definitely the potential for those people who put in a lot of effort to make a little bit of cash out of it. It’s actually quite nice to be allowed to charge the same kind of money as a full XBLA game, because some Community Games will be as good as the best XBLA games. (The worst XBLA games, unfortunately, are very poor).

However. I like at my own game: Pandemonium. There is nothing I would like more than to open up development of Pandemonium to other people. A few have even offered to help me out with various things, be it code (which I should be able to manage so long as I keep things simple, but more help would allow it to be a more complex game) or art (at which I am awful, and any help would be gratefully received, were it practical). If I were able to release Pandemonium for free, I would love to make it a team effort.

The problem is this. Pandemonium, when the time comes for it to be released on Xbox 360 Community Games, and like every other Community Game, will cost real money.

So… if I get the help of an artist, and Pandemonium sells a million copies and makes me rich (here’s hoping!), that artist would have every right to say: “hey. I helped you out there! Give me a share of the money.” To the best of my understanding, there is nothing in Xbox 360 Community Games to facilitate that. I could obviously “miss out the middle man” and transfer money into his bank account – but then, how much? The artist in question might say, “there’s two of us, so give me 50%” – but I might be of the opinion that I put in more time and effort and there wouldn’t even be a game without me, so only offer 20%. We would end up in dispute – and again, as far as I can tell Microsoft have washed their hands of the whole problem.

As the team grows larger, the problem grows worse. By the time you’ve got even five people contributing, you’re going to need to start writing legally binding contracts if you think your game will make any significant money. But then – I contract an artist to produce some character models and animations. Unfortunately, the results are awful and they don’t make it into the game. He did the work – he’ll want to get paid! But they didn’t make it into the game, so I’m unlikely to want to pay him.

It would also put obligations on me. The last few weeks, there have been (fun and exciting) things going on in my social life that have meant development on Pandemonium, and updates to this blog, have effectively frozen for a while. This is, after all, just a hobby project. If I’d contracted an artist to produce models, which he’d done – but then my distractions meant Pandemonium was delayed or unfinished, preventing him from getting any income – he might start getting pretty annoyed.

Real games teams have producers and management and business experts to handle all this kind of thing. (You see? I said “producers” without spitting. Aren’t you proud?) Hobbyist developers have nothing, and that’s fine when your games are free. You can make it clear from day one: “you want to contribute? That’s great! But this game is going to be free, so you won’t get any money, and neither will anyone else.” When you have to charge – there isn’t any choice in the matter, every game will be at least 200 Microsoft Points, of which up to 70% goes to the developer – it gets more complicated. Who gets the money? What share of it? What do they have to do to entitle them to that share? What happens if they don’t do it? Who do you complain to if you never get the payment that was agreed upon? How do you know the person making the payments is being honest – in fact, can you be sure you will ever get a payment at all?

In my opinion, if Microsoft are going to mandate that Community Games must be premium, they should also provide some kind of framework for answering these questions, and arbitrating on them. (The MS system need not be compulsory, but without it, where do you start?). I cannot, in all good conscience, accept offers of help on Pandemonium, because I cannot, with any level of honesty, promise to fulfil my side of the bargain (which would be much less of a problem with no money involved). Even if I did, and Pandemonium starting generating income, I would be deeply uncomfortable with attempting to control who gets a share of what – and unwilling to be blamed if someone felt they received an unfair share. I would love to make and distribute Pandemonium on 360 for free, but that’s simply not an option. So, it will remain a one-man effort – with all the implications that has – and that’s a real shame. Xbox 360 Community Games will, I predict, be a massive success; but part of a community involves working together, as well as sharing the fruits of your labour, and there are very real obstacles to that under the current system.

I’d love to be told I’ve overlooked something in the literature, but I fear I haven’t.

“An army cannot be commanded from within. A nation cannot be governed from without.” – Sun Tzu

September 2, 2008

Tools of the Trade – Part Five: Pot Pourri

Filed under: Games Development,Tools and Software Development,XNA — bittermanandy @ 11:02 pm

I think that FxCop, Reflector, CLRProfiler, and PIX – all of which I’ve previously discussed in some detail – are the most useful, bread-and-butter tools you’ll use in your XNA development. (In fact, all but perhaps PIX are useful regardless of whether you’re writing games or applications). There are of course many, many more tools, each with their uses, and I’d like to summarise some of them here. The sign of a good craftsman is using the right tool for the job, so I’d encourage you to explore all the different options available to you. Put bluntly, if you’re spending all your time performing repetitive tasks, or going through endless tweak-test-tweak-test cycles to try and hunt down problems in your code, you’re wasting your time. Your time may not be worth a lot to you, but mine is worth a lot to me, so I for one am always looking out for new tools and I think you should too.

Your primary development tool is Visual Studio itself (the Express version of which is available as a free download – possibly the most amazing free thing ever). I’m going to assume you already have it or you’d not be coding in XNA! However, I can guarantee that you are not using it to it’s full potential. I know I’m not. The reason I can make this guarantee is that the full potential of Visual Studio is huuuuuuuuuge. Almost every day, certainly every week, I discover new things it can do and think “that’s amazing!” Start by keeping up with the Visual Studio Tip of the Day, learn how to write macros, take some time to explore for yourself (especially consider keyboard shortcuts), and look out for plug-ins and extensions too. Project Line Counter is a personal favourite.

We’ve already looked at a couple of profiling tools but Perfmon (free with Windows) is the daddy of them all. As an example, hit Start then Run, and type “perfmon”. When the tool loads, select “Performance Monitor”, right-click on the counter list at the bottom and select “Add Counters…”. Select, say, the “.NET CLR Memory” category, then, for example, “% Time in GC”. Choose your game as the selected object and click “Add >>” then “OK”. Hey presto! A line displaying the exact processor cost you are paying for garbage collection will be added to the graph. There are hundreds of counters like this one, and much more that Perfmon can do.

I’m a bit loathe to mention this next one because, frankly, I hate it, but there are some bugs that can only be identified using WinDbg (or “windbag”, free with the Debugging Tools for Windows). Running out of memory and not sure why? Take a memory dump of your game, load sos.dll, call !DumpHeap -stat to see what’s live on the heap, call !DumpHeap -type <type> on the most memory-expensive type it lists to see all the items of that type, and call !GCRoot with the address of one of those objects to see exactly what is keeping it in memory and why. Sometimes there’s just no other way to work out what’s happening to your memory. WinDbg is an advanced tool and it’s an absolute swine to work with, but if the debugger in Visual Studio can’t solve your problem, WinDbg will.

I previously wrote about Reflector and described how it can reveal any assembly’s code to you. How does the code you write get translated from C# to the CLR and IL, and finally JIT-compiled into machine code? Well, I can’t help you with the JITter but IldAsm (free with Visual Studio) can provide a fascinating insight into the Intermediate Language stage of your code’s existence. Much in the same way that you don’t need to understand assembly language to write or use C++, but knowledge of assembly can help you fine-tune your C++ and fix the really tricky problems, knowledge of IL and an understanding of the translation process – while not essential – will make you a better C# programmer.

There’s a whole bunch of tools that are a bit more specialised or esoteric:

Perforce is absolutely the best choice for source control. I can’t live without Perforce now, it’s as though it has become a part of me. It’s free for up to two users, though very expensive for larger teams than that (absolutely worth it if you’re a professional company, perhaps less so if you’re a group of hobbyists, in which case try Subversion).

– If you’re a pro developer and aren’t using continuous integration, you face months of torment in an endless death-march of crunch at the end of the project. Do yourself a favour and use CruiseControl .NET (free).

– Continuous integration becomes even more useful when a build is run against a set of unit tests, and in fact they’re useful for finding mistakes early which is good for anyone, pro or hobbyist alike. I’ve heard good things about NUnit (free)… do as I say, not as I do, and use it… not doing unit testing is my worst programming habit that one day I will get out of. Don’t fall into that trap.

– Perfmon can tell you when you’re slow on the CPU and CLRProfiler can tell you if it’s garbage at fault, but if not and you want to know which specific functions are slow (and you very often do!) NProf is the tool for you, and it’s free.

– Finally, I’ve not used it yet but RPM (Remote Performance Monitor for Xbox, free with XNA) looks to be pretty damn useful for working out why you’re running fine on PC but slow on 360.

The best thing about all of these tools? Like XNA itself, they’re all free. That’s the kind of money I’m OK with spending! It means you have no excuse for not becoming familiar with them and, hopefully, rather than staying up bleary-eyed until 5am trying to find the bug in your code, you can fire up the appropriate tool, find and fix the bug and be home in time to see your family and get a good night’s sleep. Everyone’s a winner!

There’s only one major category of tool I’m missing, and that’s a decent bug database. I’ve tried Bugzilla and OnTime, and at work we have to use Sunrise, and I hate all of them as well as some others. By far the best defect tracking system I used was Product Studio, when I was at Microsoft, but despite being brilliant it is only available with the Team System version of Visual Studio which is very expensive. If anyone can recommend a good, usable, simple bug database that is not web-based and has a good UI, please let me know.

In fact, undoubtedly many of you out there will have your own favourite tools. Why not share the love, leave a comment and let me and everyone else know which tools make your life easier?

“If the foreman knows and deploys his men well the finished work will be good.” – Miyamato Musashi

September 1, 2008

Tools of the Trade – Part Four: PIX

Filed under: Games Development,Tools and Software Development,XNA — bittermanandy @ 9:44 pm

There is one more tool that I want to cover in a little bit more detail before presenting a round-up of the best of the rest (there really are so many good ones out there that this mini-series could last for months or years if I wrote a post for each one). The last article presented the CLRProfiler, a tool to help you manage your garbage and ensure it is being collected properly. Careless garbage collection is often the cause of poor performance on the CPU – but the CPU is only half the story, and to find out what’s causing poor performance on the GPU, you will need to use PIX (available free as part of the DirectX SDK).

Those of you who downloaded and used my Kensei Dev library might have noticed this comment in the Dev Shapes code:

// TODO I have noted some performance issues with this code when drawing very large

// numbers of shapes, but have not had time to profile it and fix it up yet, sorry!

Recently I had a bit of spare time so decided to go back and revisit this section. I set up a very simple test within Pandemonium, to draw lots and lots of spheres at random positions. I discovered that drawing 1000 spheres, or about 860,000 triangles (which doesn’t seem that many to me), caused the frame rate to plummet to only about 6Hz:

Lots of spheres!

Lots of spheres!

Using tricks that I’ve covered and linked to previously it didn’t take long to determine that the GPU was the bottleneck. (For example, returning early out of the game’s Update method, therefore dropping CPU usage as close to zero as possible, had zero effect on the frame rate). So my next port of call was PIX itself.

PIX (originally an acronym for Performance Investigator for Xbox) is an immensely powerful tool and we’re only going to scratch the surface of it here. At the most basic level, you can think of it as a recorder for absolutely everything that happens on the GPU. You can see exactly when every single function that used the GPU was called, and exactly how long it took. You can even rebuild a frame of your game method call by method call, seeing the results rendered step by step, instead of within a sixtieth of a second.

In this case, I want to see which functions are taking so long within a frame. I therefore chose to sample a single frame, as all frames are likely to be pretty much equal in this case. (If, for example, I was seeing a generally solid frame rate with occasional stutters, I’d have had to have chosen a different option).

PIX

PIX

After starting the experiment and getting to a point where the frame rate was low, I hit F12 to capture a frame (this can take a second or two). After I’d shut down my game, PIX generated a report:

A PIX report

A PIX report

There’s quite a lot going on in this image so let’s take a look at each section in turn.

The top window shows a graphical timeline. It’s not obvious from this picture, but you’ll see it very clearly when you run PIX for yourself, that the bars on the timeline indicate time when the GPU and CPU are busy doing things. As you click along the timeline, the arrows indicate where the GPU and CPU synchronise to the same call. With some classes of performance problem, you’ll see big gaps in one or other processor – these indicate whether you are CPU or GPU bound, for example, if you are GPU bound, you’ll see gaps in the timeline for the CPU where it was waiting for the GPU to catch up. The red circle in the top right of the picture shows the range of calls within our sampled frame (which occurred about 48 seconds in) – it looks mostly empty in the screenshot, but zooming reveals more details.

The middle window shows the DirectX resources in use (remember, XNA is just a layer on top of DirectX) including pixel and vertex shaders, vertex buffers, surfaces and such like. Not of much interest to us at this point.

In the bottom right I’ve selected the Render window. This shows us a preview of the frame as it was constructed. As you advance the cursor along the timeline, this preview is updated – initially getting cleared to Cornflower Blue, then having more and more things drawn onto it. This can be invaluable for detecting overdraw, and is really interesting in its own right. One of my favourite features is the ability to “Debug This Pixel”, which shows every call that affected the colour of any given pixel in the frame. This kind of thing is very useful when investigating transparencies, occluders, quadtrees etc.

Finally, in the bottom left is a list of GPU events, in sequence. Here you can see every call made to the GPU during the sample (note how they are all Direct3D calls, as mentioned above). Using the timeline view, I was able to visually identify which function call was the most expensive. Clicking on that call in the timeline synchronised it in the events window. I’ve circled the call in question. You can see from the StartTime of each event that the call to IDirect3DDevice9::DrawPrimitiveUP took 107349677 nanoseconds, or 107 milliseconds. When you consider that a whole frame normally completes in just 17 or 33 milliseconds, this one function call taking 107ms is a massive limiting factor on my frame rate.

Using a combination of intuition, logic, common sense, and the Render window (clicking on the call previous to DrawPrimitiveUP removed all the spheres from the preview, so it’s obvious what it was drawing!) I identified the corresponding code in my XNA program:

    device.DrawUserPrimitives<VertexPositionColor>(

        PrimitiveType.TriangleList, s_triangle3DVerticesArray,

        0, s_triangle3DVertices.Count / 3 );

You may not think this tells me very much. I already knew that the Kensei.Dev rendering code was slow, that’s why I fired up PIX in the first place! In fact, this is hugely valuable information. I know exactly which line of code is causing my GPU to run like a dog with no legs.

As this is a call to DrawUserPrimitives, it seems likely that the reason for this call being so slow lies in the User part of the method name. That is to say, the Kensei.Dev code builds up an array of vertices (s_triangle3DVerticesArray) each frame, and passes that into the function. This involves copying all those 860,000 triangles from main memory into the GPU memory, and is in contrast to using a vertex buffer, which lives on the GPU. If I can find a way to use native GPU resources and avoid the User methods, I may get a substantial speed boost; on the other hand, the User methods exist for the very usage scenario I’m using here, which is of vertices that can arbitrarily change position from frame to frame and which are controlled by the CPU.

Alternatively, it was suggested on the XNA Creators forums that I may be expecting the GPU to do too much in one go, and that splitting up the calls into smaller batches may improve performance. This is somewhat contrary to my understanding of modern GPUs, which, I was led to believe, vastly prefer to perform fewer operations on larger datasets than more operations on smaller datasets; nevertheless I am far from a GPU expert so will be taking that advice, and experimenting with splitting the vertex array/buffer into smaller pieces to see if this improves matters.

There are a few more possibilities as well. I’d like to say this story has a happy ending, but it doesn’t, at least not yet – I am hopeful for the future. I am still trying to solve this problem and find how to avoid this bottleneck. However, whenever investigating performance it is absolutely essential to base your observations and lines of inquiry on hard evidence. At the beginning of this article, I knew that “something in Kensei.Dev is slow”. PIX has since revealed that “DrawUserPrimitives is taking over 100ms to draw 860,000 triangles”. This will allow me to precisely focus my efforts, and hopefully find a correct, performant fix for the problem.

PIX has an awful lot more to offer than just single-frame samples and as your game nears completion you will probably find a lot of value in it. There are a lot of bugs that simply can’t be solved any other way, and if you are doing anything remotely clever with your graphics I strongly encourage you to learn about what PIX can do for you.

“My mistress’ eyes are nothing like the sun…” – William Shakespeare

August 13, 2008

Tools of the Trade – Part One: FxCop

Filed under: Games Development,Tools and Software Development — bittermanandy @ 9:04 pm

The established wisdom – and there’s undoubtedly a lot of truth in it – is that catching a bug late in the development cycle can cost as much as 1000 times as much to fix as the same bug would have cost, if you’d caught it earlier. Really bad bugs can even (depending on what you’re making) make you miss your Christmas launch date, fail to reach launch altogether, force a product recall after launch, or even open you up to legal action. Some bugs have cost their authors literally millions of pounds, and the hardware bug that causes the Xbox 360 “Red Ring of Death” cost Microsoft billions. Of course, “cost” could equally mean time instead of money – but in either case, I’d rather spend ten minutes fixing a bug just after I wrote it, than wait till just before releasing my game and realise I have to spend hours, days or weeks finding and fixing the same bug.

The first weapon in your armoury to find and fix bugs early is to turn the compiler warnings up to the most practical maximum, which in the case of Visual Studio means Warning Level 4, or /W4. (If you’re stuck using Visual C++ you might be surprised to learn that some amazingly useful, in fact, critical warnings are actually disabled by default at level 4). You should always ensure your code compiles without warnings at /W4. You may think some warnings are unnecessary; fix them anyway. It won’t hurt, and might even help without you realising.

Once you’ve got your warnings turned up and fixed, the next step is to use static analysis tools like FxCop. Static analysis tools find bugs in your code without you even needing to run it. In fact, the next version of FxCop isn’t even a separate tool, it’s a compiler option (/analyze). These tools parse your code (or in FxCop’s case, examine the MSIL assemblies) and compare what you’ve written against a set of rules that help to identify dangerous patterns in your code.

With FxCop installed, you simply need to open it up, start a new project, and point it at where to find the assemblies (.dll or .exe) for your code. It works equally well with either XNA game code or standard .NET non-game code. Hit “Analyze”, and a few seconds later it will come up with a list of problems that it has detected, along with an explanation about why they are problems and suggestions on how to fix them.

You will probably be shocked and surprised by how many problems it finds in your code. The good news is, it’s probably not as bad as it looks; the bad news is, that’s because FxCop is slightly on the noisy side, though you have complete custom control over which rules you enable (and you can even define your own). For example, FxCop regularly complains at me about the following:

IdentifiersShouldBeSpelledCorrectly: Correct the spelling of ‘Kensei’ in namespace name ‘Kensei’.

Well, first of all, Kensei is the correct spelling, it’s the codename of my engine. Secondly, I’m not completely sure that I care if the spelling is correct – nobody is going to play my game and think, “it’s a good game, but he misspelled one of his namespace names”. Thirdly, I’ve followed the instructions to create my own user dictionary for FxCop to add “Kensei” to it, and couldn’t get it to work; and I’m certainly not going to try and think up a whole new codename for my project just to keep FxCop quiet. So, I usually disable this rule, or at least exclude the specific occurrence of the warning.

There are some warnings that are a little bit trickier and need more thought. Like this one:

MarkAssembliesWithClsCompliant: Mark ‘Kensei.dll’ with CLSCompliant(true) because it exposes externally visible types.

Really…? ‘CLS compliant’ means, basically, that the assembly can be used by other languages in the Common Language Specification that aren’t C#, like Managed C++ or Visual Basic. I guess, on one level, that seems like a pretty noble thing to aim for, though I wouldn’t expect to ever use those other languages given that I love C# so much. But it’s possible I might make parts of my code available to other people, and they might want to use those other languages. So should I follow this advice or not?

In this case the answer comes when I do what it says to do. Marking the assembly as CLSCompliant results in a number of compiler warnings, because I’ve been using types that are not CLS compliant. That’s fair enough, except that these types include things like GameTime, which is a core XNA type. The XNA team chose not to make their assemblies CLS compliant; so there is absolutely no point in me trying to do so.

Anyway, by now you’re probably wondering why I’m talking about FxCop when so far I’ve just described some things it does less than amazingly well. As it happens, I think it’s a wonderful little tool, especially since it’s completely free. I run it on all my code – the Kensei engine, and my games, including Pandemonium – regularly; at minimum, after each “milestone” I’ve set myself. I’ll then fix the problems it highlights, either by changing the code as recommended or by marking a warning as Excluded, to say that the infraction was deliberate. So… why? Here’s why (a real-life example, though the names have been changed to protect the innocent):

    public class BaseClass

    {

        public BaseClass()

        {

            InitValues();

        }

 

        protected virtual void InitValues()

        {

            // …

        }

 

        // Rest of class implementation

    }

 

    public class DerivedClass : BaseClass

    {

        public DerivedClass()

        {

            // …

        }

 

        protected override void InitValues()

        {

            // …

            base.InitValues();

        }

 

        // Rest of class implementation

    }

Spotted the error yet? You probably should have done – I’ve certainly stripped it down far enough! When I wrote this, the BaseClass was in BaseClass.cs in a project in my Kensei solution, and the DerivedClass was in DerivedClass.cs in my Pandemonium solution, and both files were pushing 1000 lines of code. So the problem was a lot less obvious… but no less real for all that. FxCop spotted it straight away:

DoNotCallOverridableMethodsInConstructors: ‘BaseClass.BaseClass()’ contains a call chain that results in a call to a virtual method defined by the class. … Virtual methods defined on the class should not be called from constructors. If a derived class has overridden the method, the derived class version will be called (before the derived class constructor is called).

In other words, when I did something like this:

    DerivedClass derived = new DerivedClass();

… it would (conceptually; this isn’t completely accurate) first allocate memory on the heap, then call the BaseClass constructor, the BaseClass constructor would call the DerivedClass virtual InitValues method, which would call into the BaseClass InitValues method, and only then would it call the DerivedClass constructor before giving me back the reference to the object. That is to say – it would be calling a member function intended for a DerivedClass object, on an object that wasn’t a DerivedClass at all, only a BaseClass.

Most of you will be well aware that this is a Bad Thing. I certainly was already. Such behaviour is not polymorphism (a good and noble ideal), it’s just broken and wrong. It could rely on members being in a certain state that weren’t in that state yet. It could call out to other functions in other objects, and end up interacting with them despite being only partially constructed. It could, frankly, do just about anything, and almost none of the things it could do would be good. (For more on what is allowed in C#, see the C# Standard). However, despite the fact I’ve been programming for [mumblemumblemumble] years in total, and for six of those years I’ve been paid to do it, I still made this mistake. Well, I am only human after all – and we humans make mistakes.

It’s a mistake that FxCop spotted and I’ve since fixed it. It spotted it almost as soon as I’d written it, and it took five minutes to fix. Late in the dev cycle, I might only have spotted it after hours trying to work out why my DerivedClass objects were behaving strangely, and so much other code might have become dependant on that behaviour that it might have taken hours longer to fix. I could have lost days or weeks to one silly little bug – and believe me, I’ve seen exactly that happen before now.

There are many other genuinely code-breaking bugs that the compiler can’t spot but FxCop will pick up immediately. (Have you implemented the Dispose pattern correctly throughout your program? Are you really sure about that? How about private members and functions that are never used?) If you’re willing to spend money, there are other static analysers out there that check correctness and performance at an even lower level, therefore finding even more subtle (or critical!) bugs, and all without actually running a single cycle of your code. (Indeed, if you’re using C++ for some reason and not using Lint, BoundsChecker, PREFast or something similar, I bet real money your code is broken). But for C# and/or XNA, FxCop is free, easy to use, easy to customise, and if you’ve not used it yet I strongly recommend that you start right now.

“If debugging is the process of removing bugs, then programming must be the process of putting them in.”Edsger Dijkstra

August 10, 2008

Come Play With Me

Filed under: Games Development,Pandemonium,XNA — bittermanandy @ 4:28 pm

The first few articles on this blog have been written with the intent of sharing ideas, information and best practices with everyone else out there with an interest in developing games. It sounds like at least some of you are finding it useful, and I’ve been getting some great feedback, as well as ideas on how to make it even better.

I hope you will forgive me if I take a moment to be rather more selfish, and shamelessly publicise my in-development game, Pandemonium. That said, as well as showing off (the very early stages of) my game, this video also demonstrates several of the techniques I’ve talked about previously, most notably Kensei.Dev.Options and using PropertyGrids to rapidly tweak game variables.

I know, it’s not exactly full of eye candy! At this stage it doesn’t worry me. You can probably tell that Pandemonium is going to be a third-person platform game, very much in the vein of the classic Mario 64 or Banjo Kazooie games. The key to this genre of games (as with all games, really!) is the character control – if the player doesn’t enjoy moving their character around, they’ll never enjoy the rest of the game; and I’ve therefore decided to concentrate on honing the control first, before I start worrying about graphics, models, shaders and other such trivialities.

To this end, I’ve knocked together a small test level, which I’ve called the Playground, that contains a whole bunch of geometry for my avatar to run and jump around. I’ll use this level to refine how my character moves, and establish early on how far it can jump, how fast it can run, and other constraints that will make later level design much easier. Over time, as I add more features to the game, the Playground will get expanded; by the end of development, I’ll be able to load up the Playground and instantly test or demonstrate anything the player can do on any level of the game proper.

I mentioned SketchUp (the 3D design tool I used to create the Playground) before, and I used Bulent’s Screen Recorder to capture the video.

“I think I can make an entirely new game experience, and if I can’t do it, some other game designer will.” – Shigeru Miyamato

Next Page »

Blog at WordPress.com.