Pandemonium

July 26, 2008

Efficient Development – part one

Filed under: Games Development — bittermanandy @ 11:13 pm

I thought I would begin the real meat-and-two-veg of this blog with a short series of (three or four) posts describing some of the most useful, bread-and-butter tools that any XNA game needs during development. In the last post of the series, I’ll make the code available for free, for you to use, improve, and generally do with as you will.

In fact: there is absolutely no reason that the ideas and techniques I’m about to demonstrate should be limited to XNA games alone. The code I’ve written could be used in a non-XNA C# game with almost no changes, and converted to any other language with just a little effort as well. XNA and C# can do these things particularly easily due to their access to the .NET framework, but several of these techniques were inspired by tools I’ve used on previous projects that didn’t use .NET and didn’t always run on Windows. As if that’s not enough, I’d go further – there’s no reason games projects should be the only ones to benefit from this stuff. Any non-trivial software development effort would be made easier using techniques and tools like these.

I’ve entitled this mini-series “Efficient Development” to give a flavour of what I’m trying to achieve with this; I’d have used “Agile Development” but that has a very specific, well-defined meaning (even if no-one seems to agree on what that meaning is). Nevertheless, this is all very much in the spirit of Agile Development in the abstract – ways to work on software with minimal time wasted in recompiling, restructuring, and generally wrestling with the code. Having used techniques very similar to some of these ideas before – and thought “wouldn’t it be great if” for others – I knew before I wrote a single line of XNA that getting this stuff together would be mega handy, because it would make my coding life easier and save me a bunch of headaches later. When you might only get ten hours a week (or fewer!) to work on your game, you want to spend as little of it as possible faffing around.

Below you can see a screenshot from a tool I’ve developed for viewing models, imaginatively called the Modelviewer. XNA supports a wide range of model formats and it’s easy enough to write converters for your own custom types. With the Modelviewer, I can download models from the internet, or build my own, and very easily examine them (either using the Modelviewer as a standalone tool or a mode in another game). As my code develops, I will add features to it such as animations, particles, sound editing etc.

The classic Stanford Bunny in my Modelviewer

The classic Stanford Bunny in my Modelviewer

It’s pretty handy to be able to check out models in this way. But that’s not the focus of this article (useful though it is). Instead – let’s imagine I’ve downloaded this model and I want to use it in my game. But, maybe, I want to get a better idea of exactly how many polygons are involved. (The XNA Model class can give me a number, but suppose I want to use my intuition). Or perhaps I can see a defect in the model and want to work out what’s going wrong. The obvious answer is to view the model as a wireframe.

Look at all those lovely polygons

Look at all those lovely polygons

XNA is pretty good at making it straightforward to do things like this. All you have to do is ask the Graphics Device to render in wireframe:

    GraphicsDevice.RenderState.FillMode = FillMode.WireFrame;

Easy! Except… I had to change code to do that, which meant I had to recompile. Suppose I’ve got a whole batch of models I want to view at once, and want to be able to switch between wireframe and normal rendering. Changing this code every time I want to do that is going to be laborious. I could comment it out, or wrap it in “#if false… #endif”, but that makes the code look ugly and is hard to maintain. If we look to the future, when I might want to do this at any arbitrary time while a game level is running to see what is being rendered on the other side of a wall, changing the code every time is clearly out of the question. I could assign a key shortcut to it – but I’ll soon run out of shortcuts, or forget them, and how would that work if I tried to run it on Xbox 360?

Clearly a better solution is needed.

Using Kensei.DevOptions to toggle features at runtime

Using Kensei.Dev.Options to toggle features at runtime

That better solution comes in the form of a set of toggleable options, which can be freely switched at runtime. The dialog box (a separate form, by the way, not a child – I’d usually keep it out of the way of the game window) that you can see in the screenshot shows how easy it is to change things on the fly. In this example, I’ve set the flag “Draw.Wireframe” to off, and replaced the previous black background with a more axiomatic “Draw.CornflowerBlue” option. It’s worth noting, by the way, that the dialog box is not the only way these options can be controlled (were you about to say, “well you can’t get Windows Forms on Xbox 360!”?) but I’ll talk more about that in a future post. The key thing is that the runtime behaviour of the game can be rapidly changed during development by means of a simple set of options – you’ll see just how simple in a moment.

Behind the scenes it’s all very straightforward. The static class Kensei.Dev.Options maintains a Dictionary of strings (the name of the option) and bools (the current state). It wraps this up behind a bunch of public functions that control and check the status of these options. That’s the core of this tip, really – a single centralised location where any arbitrary flag can be set to allow rapid changing of game state during development. It’s not intended for player-controlled options – but it will allow you to change things on the fly without recompiling your code.

The dialog box itself, by the way, is a standard .NET Windows Form, though I suppose if you’re not using C# you could use MFC if you’re still living in the Dark Ages. It adds all the Dev Options as checkboxes and maintains a live update of each option’s state with the game (so whether the option is changed in the dialog box, or in code, or by some other method, it will always remain in sync). You can see that the main form contains a tab control – there can be as many tabs as you like, with each containing as many checkboxes as you like. The form even automatically resizes itself as more options are added.

So what code is involved in this, you ask? Well, the whole Options.cs file is less than 500 lines in size, writing which was a one-off cost on my part that will save me (and you, if you decide to use it when I make it available for download) lots and lots of time in the future. The game simply needs to add one function call in its over-ridden Initialize() method (this Manager initialises all the stuff I’ll be talking about in this mini-series):

    Kensei.Dev.Manager.Initialise( Content, GraphicsDevice );

…and perhaps another to make the dialog box appear automatically at startup – or it can be summoned later (here I have limited it to Debug configurations):

#if DEBUG

    Kensei.Dev.Options.DoModelessDialog();

#endif

From this point on, it only takes a single line of code to add an option. Options default to off, but that can be controlled with an overloaded function call, or they can be added separately to explicitly state whether they should start on or off. You can even add a delegate that gets called when the option changes, which is useful in a number of scenarios. My wireframe option simply looks like this:

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

    {

        GraphicsDevice.RenderState.FillMode = FillMode.WireFrame;

    }

There are millions of things this can be useful for during development. Testing a difficult part of the game and need to get past it? Turn on Cheats.Invincible. Noticing your frame rate drop? Switch on Profile.ShowFPS and see how bad the damage is. Need to know what your bad guys are thinking to work out why they’re running away from the player instead of kicking his ass? AI.ShowInfluences should do the trick. Absolutely anything you can think of that you might need to change on the fly at runtime during development can be controlled using Dev Options, and it only takes one line of code to implement.

This kind of thing is what I mean by Efficient Development. It saves time, it saves effort, it keeps the code clean and maintainable. I hope you’ll have seen the benefits – firstly of having a centralised development option store, and secondly of making them easy to change via a standard Windows control. Of course you’ll already have noticed some limitations, too. It only controls booleans, for example, and from all you’ve seen so far it’s Windows only. In part two of this mini-series, I’ll show you another Kensei.Dev feature, that will go even further to making your development efficient and fast.

“Controlling complexity is the essence of computer programming.” – Brian Kernigan

PS. I can heartily recommend the Copy Source As Html add-in for Visual Studio, without which writing this blog would be much more painful.
PPS. Please, please do leave comments. Was this useful to you? Too long? Too short? Too obvious? Very clever? Questions, or suggestions?

About these ads

13 Comments »

  1. Nice post.

    I’m working on a similar system for in-game variables. This is for development, but could also be used for mods. I have a directory class and a variable class. The directory class has a list of subdirectories and a list of variables. Directories and variables can save themselves out to an XML node, to allow storage of game options in an XML settings file. When the code looks for these variables in the static database, it also supplies some default variable, and the variable is created if it’s not in the database already. The user can save the settings to and load the settings from some file of their choice. At runtime, the user can call up an in-game window (which is part of the UI system in the game’s framework), and modify the variables at will.

    Of course, one could always go the whole hog and implement a console maybe using some scripting language, and have the system variables implemented in that like in the Id engines etc.

    That copy source as HTML thing – awesome :D

    Comment by haowan — July 27, 2008 @ 10:52 am | Reply

  2. Great feedback, thanks.

    I like the idea of saving out to XML, I may have to add that; and it sounds like you’re supporting any arbitrary type too, not just flags – that’s something I have planned for future work (probably using a property grid, else attributes and reflection) but hadn’t got round to yet.

    As for the command console – way ahead of you, just wait for part two or three of this mini-series. :)

    Comment by bittermanandy — July 27, 2008 @ 6:39 pm | Reply

  3. In the beginning of developing my little project, i started to think about such tools. They are VERY useful, so it’s good you are mentioning it at the very beginning.

    I made mine using reflection – the window with properties, and even methods(parameterless) is created basing on any object you want. It isn’t as convenient as it should be, but it does not require any job to inspect new objects.
    I was even surprised that it gave me more power than I even wanted. Using it I can tweak parameters of GraphicsDevice too, so I can do such things like in your example(FillMode) without any line of code in renderer.

    Comment by scypior — July 29, 2008 @ 10:52 am | Reply

  4. In a previous comment I mentioned property grids and/or reflection, I’ve started playing around with both but not found anything I’m really happy with yet. (For the general case, anyway, for specific objects it’s straightforward enough). Sounds like you’ve got it working though which is awesome, and I like the idea of including methods on the control.

    I’d still probably never have thought of using it on the GraphicsDevice! That’s just brilliant!

    Comment by bittermanandy — July 29, 2008 @ 12:05 pm | Reply

  5. There is one more place I use reflection. For context menus. When I click on an object, it searches for:
    - bool properties
    - methods with particular attribute (in my case UIMethodAttribute)

    Then it creates pop up menu with the names of these properties and methods, and after clicking bool properties are negated, and methods are just executed.

    Comment by scypior — July 29, 2008 @ 2:55 pm | Reply

  6. [...] Efficient Development – part one Efficient Development – part two Efficient Development – part three Efficient Development – part four [...]

    Pingback by Deadrock » Efficient game development in C# — July 31, 2008 @ 4:49 pm | Reply

  7. One simple thing that I found useful trying to replicate some of this functioality was using enum’s rather than full-on reflection.

    You can easily add e.g. command boxes for each of the options within an enum (using Enum.GetNames()), and then you get the benefit of IntelliSense when filling out the Kensei.Dev.Options.GetOption( … ) parameter. Much easier than remembering exactly what text you’d used.

    Comment by Acemuzzyq — August 9, 2008 @ 7:21 pm | Reply

  8. True, the Intellisense would be a benefit. On the other hand, it means you need to declare the enum somewhere as well as using it – that’s twice as many lines of code. :-) A good idea that some people may prefer though.

    Comment by bittermanandy — August 9, 2008 @ 8:01 pm | Reply

  9. Well, only (at most) 50% more code – presumably you’d normally have to add it anyway! This way you can declare an Enum containing many (binary) descriptions and add them all with a single add call.

    But yes, not perfect as amongst other things you have lengthy Blah.Blah.MyEndum.ThingImInterestedIn.ToString() stuff being passed as parameters (though I think C# 3.0 might help with some of that junk).

    Good follow up posts by the way – we look forwad to seeing the game :)

    Comment by Acemuzzy — August 9, 2008 @ 8:49 pm | Reply

  10. Nice but how could you describe it as Agile if it doesn’t respect the YAGNI principle :)

    Comment by Ufinii — August 22, 2008 @ 1:58 pm | Reply

  11. Nice…
    But does these Method Call 60 times per second not cost many speed? I want my Game to run on old Computer, too!

    P.S. Sorry for my English, I´m from Germany…

    Comment by simsmaster — June 12, 2009 @ 1:59 pm | Reply

  12. Well, as this is all intended only for development – it shouldn’t matter (development can be done on a very fast system). At worst, in the final game, there’s a few “if’s” checking whether any of it is turned on – which has negligible cost.

    PS. Your English is rather better than my German! ;-)

    Comment by bittermanandy — June 12, 2009 @ 3:22 pm | Reply

  13. [...] are a couple of posts on the excellent Pandemonium game development blog (which sadly seems to have not been [...]

    Pingback by Tune Up Your PC » Post Topic » GenesisEngine: Using WPF in XNA and other non-WPF applications — April 4, 2010 @ 8:20 am | Reply


RSS feed for comments on this post. TrackBack URI

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

The Rubric Theme Blog at WordPress.com.

Follow

Get every new post delivered to your Inbox.

%d bloggers like this: