In part one of the Efficient Development mini-series, I talked about the importance of providing a simple set of boolean switches that can be set up and used with an absolute minimum of effort, to gain the absolute best possible use of your development time. I also showed how my Kensei.Dev library reduces the effort involved in setting such options up, to basically one line of code.
I mentioned in the closing comments of that article that Kensei.Dev.Options has some limitations. For a start, it only allows you to turn options on and off (or, set up a delegate that is called whenever the on/off state is changed). It’s not hard to imagine that you might encounter a situation where you need much more power and flexibility than that.
Let’s look at a slightly more concrete example. Let us suppose that we are getting into the closing stages of development on our game, and are starting to encounter frame rate issues. We’ve read through what Shawn Hargreaves has to say about profiling XNA games, and working on a combination of his advice and what we’ve already learned about Efficient Development, we’ve set up a couple of Kensei.Dev.Options we can use to help us determine whether we are CPU or GPU bound:
protected override void Update( GameTime gameTime )
if ( Kensei.Dev.Options.GetOption( “Profile.Sleep1msOnUpdate” ) )
// If enabling this option does NOT reduce frame rate,
// we must be GPU bound
System.Threading.Thread.Sleep( 1 );
if ( Kensei.Dev.Options.GetOption( “Profile.SkipUpdate” ) )
// If we are not GPU bound, if enabling this option improves frame rate,
// we must be CPU bound (else balanced).
base.Update( gameTime );
// … rest of Update method
After determining that we are GPU bound, we continue to read through Shawn’s brilliant performance articles and notice the following advice:
Try running your game in a tiny resolution, say 100×50. … If reducing the resolution speeds things up, you must be limited by one of the pixel processing stages.
Good tip. It’d be great if we could do this whenever we wanted instead of hard coding it, so obviously we need to add another Kensei.Dev.Option that will set the resolution to 100×50.
Wait right there! Doesn’t it strike you that 100×50 is a bit, well, fixed? Undoubtedly running in a very low resolution will be handy for profiling. Still – wouldn’t running in a very high resolution be handy for showing the game off to our friends? How about changing aspect ratios to check how our user interface behaves? In fact, shouldn’t we be able to run the game in absolutely any resolution we want?
This is clearly a situation where Kensei.Dev.Options is insufficient. Luckily, at this point Kensei.Dev.Command steps up to the mark.
The idea is a very simple one, and not new (though I think the way I’ve implemented it is pretty clever). It’s something you can and should add to any of your games, even if you choose not to use my implementation. Basically it involves adding support for a command line interface to the game – and making it trivially easy to add new commands, and for the player/developer to issue such commands. You’ve undoubtedly have seen this before – most likely in the Quake series and Half-Life 2, which ship with these command interfaces even in their distributable builds.
In Kensei.Dev.Command, registering a new command is very easy:
Kensei.Dev.Command.AddCommand( “SetResolution”, SetResolutionDelegate,
“Sets the display resolution.” );
This simply registers the command string with the delegate in a Dictionary. When the command is issued, the delegate is called with an array of strings representing the full command line. This is exactly analogous to the way command line arguments are passed to an executable, so you can use the same well-known techniques to parse these arguments. Providing the parameters in this way separates Kensei.Dev.Command completely from the way any particular command behaves.
private void SetResolutionDelegate( string parameters )
switch ( parameters.Length )
Kensei.Dev.Command.Print( “Sets display resolution.
Usage: SetResolution <width> <height>” );
int width = int.Parse( parameters );
int height = int.Parse( parameters );
m_graphics.PreferredBackBufferWidth = width;
m_graphics.PreferredBackBufferHeight = height;
catch ( System.Exception )
Kensei.Dev.Command.Print( “Invalid resolution.” );
That’s it – that really is all there is to it. Not very much code for a very useful, flexible and powerful feature. Not the way you’d want to present the choice of resolution to a player of the final version of your game, but it gives us the flexibility to change resolution at will completely arbitrarily. At runtime, we use a Windows Form (much like the one used by Kensei.Dev.Options) to allow the developer to enter their commands. The command line has full support for typical Doskey features (for example, using the up and down cursors to scroll through previously issued commands) and there are some common commands that every game is likely to need.
I think the separate form for input is the most elegant way of achieving this, but obviously that won’t work on Xbox 360, so I’ve also supported the more Quake-like technique of drawing the command line interface over the top of the game itself. You can plug any USB keyboard into your Xbox 360 (you can pick up a cheap one for maybe £5-£10), and instantly have access to the full range of dev commands, exactly the same as you have on Windows, shown here. (You can see listed the full range of commands currently available to my Modelviewer tool. Note in particular “setoption” and “getoption” – this is how it’s possible to use the Kensei.Dev.Options stuff on 360, where there are no Windows Forms).
I hope it’s obvious how useful Kensei.Dev.Command (or your own similar implementation, if you prefer) can be, and how little extra code it involves. I use it to take screenshots; to save, load, and change levels; and to interrogate the game database as to the current state of an object; among many other things. If your game uses a scripting language (and as we’re talking about Efficient Development, that is something I would strongly recommend for any complex game) it is trivial to use this command line interface to issue commands in that language, allowing you to make changes to the fundamental behaviour of your game on the fly, without recompiling, and dramatically speeding up your development iterations. You could even allow whole scripts to be created and run via the command line, removing the tedium of repeatedly entering the same commands.
So this was another straightforward tip but a very powerful and flexible one. Combined with the easily-switchable options discussed in the previous article, this will really help make your development sessions faster and more efficient. In the next part of this mini-series, we’ll look at some more techniques to help you do just that.
“Make everything as simple as possible; but no simpler.” – Albert Einstein