Archive for March, 2009

Changing constants at runtime

When it comes to game development, you end up changing constants a lot. Make an enemy hit harder, make a character move just a tiny bit faster, etc. They’re still constant as far as the player’s concerned, but the compiler will get a little annoyed if you try and change them without recompiling. While my compile times are still reasonable (only a few seconds), it takes a few moments to exit my game, edit some source files, and load it up again. Even after the game’s started up, I still need to load a saved game to get back to where I was. All said, a hassle if I’m looking to fine-tune things.

I spent some time today adjusting various physics parameters to compensate for the fact that I’m getting ready to drop in the actual sprites for my player characters. The actual sprites are much, much larger than the placeholders I’ve been using, so various parameters – run speed, jump velocity, etc – all needed adjustment. Tuning these by hand was a pain.

The solution is a simple one, but it requires a little magic: Replace game-related constants with something more malleable that can still be used like a constant.

The first step is to find all the constants I care about. Hopefully, they’re all marked const… so, they’ll look something like this:

        public const float StandingSearchDistance = 4.0f;

I change them to this:

        public static Constant<float> StandingSearchDistance = 4.0f;

Easy to do with a regular expression, or a simple search/replace. Once I’ve defined the Constant<T> class appropriately, everything compiles and runs just like it used to.

    public class Constant<T> {
        public readonly T DefaultValue;

        public Constant (T defaultValue) {
            DefaultValue = defaultValue;
        }

        public static implicit operator T (Constant<T> constant) {
            return constant.DefaultValue;
        }

        public static implicit operator Constant<T> (T constant) {
            return new Constant<T>(constant);
        }
    }

This class doesn’t do much yet, but it’s not a bad start! It meets our most pressing need: Keeping the code working correctly, and setting the foundation for us to do more interesting things.

So, the next step is to make the Constant type a little less constant. Let’s give it a way to take on a new value at runtime:

    public class Constant<T> where T : struct {
        public readonly T DefaultValue;
        private T? _CurrentValue;

        public Constant (T defaultValue) {
            DefaultValue = defaultValue;
            _CurrentValue = null;
        }

        public T Value {
            get {
                return _CurrentValue.GetValueOrDefault(DefaultValue);
            }
            set {
                _CurrentValue = value;
            }
        }

        public static implicit operator T (Constant<T> constant) {
            return constant.Value;
        }

        public static implicit operator Constant<T> (T constant) {
            return new Constant<T>(constant);
        }
    }

Not a difficult change, really, and we’ve already got something useful to play with! If we wanted to, we could rig some code up to let us change these constants already, and if the game code is structured right, it’ll work just fine. It’s done! Ship it!

Well, okay. There’s more work to do. Two major things missing:

  • There’s no easy way to get a list of constants to modify. Seems silly to leave that responsibility up to the game code, so let’s handle it in this bit of utility code instead.
  • We need a way to save out constants once they’re modified, so that the changes you’ve painstakingly tested don’t get lost.

The first one is easier, and happens to be a prerequisite for the second one. So let’s start there.

The solution to this is pretty easy, really: We can use reflection! We know that every constant is going to be in a static field, and it’s going to be an instance of a generic type: Constant<>. This lets us write a simple bit of reflection code to find all the constants defined in the current assembly:

    public static class ConstantManager {
        public static Dictionary<string, object> Constants = new Dictionary<string, object>();

        public static void Initialize () {
            var genericConstant = typeof(Constant<>);

            foreach (var type in Assembly.GetCallingAssembly().GetTypes()) {
                var typeName = type.Name;

                foreach (var field in type.GetFields(BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic)) {
                    var fieldName = field.Name;
                    var fieldType = field.FieldType;

                    if (!fieldType.IsGenericType || fieldType.GetGenericTypeDefinition() != genericConstant)
                        continue;

                    var constant = field.GetValue(null);
                    if (constant != null) {
                        var constantName = String.Format("{0}.{1}", typeName, fieldName);
                        Constants.Add(constantName, constant);
                    }
                }
            }
        }
    }

Well, okay. I might have been exaggerating a little – 20 lines isn’t ’simple’. But it’s not bad! There’s a few things going on in here: We scan over all the types in the assembly for static fields, check to see if they’re instances of Constant<>, and then pull them out, figure out their full name, and store them in a dictionary. Once we’ve done this, we now have a list of constants we can iterate over, so we can populate a UI to let the user fiddle with values.

So, as long as we call ConstantManager.Initialize at some point, the first problem is solved. Now for the second one!

As you may have noticed, we don’t actually have a clean way to interact with constants yet, because they don’t all share an underlying type – you can’t cast from object to Constant<> and fiddle with an untyped value, unfortunately. But the solution to this is simple – define an interface, and implement it:

    public interface IConstant {
        object Value { get; set; }
        object DefaultValue { get; }
        Type Type { get; }
        void Save ();
    }

Simple enough, right? Toss a little magic into the class to wire things up:

    public class Constant<T> : IConstant, where T : struct {
        ...

        object IConstant.DefaultValue {
            get {
                return this.DefaultValue;
            }
        }

        object IConstant.Value {
            get {
                return this.Value;
            }
            set {
                this.Value = (T)value;
            }
        }

        public Type Type {
            get {
                return typeof(T);
            }
        }

        ...

Now we can use this interface to interact with constants – get their current/default values, and change their values. Combine this with the names stored in the ConstantManager and we have everything we need to populate a UI. Coincidentally, this gets us closer to being able to save constants out at runtime, too!

We’ve got a way to get a list of all the constants at runtime, and now we’ve got a way to get their values. All we need is a way to save them out to disk. We could try something elaborate based on digging through our source code, or save constants out to XML or something silly like that. But instead, why not let the compiler help us out?

The compiler already knows where our constants live, and it so happens there’s a way for us to get that information – in debug mode: The StackFrame class. Every StackFrame comes with a file name, line number, and even a column number. As it happens, it’s possible for us to get a StackFrame for the static member that contains a Constant! All we need to do is walk a couple steps up the stack:

public class Constant<T> : INamedConstant where T : struct {
    ...
    public readonly string SourceFile;
    public readonly int SourceLine;

    public Constant (T defaultValue) {
        var sf = new StackFrame(2, true);
        SourceFile = sf.GetFileName();
        SourceLine = sf.GetFileLineNumber();
        ...

We pass 2 to the StackFrame constructor because: 0 is Constant’s constructor, 1 is Constant’s implicit conversion operator (invoked because we didn’t change our constants to use the constructor directly), and 2 is the static constructor for the type that holds the constants.

Now, one would assume that the line number we get would point to the start of the class, or out into the middle of nowhere. But it turns out that somebody on the compiler team was feeling generous, because we actually get the exact line and column where the constant was declared. Awesome!

Given the file name, line number, name of the constant, and value, we have everything we need to save a constant back out to disk – right into the source file it came from, so it’s ready to be compiled or checked into version control.

I’ll admit – mucking with text files is annoying. So here’s the cheap hack I wrote to get the job done:

        public void Save () {
            var lines = File.ReadAllLines(SourceFile);
            var line = lines[SourceLine - 1];
            var typeSuffix = "";

            if (Type == typeof(float))
                typeSuffix = "f";

            lines[SourceLine - 1] = Regex.Replace(
                line, @"=(\w*)([^;]*);",
                String.Format(@"= {0}{1};", Value, typeSuffix)
            );
            File.WriteAllLines(SourceFile, lines, Encoding.UTF8);
        }

You’ll notice I had to hack in a fix for floats – if you write them out raw without an ‘f’ on the end, the compiler will treat them as doubles, and yell at you. I’m willing to bet there’s a better way to solve this problem, but I don’t know what it is. :)

After this, the rest is pretty simple – pop a button into the UI where you show your constants, and in the click handler, walk over all the constants and save them. You probably want to only save constants that’ve been changed from their default value, and that’s easy since we store the default value separately from the current value.

Now that you know how it works, here’s what my take on it looks like. It’s pretty simple – I wrote a couple dozen lines of code to hook it up to a DataGrid and some extra code to highlight constants that’ve been changed from their default values.

Tags: , ,

Content and conferences

Been busy with GDC this week, since IMVU bought some passes for a few of us to share amongst ourselves so that we could see lectures and chat with people. Had some good times on tuesday and wednesday, seeing talks by people like Dave Hellman and Daniel James. Even had a beer courtesy of the kind folks at Flashbang! I tried using twitter to keep up with what was going on at the conference but quickly discovered that neither Wi-Fi or EDGE were useful – apparently the hundreds of iPhones at the conference have overloaded AT&T’s feeble cellular networks.

In the bits of spare time I still had available, I spent most of my energy working on building a prototype of the game’s first level, assembling the content I’ve gotten from my artist and making improvements to the editor as needed. I did some refactoring to my rendering code so that I could zoom the game’s camera in and out, which ends up being quite helpful when trying to assemble levels. I also had to make lots of minor tweaks to the algorithms for aligning and placing tiles, due to the odd sizes and shapes of some of the tiles I’m using.

Still a lot further to go, but my prototype level is starting to resemble what I want the final version to be, instead of just being a bunch of geometry.

One problem I still need to solve is that since some of my tiles share the same texture surface, the edges of adjacent tiles ‘bleed’ in sometimes if I draw them at fractional positions, based on the location of the camera. The solution to this will likely be a combination of premultiplied alpha and extracting individual tiles into their own textures. I haven’t decided whether I want to do this processing offline using the XNA content pipeline, or do it at runtime – I’ll probably end up doing the latter for now, though, since the content pipeline is ridiculously complicated.

I also ended up making a minor improvement to my tileset system, to make it easier to build good looking levels – previously, individual variations on a given tile – stone brick 1, stone brick 2, stone brick 3 – were listed individually in the tile selector, and I had to place them by hand. I decided to streamline things by grouping those variations together as one entry in the selector, and having the editor automatically randomize them when adding them to the level, so that things look more organic without me having to manually place the individual variations. This also helped cut down on the amount of noise in the tile selector, since it was getting difficult to scroll through the dozens of similar tiles.

Seeing all the pieces come together is making me get a little impatient about getting the actual character sprites into the game, especially since the early drafts look so good. Having tiny placeholder sprites next to huge tiles can get a little confusing at times.

Tags: , , ,

Valkyrie Profile: Covenant of the Plume (Nintendo DS)

This is a review-ish piece I recently wrote and posted on a forum. It’s not publication quality, but since I haven’t seen much discussion of this game anywhere, I figured I’d repost it here, with minor alterations. There’s no scoring or overall judgement on the game, but if you’re trying to decide whether you’re interested in the game, hopefully you’ll find it useful. I thoroughly enjoyed it and don’t regret spending $40, if that counts for anything. P.S. this review contains vulgarity, hide the children.

Covenant of the Plume is a very strange game. For the most part, the strange things are also good things, but it ultimately leaves you feeling unsure about what you’re playing and whether you like it or not.

At first, it seems like a typical strategy RPG. You’ve got the standard FFT-style isometric map and character sprites, with the rotating camera and per-character turns, characters each have their own attack and movement ranges, there’s terrain restrictions on movement, all that sort of stuff. Then they pile a bunch of weird stuff on top, and it’s hard to tell whether all of it works.

For example, like in a standard SRPG, if you run up to a guy, you can attack him. But it’s a little strange – it cuts away to a higher-res screen where you can see your characters fighting, instead of doing it on the main map. Then you move in another character to attack the same guy, and you realize that both of your characters are now on that cutaway screen, and they can both attack the foe at the same time.

You are now in the Valkyrie Profile battle system, not to be confused with the FFT battle system. The two are basically separate, with one exception. This is really, really bizarre. I don’t think I’ve seen something like it in a game before, which is all the more strange since it actually works pretty well.

Read the rest of this entry »

Tags: , ,

Two-character mechanics (#2) and tilesets

I spent most of my time this week working on editor improvements, and more two-character support. One of my first steps was to pull code out of the Player class into unique classes for each of the player characters. As a result, only one of the two characters can use a grappling hook, as intended. Next, I need to start building the other character’s special ability :)

The editor work mostly went into loading art assets and properly handling levels with missing assets, since i’ve been getting more tiles from my artist of varying sizes and shapes. I ended up building a simple XML-based file format for describing tilesets, based on my serialization framework, so that I can easily point the engine at multiple textures to pull tiles from.

It works pretty well, despite only being a couple hundred lines of code, and can easily be adapted to work with the XNA content pipeline, so it’s likely I’ll stick with it. I’m considering adapting the approach to also work for character sprites, since right now I have to manually tag sprite frames with specially-colored pixels in an image editor, which is extremely awkward and easy to get wrong. Here’s a snippet from one of my tilesets:

            <TileStrip key="7" typeId="1">
                <Id>prison_column_ornate_{index}</Id>
                <Filename>prison_columns.png</Filename>
                <TileSize width="32" height="208" />
                <Border left="0" top="0" right="384" bottom="0" />
            </TileStrip>
            <TileStrip key="8" typeId="1">
                <Id>prison_column_wood_{index}</Id>
                <Filename>prison_columns.png</Filename>
                <TileSize width="24" height="208" />
                <Border left="100" top="0" right="292" bottom="0" />
                <Margin left="0" top="0" right="8" bottom="0" />
            </TileStrip>

Simple enough syntax to be easy to write by hand in a text editor, but also not too difficult to load at runtime. I’m pretty happy with it.

One of the challenges in making use of the new art assets is getting all my tiles to line up properly. They have a large variety of sizes, so the algorithm I’m currently using to select tile positions isn’t a very good fit for my needs. Right now I’ve been having to make minor adjustments to my tile positions after I place them, but in the long run I’m going to want to come up with a tile placement technique that works well for tiles of all sizes.

Tags: , , ,

Two-character mechanics #1

Spent most of this week implementing the basic framework for having two player characters. A lot of code ended up needing changes since it had assumed the existence of a single player character – things like saved games, the grappling hook, etc. By far the hardest parts to get working properly were user input and collision detection.

Getting the inactive player character to properly handle input took some significant changes since I previously assumed that I could just poll the state of the joystick – now, a class called the PlayerManager sits between the two Player instances and objects like the joypad in order to make sure that only the active player receives input events. Collision detection also required some major changes in order to allow players to avoid colliding with each other without breaking any other behaviors that depended on collision detection, like gripping onto ledges or riding platforms.

Now that I have the basics working, I plan to start working on the initial implementation of the secondary character’s AI, so it can follow you around and traverse the environment by jumping and climbing up onto ledges. I still have yet to start working on the code for the secondary character’s abilities and attributes, so right now both characters are basically identical.

Tags: , , ,

Gruedorf mini-update #2

Another slow week. Most of my work went into moving to the new object model discussed previously – splitting bits of data and logic out into the Level and RuntimeLevel classes, fixing bugs as they cropped up, and so on. One thing I had to do in order for that to work that I hadn’t anticipated was change my object model so that every object in a given level had a unique name. Previously names were optional, but in the new object model it didn’t really make sense for objects to not have a name, or share the same name. After resolving that, some other issues cropped up – for example, bounding boxes weren’t updating correctly for some moving objects like doors and moving platforms, which meant that in some cases an entity could slip through an obstruction.

Once the issues resulting from the switch were resolved, I started making some improvements to my moving platform code so it was easier to put to work. The first problem was that the use of cubic interpolation caused platforms to move at an inconsistent speed – slowing down as they approached waypoints on their path, and accelerating as they grew more distant. I spent a little time experimenting with various approaches to solving this, and ended up settling with a simple hack, where I do a binary search of the curve to find the next point along the curve that is a given distance away from the current one. While not mathematically pure, it was easy to build and solves the problem, and after implementing it I was surprised by how much better the motion of the platforms looked as a result of them moving consistently.

After this I spent some time improving the editor’s support for dealing with objects that move, making it possible to see a simple visualization of their path so you can get an idea of possible collisions and where it’s going to move.

Tags: , , ,

luminance is Digg proof thanks to caching by WP Super Cache