Pandemonium

July 30, 2008

Efficient Development – part four

Filed under: Games Development — bittermanandy @ 1:11 am

So the time has come, this is the moment you may have been waiting for… the Efficient Development mini-series is over and it’s time to release Kensei.Dev to the world! And talk about feeling the pressure – thanks mostly to a link from Shawn’s blog my hit count went through the roof today. I hope not to disappoint!

Before I provide the download link, there are some disclaimers…

  • You can do whatever you want with this code. Change it, modify it, improve it, fix it, redistribute it, use it, anything. Except, that is, try to blame me if it goes wrong / doesn’t work / formats your hard drive / steals your car. You use it at your own risk, but may use it for whatever purpose you deem appropriate. I’m probably supposed to provide some kind of license with this code, but we’re all adults here, right? Of course, if you do use this code, it’d be nice to get a mention in the credits when your game sells a trillion copies, but, y’know, I’m not going to hunt you down if my name isn’t there.
  • I don’t claim the code is necessarily perfect. There may be bugs. It might take you a few minutes to integrate it with your code. Most of it got written when I was still more of a C++ programmer than a C# programmer, so it may not be perfectly optimal in a managed environment. Well… it’s free! Go figure. The point is I’m confident it will save you time in the long run, and if you spot or fix any issues, please let me know.
  • Known issue: you’ll need to put the spritefont and shader files in the right folder in your Content project. There are better ways of doing this but I’ve not had time to set this code up to use them.
  • Known issue: I realised while editing for posting that I was using two functions from a book I’d bought. It’s straightforward stuff, but I don’t have the rights to publish that code, so I had to replace it with a home-rolled version. You may therefore notice some imperfect behaviour with keyboard input in Dev.Command. It shouldn’t be too hard to fix up yourself.
  • There are a number of TODOs in comments in the code. These represent features I’d like to do one day, but have decided that for now I’d rather get on with making actual games instead. You may wish to use those as starting points for your own improvements to it.

With that lot out of the way… here you go.

There’s still a couple more things I want to mention. The first of these is the next obvious addition to the library. Dev.Options does a great job of providing a simple and easy to use way to switch flags on and off. What if you want to edit a bunch of ints, floats, or enums? Sure, you could use a Dev.Command for each one, but it’s time consuming (not what we want!) and not very elegant. Well… why not put the values you want to edit into an object you then show in a Property Grid? As Scypior pointed out in the comments of Part One, you can even drop your GraphicsDevice into a property grid and the rest is done for you, which is pretty amazing stuff and reminds me why I love C# so much.

An alternative to a property grid – which would be a lot more work, but would produce more elegant results; probably not worth doing if you’re in a team of one, but if you want designers and artists to use your tools it would be well worth the effort – would be to use reflection to create customised Windows Forms controls. In a previous life, working with C++ for Xbox 360, our build tools would scan the code looking for structures containing lines like this:

    //! type=float control=slider min=0.0 max=360.0 default=45.0

    float angle;

When an object of a type containing that member was edited in the level editing tools, it would parse that comment and create a slider control with the specified ranges, attached to the variable. This system was used for an entire data-driven system. That’s how I know this idea is plausible – there’s games out there that were created using exactly these techniques! Now, as we all know, C# is better than smelly old C++ and could do this without needing a seperate tool to scan the code, and with greater type safety, by making use of reflection and custom attributes:

    [SliderControl( Min = 0.0f, Max = 360.0f )]

    float angle = 45.0f;

Your reflection code would simply check the attributes for each member of a type and create the corresponding controls in a Windows form. Just to be clear – there’s probably not much you can do with this that would be impossible using a property grid. But, property grids aren’t that pretty, and designers and artists (and end users!) prefer pretty things to ugly things so for some of you, it may be appropriate to go the extra mile. There’s probably a lot more that could be written about this, so I may come back to it one day.

The other tip I wanted to share is related to the nitty-gritty of debugging. It’s a fact of life that, as programmers, we probably spend more of our time debugging stuff than coding. So have you ever been frustrated while in the debugger to see something like this:

The debugger obviously knows quite a bit about the object, but isn’t telling us anything more than its type! Not until we expand the [+] symbol or open up a Watch window, anyway. Try using the DebuggerDisplayAttribute instead: 

    [DebuggerDisplay(“Name = {m_name}”)]

    public class CueInfo

    {

        string m_name;

        // … remainder of class implementation

Now you will find that the debugger will tell us something rather more useful while we’re debugging:

It’s a little thing, but I like it. If this kind of thing appeals to you too, you may also want to check out DebuggerHiddenAttribute, DebuggerBrowsableAttribute, and a whole bunch of others. I tend to add them to most of my types by default as it only takes a few seconds. There’s only one real drawback: for reasons best known to the Compact Framework devs, they’re not implemented on Xbox 360. That means you’ll either need to wrap #if !XBOX360 … #endif around every use of these attributes (ugly) or, just once, define dummy attributes like this:

#if XBOX360

namespace System.Diagnostics

{

    [AttributeUsage( System.AttributeTargets.Class | System.AttributeTargets.Struct

        | System.AttributeTargets.Delegate | System.AttributeTargets.Enum

        | System.AttributeTargets.Field | System.AttributeTargets.Interface

        | System.AttributeTargets.Property | System.AttributeTargets.Assembly,

        AllowMultiple = true)]

    public sealed class DebuggerDisplayAttribute : Attribute

    {

        public DebuggerDisplayAttribute( string value )

        {

            // Do nothing!

        }

 

        // NOTE the “official” implementation of DebuggerDisplayAttribute

        // has more in it than this, which you may need to add dummy code

        // for if you use any of it in Windows.

    }

}

#endif

And that about wraps it up. I hope you’ve got something out of this little mini-series, and thanks to all those of you who have left comments. Please do let me know how you get on if you decide to use this stuff, or if you have any questions or observations about it. I’ve not yet decided exactly what I’ll be writing about next, or when that is likely to be, but I’ll try to keep things interesting!

Advertisements

9 Comments »

  1. It’d be neat if you set this up in Google Code / Codeplex / Sourceforge so everyone could collaboratively improve the library. I know I’m looking forward to using it whenever I get around to starting an XNA project.

    Comment by Ben Hollis — July 30, 2008 @ 4:03 am | Reply

  2. The thought did cross my mind… unfortunately the experience I’ve had with such code stores before is that they’re clunky to set up, awkward and inconvenient to use and a pain to remain in sync with. So I decided a zip file would be the best way to make this available to everyone. Of course… as mentioned, you can do anything with this code, so if someone wants to take the time to set up such a store, feel free!

    Comment by bittermanandy — July 30, 2008 @ 8:12 am | Reply

  3. Hi, you don’t disappoint at all! I considered to post it before, but now you already mentioned it yourself: reflection is great for a debug console thing. I once made a debug console that accepted objects (e.g. an instance of RenderSystem), and through reflection the user could change attributes of it, from the console. Ofcourse it had extra bells & whistles like autocompletion with the tab key, etc. 🙂 Like: >rendersystem.renderwireframe=true;

    Comment by Roel — July 30, 2008 @ 9:17 am | Reply

  4. Cool tips, I didn’t know about DebuggerDisplay attribute. I was doing this by overloading ToString method 😉

    Comment by scypior — July 30, 2008 @ 1:54 pm | Reply

  5. Very good post.

    I had the same reasonment about properties and propertygrid last week, and i convinced my self to use a propertygrid (i’m developping a professional game editor). After some times with the simple PropertyGrid from MS, we made the turn to use the SmartPropertyGrid from visualhint. With a very tweaked user interface, it’s a perfect way to manipulate variables, even for the graphist team. And, at the end of the day, if well understood, Attributes are a very powerfull feature in C#.

    Comment by jbriguet — July 30, 2008 @ 6:18 pm | Reply

  6. Superb, great tips Andy. Simple additions that will help “loads” I’m all for that. I love the form of the mini-series it works well.

    Look forward to hearing more from you.

    Comment by Antony Kancidrowski — August 1, 2008 @ 5:04 pm | Reply

  7. Hi, great article again, and thanks very much for the code. I noticed that there was a section where you couldn’t post your own code (KeyToChar, specifically) because it was taken from another author. Good news! I went to the Wrox (book publisher) website and found the book, complete with a section for publicly-available downloads. Here’s the link if anyone is interested in it: http://www.wrox.com/WileyCDA/WroxTitle/productCd-0470261285,descCd-DOWNLOAD.html. If that doesn’t work, you can go to wrox.com and just search for “Professional XNA Game Programming.”

    Thanks again for the tips and code!

    Comment by Kolo Rahl — August 2, 2008 @ 10:54 pm | Reply

  8. Thanks a lot for the tips and the code. I was thinking about this improvements for my “work in progress” game but until now I was to lazy to code them. Now with a little tweaking they are already working! So this helped a lot. Thanks again.

    Comment by TheRoboz — August 10, 2008 @ 2:31 pm | Reply

  9. Thanks for the example code, im using it as a base for some devtools in my game engine. If anyone plans on using it, heres a quick fix for a small bug in the console code. As it stands, pressing shift to capitalize a letter will also add a space to the command line. left shift, right shift, well anything other than the defined special keys will get passed to KeyToChar and will return as ‘ ‘. Adding left and right shift to the IsSpecialKey method gets around this problem.

    Comment by Cubed2D — May 25, 2009 @ 7:55 pm | 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

Blog at WordPress.com.

%d bloggers like this: