Posts Tagged platformer

Level Up 2009

I’ve been spending the past few days down in Austin, TX at the Austin Game Developers Conference, and having a pretty good time. For anyone who’s ever been on the fence about going to GDC (either in San Francisco, or in Austin) I wholeheartedly recommend going if you can find a way – it’s a bit expensive, but an amazing experience.

On a related note, I can now announce that Inferus was selected as a winner of Intel’s Level Up 2009 game competition. I’m quite pleased with how it turned out and very grateful to Intel for running the contest. You can check out the list of winners here – there are some pretty interesting games!

Tags: , , , , ,

Bits and pieces week

Did work on various bits and pieces of the game this week. A rough overview:

  • Added the first piece of level geometry that deals damage on contact (spikes)
  • Overhauled my ComputeStandingY algorithm so that it takes an order of magnitude less time to run
  • Implemented a new animation for surface mantling that includes camera control
  • Moved jumping, ledge clinging and mantling from using tasks to using a combination of animation triggers and simple state machine logic

So, I guess I’ll give each bullet point a little detail.


Adding spikes was fairly straightforward. The largest challenges were getting the collision detection and rendering to work correctly. All the geometry I’ve added to levels before now has simple collision detection, in that the geometry remains relatively static and obstructs the player’s movement. Spikes, however, needed to allow the player to move through them but still detect collisions so that they could deal damage. Getting this to work meant some changes to my collision detection code, in order to correctly handle cases where a piece of geometry had no collision, and also meant that I had to add support for changing a piece of geometry’s collision on the fly – that way I could leave the spike with no collision by default, but assign it collision temporarily during each update so that I can perform a collision check to find the entities it’s touching.

            _CollisionList = _DrawList;
            this.FindObstructions(this.InflictDamage);
            _CollisionList = Game.NullCollisionList;

Rendering the spikes was a bit of a challenge as well – since they’re arbitrarily sized and can point in different directions, I had to do some work to figure out how to take an arbitrary texture and use SpriteBatch to align it with the spike’s geometry. After a lot of iteration, I ended up with something that properly scales, rotates, and aligns the sprite so that it lines up with the geometry – determining the proper inputs to a SpriteBatch.Draw call can be challenging when you’re rotating, scaling and translating all in one go, so it involved a lot of trial and error.


Some investigation of issues I was running into with standing on surfaces revealed that my current approach was getting too complicated and fragile – previously, I was scanning over all the objects under the player, and then choosing arbitrary points along their surface (left edge, middle, and right edge) and casting rays downward at those points to attempt to determine where the player should stand on the surface. This ended up not working well for complex surfaces, like the uneven edges of the stone outcroppings created by the stone potion, and being unnecessarily expensive for simple surfaces like flat rectangles (which really only need a single ray cast). Furthermore, it had a negative performance impact, since I was issuing hundreds of ray cast calls per frame in situations where I might have gotten away with only a dozen.

The solution to this ended up being simple: Where previously, I’d issue ComputeStandingY calls on each object that the player could be standing on, multiple times to cast individual rays, now I would issue a single call for each object, telling it the location of the player’s left and right edges. This way each object could have its own implementation for handling uneven surfaces – simple rectangles could just return the Y coordinate of their top edge, while complex geometry could sweep over its vertices and do the necessary math to compute the Y coordinate. In some cases, the new handlers got a bit complicated, but in most cases, they weren’t actually any harder to write than the old ones – a pleasant surprise. For example, the handler for pressure plates required a complete rewrite, since a pressure plate is represented by a rectangle (in the middle) with two triangles on the corners to give it a smooth slope:

        public override float? ComputeStandingY (float x1, float x2, float y) {
            var p = _CollisionList[0];
            if ((x2 >= p[1].X) && (x1 <= p[2].X))
                return Anchor.Y;
            else if (x2 < p[2].X)
                return RuntimeTriangle.ComputeStandingY(p[0], p[1], x1, x2, y);
            else
                return RuntimeTriangle.ComputeStandingY(p[2], p[3], x1, x2, y);
        }

While other handlers, like Triangle, required only minor changes to account for the addition of a second X coordinate:

        public static float ComputeStandingY (Vector2 slopeBegin, Vector2 slopeEnd, float x1, float x2, float y) {
            var minX = slopeBegin.X;
            var maxX = slopeEnd.X;

            if (x2 < minX)
                return slopeBegin.Y;
            else if (x1 > maxX)
                return slopeEnd.Y;

            var startY = slopeBegin.Y;
            var endY = slopeEnd.Y;
            var dX = maxX - minX;
            var dY = endY - startY;

            float x = (dY > 0) ? x1 : x2;

            var d = (x - minX) / dX;

            var result = startY + (dY * MathHelper.Clamp(d, 0.0f, 1.0f));

            return result;
        }

The end result is that ComputeStandingY went from around #10 on profiler results to well below #50 (always good to maintain a stable framerate), and a number of minor surface standing oddities went away. Future work involving complex surfaces should be much easier, as well, which will be important for some of the game content I have planned.


Earlier this week I got the art for one of the player characters’ surface mantling animations, so I decided to get it into the game. Doing this required throwing out most of the existing code for surface mantling, since I had previously animated it by actually moving the player character progressively from his old location to the new one. The new animation is simpler, in that the player switches instantly from the old location to the new one, but poses some interesting challenges: I have to realign the player such that his animation looks like it’s moving from his old location to the new one, without the jarring realignment of the camera that would normally accompany an instant relocation like that.

The end result looks pretty good. The basic approach looks like this:

        protected void BeginMantle (ICollidable mantleTarget, Vector2 targetPosition) {
            Jumping = false;
            JumpApex = false;
            LedgeClinging = false;
            Mantling = true;
            LockInput = true;

            var anim = PlayAnimation("Mantle");
            _MantleTarget = mantleTarget;
            _MantleStartPosition = Position;

            _LockCamera.Position = Position;
            _LockCamera.Weight = 1.0f;
            Game.CameraStack.Add(_LockCamera);

            Velocity = Vector2.Zero;
            Position = mantleTarget.Anchor + targetPosition;

            var rideable = mantleTarget as IRideable;
            if ((rideable != null) && (!_Riding.ContainsKey(rideable)))
                BeginRiding(rideable);
        }

        protected void EndMantle () {
            Mantling = false;
            LockInput = false;
            if (StandingOn != null)
                _RidingPosition = Position - StandingOn.Anchor;

            Game.CameraStack.Remove(_LockCamera);
            Game.CameraStack.Add(new LookAtCameraController(
                _MantleStartPosition, 0.0f, 0.0f, MantleCameraPanDuration
            ));
        }

A few things are going on here: When the player begins mantling onto a surface, I set some state flags in order to keep things sane, for example disabling the input, so that you can’t move left/right or jump while mantling is in progress. After that, I start the mantle animation and initialize some fields so that the player’s code can keep track of the surface it’s mantling onto and what the source and target positions are, for animation purposes. Next, I lock the camera on the player’s original position, so that it won’t move suddenly when I relocate the player to the new location. Finally, I move the player to his new position, reset his velocity, and if the surface being mantled onto is rideable, I set him as riding it.

The rest of the work mostly happens automatically: I tag the animation frames with markers so that the game knows what his origin is and where the top of his head is, so that his bounding box changes automatically along with the animation, and he appears to be climbing up onto the surface. When the animation finishes, it triggers a handler (EndMantle) to do the rest of the work – Cleaning up the state, and triggering a short camera pan from the old location to the new location so everything looks smooth. One final touch is that I play the ‘crouch to stand’ animation immediately after completing a mantle, so that the player appears to quickly stand back up after climbing onto a surface.

In practice, this solution actually looks smoother and more realistic than the old one, despite the fact that the animation is simpler and the collision detection approach is simpler.


And finally, this brings me to the task changes. As you might have noticed, previously I used tasks to structure ‘long-lived’ pieces of player state, like mantling onto a surface or gripping onto a ledge. This was convenient since tasks could easily take parameters and have local variables that would last for their entire duration, allowing me to track things like the source and destination positions for a mantle without needing to define fields for them. It also simplified the state machines necessary for handling player input and motion, since states like ‘is the player mantling’ could be represented entirely by the task responsible for them, and all the logic for updating during that task could be handled by the task itself, once per frame. Tasks also gave me an easy way to ensure that code ran at the beginning and end of a given animation, via the use of IDisposable, without having to manually track state and call Begin/End functions. Put together, all this was a huge timesaver initially, before the addition of my animation system and the simplification of my collision detection code – early prototypes contained some utterly terrifying state machines before I simplified things by switching to tasks.

The time had finally come to stop using tasks for this, though. The new animation system gave me a way to easily attach logic to onscreen animation, by responding to markers/triggers and to the beginning and end of an animation, and the conditional branching support in the animation format meant that the majority of my animation logic no longer needed to live in the code at all, alleviating most of the issues with huge state machines that I had before. So in the process of rigging up the new mantle animation, I converted jumping, mantling, and ledge clinging so that they used simple state machines and animations instead of tasks.

For the most part, the process was straightforward – I added boolean fields to track the player’s state where I previously used a task (so the player now has LedgeClinging and Mantling flags that he didn’t before), and created private fields for things that were previously stored in task locals (like the surface being mantled onto). Logic that needs to happen at the beginning or end now has its own handler (like the BeginMantle and EndMantle functions shown above), and in the event that I need to run some logic every frame during an animation, I write a simple function for it and insert it into the appropriate part of the state machine. Some of the code for handling player input is starting to get rather complicated, with chains of 5-6 if () else if () else if () else if () conditions, but it’s at least remaining relatively small and encapsulated.

        protected bool BeginLedgeCling (out ICollidable clingTarget) {
            if (!CanLedgeCling(out clingTarget)) {
                LedgeClinging = false;
                return false;
            }

            Velocity = Vector2.Zero;
            LedgeClinging = true;
            _ClingDirection = GetInputDirection();
            if (clingTarget != null)
                _ClingPosition = Position - clingTarget.Anchor;
            if (_ClingTarget is IRideable)
                BeginRiding(_ClingTarget as IRideable);

            return true;
        }

        protected void UpdateLedgeCling () {
            if (_ClingTarget == null)
                return;

            var delta = (_ClingTarget.Anchor + _ClingPosition) - Position;
            ApplyMotion(delta);
            AutoUpdateBounds();
        }

        protected void EndLedgeCling () {
            LedgeClinging = false;
            if (_ClingTarget is IRideable)
                StopRiding(_ClingTarget as IRideable);
            _ClingDirection = 0;
            _ClingTarget = null;
        }

During the process of moving things around, I actually found a few bugs in my implementation of ledge clinging, which made this refactoring quite worthwhile. Previously, I’d been depending on some bugs in my code in order to make the player remain stationary while clinging to a ledge, when I could have easily accomplished this with a single-line change in the right spot. I also discovered that rebounding off of a wall was actually intermittently broken before because the ledge clinging code had the ability to interfere by causing the player to begin clinging onto the ledge during the middle of a rebound. The new state machine approach made it much easier to address this problem by adding some appropriate checks, so that the player can’t even attempt to grip onto a ledge if he’s moving away from it.

All in all, a productive week!

Tags: , , , ,

Animation markers and triggers

One of the first things I did this week was implement support for scripted animation markers. Markers let me attach names to various parts of a sprite so that I can use them in animation and collision detection – for example, lining up a weapon with a character’s hand, or doing hit detection against a character’s hand instead of his entire hitbox.

Once I had some simple markers for the player’s feet added to his animation script, to test them out more thoroughly, I implemented support for attaching simple script triggers to a combination of a marker and a given animation frame, like this:

    <SpriteMarker typeId="2">
        <Name>Left Foot</Name>
        <Groups>
            ...
            <Group name="run">
                <Frames>
                    <Frame anchor="tl" x="80"  y="170" index="0" />
                    <Frame anchor="tl" x="61"  y="169" index="1" />
                    ...
                    <Frame anchor="tl" x="132" y="143" index="6" />
                    <Frame anchor="tl" x="99"  y="173" index="7" trigger="Footstep" />
                </Frames>
            </Group>
        </Groups>
    </SpriteMarker>

Using the combination of markers and triggers, I was able to write a simple bit of C# to go with the animation script and spawn small puffs of smoke every time the player’s feet land on the ground during his run animation:

    public void Footstep (string foot) {
        if (Jumping && !JumpLanded)
            return;

        var pos = ResolveMarker(foot);
        if (!pos.HasValue)
            return;
        Game.SpawnSmokePuff(Position + pos.Value - GetDrawOrigin(Animator.Frame), 10, 0.5f);
    }

The real motivation behind the marker system, however, was syncing animations with the game world – I wanted the player’s grappling hook to extend from his hand, have his melee attacks actually sync up with his animation frames, and have his collision detection change realistically while crouched.

Essentially, where before I used hard-coded coordinates and percentages, now I ‘resolve’ one of the player’s named markers. Resolving a marker either returns coordinates (relative to the top left of the frame) or null, which allows me to determine whether a given frame has a particular marker attached to it. Once I have coordinates for a marker, I compute the player’s origin (used for positioning his animation frames) and use that to compute the on-screen or in-world coordinates for the marker, based on the frame-relative coordinate I already have. Given that, I can sync up things like a grappling hook or a potion with the player’s hand:

    public Vector2 GrappleFrom {
        get {
            var handPos = ResolveMarker("Right Hand");
            return Position + handPos.GetValueOrDefault(
                new Vector2(0, Obstruction.Y * -0.5f)
            ) - GetDrawOrigin(Animator.Frame);
        }
    }

After using this technique to make the player’s bounding box change while crouching, I realized that by uncrouching, the player could become stuck in a ceiling. The solution to this ended up being a bit of a hack – before increasing the size of the player’s bounding box, do a quick collision check to see if the player’s current bounding box is able to move upward by that same amount. If the check fails, I now know exactly how far the player’s current bounding box would have been able to move, and I can constrain the growth of the bounding box to avoid making the player become stuck.

Once the player is out of a tight space, I can grow the bounding box to its full height, restoring sanity. It’s not perfect (and looks kind of stupid since it allows the player’s head to stick through ceilings), but it was relatively simple to implement. I suspect I’ll end up with a different solution in the final game – perhaps forcing the player to stay crouched if he can’t stand up in his current position.

During the process of rigging up the player’s animations, I spent a lot of time fine-tuning things and working out issues. To make things move quicker, I ended up adding a couple new features to my engine:

First, I added support for reloading sprites and tiles at runtime. My existing game code already was designed in such a way that this wasn’t too difficult, but I still had to do some work in order to get the rest of the way. One of the biggest changes was that I had to change entities to store a sprite’s Name instead of storing the sprite itself, so that I could replace a given sprite instance at runtime after reloading it from disk. As a result, where before I had:

    this.Sprite.Animations["Walk"].Run(this.SpriteContext);

Now, I have something like this:

    Game.Sprites[this.SpriteName].Animations["Walk"].Run(this.SpriteContext);

A bit more verbose, but easy to abstract out using properties and helper methods – such that actual game code can just use convenience methods, like so:

    this.PlayAnimation("Walk");

And everything happens behind the scenes.

The other change I made was to overhaul my rendering model in order to make it easier to add debugging overlays, user interface graphics, and special effects without having to change the Game’s Draw function. First, I changed the signature of most of my objects’ Draw methods, such that they now take an extra parameter:

    public override void Draw (DrawFlags flags) {

Then, the game code can pass a combination of flags to an object to specify which types of rendering to perform:

    if (ShowHUD) {
        var flags = DrawFlags.HUD | (GlobalDrawFlags & DrawFlags.DebugHUD);
        RenderGeometry(flags);
        RenderEntities(flags);
    }

As a result, I have the ability to easily toggle off sections of an individual object’s painting code, without having to directly hook the logic into the Game object itself. This also nicely simplifies a lot of the code in my editor, since I can now do editor-related painting (like drawing bounding boxes, selection highlights, etc) in the Draw method of the object in question, instead of having to add a special function to the editor that draws those things manually, or having to add an ‘EditorDraw’ method to the objects (like I had before in a few cases, unfortunately).

With the addition of a couple extension methods to simplify things, it wasn’t too hard to wire things up inside my game objects. For example, this is what SpriteEntity.Draw looks like:

    public override void Draw (DrawFlags flags) {
        ...
        var drawPos = GetDrawPosition();
        var origin = GetDrawOrigin(Animator.Frame);

        if (flags.Check(DrawFlags.Entities))
            Draw(drawPos, origin, Scale, Color);

        if (flags.Check(DrawFlags.DebugEntities)) {
            Game.SetupRenderState(true);
            Game.DrawBox(this.Bounds, Color.White);
            Game.CleanupRenderState();
        }

It simply checks for each of the draw flags it knows how to handle, and processes them accordingly, in a given order. This gives me the ability to do multiple draw passes at once, or do them individually if I want finer-grained control over draw order. A good example of this is the HUD pass – I want HUD elements to cover all the objects in the game world, so I draw them in a separate pass. But debugging overlays like entities’ bounding boxes don’t need to cover everything, so I draw them in the same pass as the entities themselves.

For the curious, the extension methods I ended up writing look like this:

    public static bool Check (this DrawFlags drawFlags, DrawFlags flag) {
        return (drawFlags & flag) == flag;
    }

    public static DrawFlags Toggle (this DrawFlags drawFlags, DrawFlags flag) {
        return ((drawFlags ^ DrawFlags.All) & flag) | (drawFlags & (flag ^ DrawFlags.All));
    }

They’re fairly simple, but having them tremendously simplifies the process of working with the DrawFlags enumeration. This is one thing that I wish C# had built-in support for, but it’s at least fairly easy to add with extension methods. Unfortunately, generic types and enums don’t get along, otherwise you could have generic forms of these functions instead of having to write them for each Flags enumeration in your game.

Tags: , , , , , , ,

Scripted animations and saved games

I spent some time this week building a new animation system to replace my old hard-coded player animations. Right now the player doesn’t look any different, but the new system is set up such that I can drop the animation frames my artist is working on directly into my Content folder and see them in action with minor XML changes, instead of having to adjust large parts of the Player class.

One of the main goals I had for the Player class was to separate the presentation-related aspects of the animations (number of frames, size, etc) from the logic-related ones. Previously, both were handled in the same C# function – to handle punching, I had an Animation_Punch function in the Player class that looked something like this:

        protected Anim Animation_Punch () {
            _AttackShape = new DrawablePolygon(
                new Vector2[4]
            );

            using (Finally.Do(() => { ActiveAttack = Attack.None; _AttackShape = null; }))
            using (var a = Animation_OneShot(AnimId_Punch, 40 * Time.MillisecondInTicks))
            while (a.MoveNext() && (ActiveAttack == Attack.Punch)) {
                float x = ObstructionWidth / 2.0f * Facing;
                float y = -ObstructionHeight + ArmTop;
                float w = ((Sprite[Animator.Group][Animator.Frame].Width * ScaleFactor) - ObstructionWidth) / 2.0f * Facing;
                float h = ArmHeight;

                _AttackShape.SetVertex(0, new Vector2(x, y));
                _AttackShape.SetVertex(1, new Vector2(x + w, y));
                _AttackShape.SetVertex(2, new Vector2(x + w, y + h));
                _AttackShape.SetVertex(3, new Vector2(x, y + h));

                yield return a.Current;
            }

            yield return new SetAnimation {
                Animation = (Jumping && !JumpLanded) ? Animation_Jump_Fall() : Animation_Stand()
            };
        }

As you can see, the presentation - Animation_OneShot(AnimId_Punch, 40 * Time.MillisecondInTicks) – and logic are mixed directly together. Also, it has hard-coded coordinates and sizes in it, in order to keep the collision detection in sync with the animation. My goal is to eliminate both such that the Animation_Punch function becomes pure logic and all of the presentation-related data lives in the animation file. The use of an animation file also eliminates annoyances like hard-coded animation IDs, replacing them with filenames.

The equivalent in the new animation file looks like this:

            <SpriteAnimation typeId="1">
                <Name>Punch</Name>
                <Group name="punch" />
                <Frames delay="40" />
                <NativeWrapper name="Animation_Punch" />
            </SpriteAnimation>

As you can see, it expresses the same information, though in some cases it is able to omit things that had to be explicit before. The Animation_Punch function still exists, but has a more clearly defined purpose:

        protected Anim Animation_Punch (Anim inner) {
            using (Finally.Do(() => { ActiveAttack = Attack.None; _AttackShape = null; }))
            using (inner) {
                ActiveAttack = Attack.Punch;
                _AttackShape = new DrawablePolygon(
                    new Vector2[4]
                );

                while (inner.MoveNext()) {
                    var group = (SpriteGroup)Animator.Group;
                    var frame = group[Animator.Frame];
                    float x = ObstructionWidth / 2.0f * Facing;
                    float y = -ObstructionHeight + ArmTop;
                    float w = ((frame.Width * ScaleFactor) - ObstructionWidth) / 2.0f * Facing;
                    float h = ArmHeight;

                    _AttackShape.SetVertex(0, new Vector2(x, y));
                    _AttackShape.SetVertex(1, new Vector2(x + w, y));
                    _AttackShape.SetVertex(2, new Vector2(x + w, y + h));
                    _AttackShape.SetVertex(3, new Vector2(x, y + h));

                    yield return inner.Current;
                }

                if (Jumping && !JumpLanded)
                    PlayAnimation("Jump_Falling");
                else
                    PlayAnimation("Stand");
            }
        }

Oddly enough, the function actually got larger. Future refactorings will enable me to shrink it, but for now, it at least has less presentation mixed in – the actual animation itself is passed in via a parameter (inner), and the function is called as a result of being referenced by the animation file, instead of the other way around. The logic for pulling out the current frame is also abstracted out, which is another small but important improvement.

One of the other requirements for my animation system is the ability to set up simple triggers that cause one animation to switch to another. The way I previously implemented this was by checking the triggers every frame, using a convenience function in my C#:

        protected Anim Animation_Stand () {
            return Animation_PingPong(AnimId_Stand, 50 * Time.MillisecondInTicks)
                .SwitchIf(Animation_Stand_to_Walk, () => Acceleration != 0)
                .SwitchIf(Animation_Grapple, () => Grappling);
        }

Now, the entire animation lives in the file, more or less unchanged:

        <SpriteAnimation typeId="1">
            <Name>Stand</Name>
            <Group name="stand" />
            <Frames delay="50" loop="PingPong" />
            <Branches>
                <Branch name="Stand_to_Walk" if="Acceleration != 0" />
                <Branch name="Grapple" if="Grappling" />
            </Branches>
        </SpriteAnimation>

One detail of note here is that this means I’ve moved the conditions from compiled code (C#) to interpreted code (they’re now handled using the same expression evaluator I already use for configuring levels). This has a performance impact, but is worth it since it means I’m free to reload animations without having to recompile the game – particularly important if I’m trying to quickly fine-tune animations, since it cuts out the entire ‘Save, Exit, Compile, Start, Load’ cycle.

Thanks to the fact that my animations were already represented as composited iterators (take an iterator that represents an animation, and then layer another iterator atop it that will play a second animation when the first one completes – and so on), the core animation code didn’t have to change at all, which was a big time saver – when I switched from the old C# animations to the new file-based ones, the animations all looked the same, so I didn’t have to spend any time hunting down minor differences.

One other advantage to this approach is that it’s now a reasonable idea for me to let my artist make changes to the game’s animations, instead of doing it all myself. Even fairly complex animations are understandable:

        <SpriteAnimation typeId="1">
            <Name>Jump_Falling</Name>
            <Group name="jump_fall" />
            <Frames delay="70" first="-2" last="-1" loop="Repeat" />
            <Branches>
                <Branch name="Jump_to_Walk" if="(Running) and (!Jumping)" />
                <Branch name="Jump_to_Stand" if="(!Jumping)" />
                <Branch name="Grapple" if="Grappling" />
            </Branches>
        </SpriteAnimation>

As long as you understand XML, most of it is fairly easy to interpret. The equivalent C# would have been much harder to understand, and easier to break if my artist had to edit it to make changes.

The next thing I did was spend some time getting saved games working properly again. The addition of two-character support broke some parts of my saved game implementation, and it seemed like it was about time to fix them. The core problem ended up being larger than I expected – properly loading a saved game without a lot of hacks meant that I had to rethink the way I structured some of my game code.

Originally, objects like entities and geometry had both design-time and run-time representations. For entities, these were the LevelEntity and Entity objects. You constructed a LevelEntity with basic configuration information on the entity, and then added it to a Level. At runtime, the game would load the Level, and construct a RuntimeLevel object from it. Every LevelEntity would become a corresponding Entity in the RuntimeLevel. The core problem here was that constructing an Entity took a reference to the Game object, not to the Level or RuntimeLevel. So if I wanted to construct a new version of an entity (like a monster, or a player), I had no way to tell it which Level to use – it had to guess.

The first step I took was to rename Entity to RuntimeEntity, because it was getting pretty confusing. :) After that, I bit the bullet and changed everything such that constructing a RuntimeEntity required a RuntimeLevel instead of a Game. This meant I had to shuffle lots of things around, and update some code, but in the end, the payoff was worth it – now, I could load a new level from disk, construct all the entities and geometry, and swap it in for the current level, without any glitches. This was an important requirement for being able to undo actions like destroying walls, killing monsters, etc when the player loaded a saved game.

This change also helps kill off some technical debt I’d accrued in the design – lots of code in various places was jumping through ridiculous hoops, doing things like this.Player.Game.RuntimeLevel.Level.Entities[...]… in order to get at objects, so I clearly needed to rethink my dependencies.

One of my next goals is to add a way to place named ‘markers’ inside my animations, so that the game logic can reference locations like the player’s left hand without having to do arithmetic every frame. Getting that working will go a long way towards shrinking the size of functions like Animation_Punch and allow me to add more detailed animations for things like footsteps and attacks.

Tags: , , , , ,

Throwing potions III

Most of my work this week focused around getting the stone potion working.

One of the first things I had to do was split some of my existing Entity code out into smaller pieces. All the entities I’d written previously were sprites, but the stone potion spawns geometric shapes. I ended up pulling the sprite-related code out into a SpriteEntity class, derived from Entity, so that I could customize entity rendering behavior without having to duplicate the code for mantling, collision detection, etc.

Once that was done, I was able to spawn stone outcroppings at the point of impact of a stone potion, based on the surrounding geometry. The player could walk across them and destroy them. This quickly revealed that there were some issues with my algorithm for walking on surfaces: previously, all the surfaces in the game were simple geometric shapes – rectangles, triangles, circles. The stone outcroppings are irregular surfaces, which meant that some of the assumptions I made previously no longer hold.

Previously, to determine where on a surface the player should stand, I checked the left and right edges of the player along with his center. In order to account for irregular surfaces, I now have to scan across the entire width of the player in small increments to account for variations in height. It’s a slight performance hit, but it ensures that the player can walk smoothly over irregular surfaces cobbled together from multiple stones.

I also discovered that I’d made a mistake when implementing my damage effect code – the code in the XNA framework for maintaining a smooth framerate introduced timing inconsistencies between frames, such that the points where I sampled a damage effect’s curve didn’t match the points I sampled initially when computing the total damage (as described in the previous post). The result was that sometimes a potion would do more or less damage depending on the timing of its impact and the game’s current framerate. The solution to this was to maintain an internal clock for each damage effect so that I could walk along the curve at the same points in time.

The next thing I noticed was that the player had difficulty grabbing onto stone outcroppings and mantling up onto them. It turned out that there were two problems there:

The first problem was that the algorithm for finding a point to mantle onto assumed square surfaces. As a result, the uneven, rounded shape of the stone outcroppings caused it to sometimes select points below or above the surface of the stone. I rewrote the algorithm to work in two stages: First, sweep upward to find an obstruction, starting at the player’s feet, and then sweep upward further to find the end of the obstruction and a new place for the player’s feet to occupy.

Tags: , , ,

Throwing potions II

Not too much progress this week, been busy with other stuff. Most of my development effort went towards potions – there’s a simple HUD that shows the player’s selected potion and you can cycle through them using a button on the controller. I started working on the stone potion, which creates a short-lived rock outcropping when it impacts a surface. The basic functionality is there, but I still need to do lots of tweaking – the shape of the outcropping isn’t quite right, and it needs to decay after a little while instead of lasting forever. It also spawns at the wrong angle when hitting some surfaces, so I still need to figure that out as well.

Tags: , , ,

Damage effects

My goals for the damage effect code were as follows:

  1. I should be able to set a desired amount of damage for an effect to deal over its entire duration
  2. Effects should deal a portion of their damage every frame while an entity is within range
  3. Effects should not deal damage to an entity if it has moved out of range
  4. I should be able to set a curve for a given effect so that I can sync the damage with the onscreen animation (pulsing, fading in, fading out, etc)
  5. Effects should be able to deal a different amount of damage based on how close an entity is to the effect

The first thing I did was to set a pair of values that specify the damage multiplier for the inside and outside edges of the damage effect – this allowed me to create effects with a smooth damage gradient from the inside to the outside, along with effects that have an inverted gradient or effects that deal the same amount of damage over their entire area of effect. I also added a pair of values that control the radius of the inner and outer parts of the damage ramp. The end result looks something like this:

Once I have the damage ramp figured out, it’s easy to map a given point within the circle to a damage value, and I can use that approach to figure out how much damage an entity should take based on its distance from the center.

The next step is to apply a second multiplier, based on a damage curve. This lets me control how long a damage effect is and the nature of the effect – pulsing, fading, etc. The curve takes the time elapsed since the start of the effect as an input, and outputs a damage multiplier (in the range 0 to 1) so that I can multiply it by the distance value from the damage ramp.

Once I have the two multipliers for a given entity, all that’s left is to determine how much damage to deal during the given frame. In order to get this value, I have to come up with a multiplier that will cause the effect’s total damage dealt to sum up to the desired amount.

As an example, if I want the effect to deal a total of 50 damage, and the damage curve I specified is 0.13 seconds long, that maps to around 8 frames. Given that, I can walk over the entire length of the curve, sampling it in single-frame steps. The sum of those values gives me the total value of the curve, which I can then map to the desired total damage value using simple arithmetic. Combining that with the other two multipliers (from the damage ramp and the damage curve) gives me the actual amount of damage to deal during the current frame.

The final implementation ends up looking like this:

public void Initialize () {
    CurveSum = 0.0f;

    float frameLength = 1.0f / 60.0f;
    int numFrames = (int)Math.Ceiling(DamageCurve.End * 60);
    float t = 0.0f;

    for (int i = 0; i < numFrames; i++) {
        CurveSum += DamageCurve[t];

        t += frameLength;
    }
}

public void Update (GameTime gameTime) {
    var t = (float)Game.AnimationTimeProvider.Seconds - StartTime;
    var curve = DamageCurve[t];

    float frameDamage = (TotalDamage / CurveSum) * curve;

    foreach (var hit in FindHits()) {
        float rampPosition = MathHelper.Clamp((hit.Distance - InnerRadius) / (OuterRadius - InnerRadius), 0.0f, 1.0f);
        float hitDamage = frameDamage * MathHelper.Lerp(InnerMultiplier, OuterMultiplier, rampPosition);
        hit.Entity.Injure(hitDamage);
    }

    if (t > DamageCurve.End)
        Game.Components.Remove(this);
}

internal IEnumerable<HitInfo> FindHits () {
    var bounds = new Bounds(
        new Vector2(Center.X - OuterRadius, Center.Y - OuterRadius),
        new Vector2(Center.X + OuterRadius, Center.Y + OuterRadius)
    );

    RuntimeEntityList.ItemInfo itemInfo;
    using (var e = Game.RuntimeLevel.Entities.GetItemsFromBounds(bounds))
    while (e.GetNext(out itemInfo)) {
        if (!bounds.Intersects(itemInfo.Bounds))
            continue;

        float minDistanceSquared = float.MaxValue;

        foreach (var poly in itemInfo.Item.GetCollisionList()) {
            int count = poly.Count;
            for (int i = 0; i < count; i++) {
                var edge = poly.GetEdge(i);
                var closestPoint = Geometry.ClosestPointOnLine(Center, edge.Start, edge.End);
                minDistanceSquared = Math.Min(minDistanceSquared, (closestPoint - Center).LengthSquared());
            }
        }

        if (minDistanceSquared < float.MaxValue) {
            yield return new HitInfo {
                Entity = itemInfo.Item,
                Distance = (float)Math.Sqrt(minDistanceSquared)
            };
        }
    }
}

Tags: , , ,

Throwing potions

Most of my work this week was centered around adding the ability to throw potions of various types.

The first task was to implement basic collision detection for potions. I based this on the code I already wrote for drawing the trajectory of a potion when aiming, as shown in the previous post. The basic structure is that the potion has a position and a velocity, and has a gravitational pull applied every ‘step’. To compute the trajectory for drawing, I iteratively ‘step’ forward along the path of the potion, drawing dots onscreen every few steps, to show the predicted path of the potion if thrown in a given direction. Since I already had the code for that, it was easy to pull the step code out into a function of its own, and then call that from the Update function for the actual thrown potion. The end result looks like this:

internal static bool UpdateMotion (Sapphira sapphira, ref Vector2 position, ref Vector2 velocity) {
    Vector2 newPosition = position + velocity;

    if (sapphira.Game.ResolveMotion(position, newPosition, ref newPosition, sapphira)) {
        position = newPosition;
        velocity = new Vector2(0.0f, 0.0f);
        return false;
    } else {
        position = newPosition;

        velocity.Y = velocity.Y + GravitationRate;
        float dist = velocity.Length();
        if (dist > TravelVelocity)
            dist = Math.Max(TravelVelocity, dist - DecelerationRate);
        velocity = Vector2.Normalize(velocity) * dist;

        return true;
    }
}

internal static IEnumerable<Vector2> ComputeTrajectory (Sapphira sapphira, Vector2 startPosition, Vector2 direction) {
    var position = startPosition;
    var velocity = direction * InitialVelocity;

    for (int i = 0; i < 200; i++) {
        yield return position;

        UpdateMotion(sapphira, ref position, ref velocity);

        if (velocity.LengthSquared() <= 0)
            yield break;
    }
}

The ComputeTrajectory iterator is used by the drawing routines to show the predicted trajectory of a potion, and the UpdateMotion function is used by both the iterator and the actual thrown potion to update motion. Pretty simple, and it works fairly well. One thing that may need improvement is the length of ComputeTrajectory’s projection – right now it just steps 200 times, since that’s ‘about enough’ in all of my test cases to draw a full onscreen trajectory. I may need to come up with a better technique for that in the future if things change.

My initial implementation of UpdateMotion had a bug for a while where if you threw a potion directly upward, it would never fall – this was pretty sneaky, since it resulted from a minor mistake, where I was computing ‘dist’ based on the velocity of the potion before I applied gravity. I spent a little time messing around before I finally realized what was happening, because the visualization I was using to look at the results wasn’t making it clear what was going on. Luckily I caught the bug before writing too much code, otherwise I might have had to waste a lot of time trying to track it down.

Once I had the collision detection working, I spent some time implementing basic animation for the potions, so they leave a trail in the air as they fly and spray out some fluid when they collide with a surface and shatter. Tuning particle effects is a tough job, so I ended up having to make myself stop fiddling with it after a while and move onto something more productive, but it at least does the job.

My work-in-progress is the code for allowing potions to deal damage when shattered – right now, I’m modeling a potion’s impact as a circle, with a pair of radiuses that specify the two ends of a damage ramp. This allows me to create damage effects with a hard edge, damage effects with a softer damage ramp, and damage effects that combine the two (a hard-edged center with a ramp on the outside), which should be sufficient for the potions I have designed currently. To handle the other half of it – the fading in/out of the damage effect, based on the type of the potion – right now I’m just using a Curve that represents damage over time, as a multiplier based on the location of the target relative to the damage effect. I’m not totally certain this will work, but it seems to be effective so far.

public class FirePotion : ThrownPotion {
    public CircularDamageEffect DamageEffect = new CircularDamageEffect {
        InnerMultiplier = 1.0f,
        OuterMultiplier = 0.0f,
        InnerRadius = 16.0f,
        OuterRadius = 64.0f,
        DamageCurve = new Curve<float> {
            {0.0f, 0.25f, Interpolators<float>.Cubic},
            {0.25f, 1.0f, Interpolators<float>.Cubic},
            {0.75f, 0.0f, Interpolators<float>.Cubic},
        }
    };

    public FirePotion (Sapphira sapphira, Vector2 initialPosition, Vector2 direction)
        : base (sapphira, initialPosition, direction) {
        Color1 = new Color(0.9f, 0.4f, 0.2f, 1.0f);
        Color2 = new Color(0.825f, 0.225f, 0.125f, 1.0f);
    }

    public override void Impact () {
        base.Impact();
        Game.SpawnSparks(Position);
        DamageEffect.TriggerAt(Game, Position);
    }
}

Right now you can’t choose which kind of potion to throw, so the game just randomly selects a type every time you throw one. I plan to address this once damage effects are fully working. I’m also not totally happy with the way you aim potions right now – you just choose the initial trajectory of the potion, and you can’t adjust how hard you throw it, so it is a bit difficult to aim in certain directions. I’m thinking I might allow the player to aim at a position instead, and create a trajectory that passes through that point at a given distance, based on how hard you push the analog stick, in order to make it easier to aim.

In the video above, you can see the two different potion types have slightly different particle effects, and different damage ramps (drawn as solid white circles). While the damage effects detect collision with an entity (highlighted with a thin red box), they don’t actually deal damage to the entity yet, since I haven’t worked out the math for it. My goal is for an entity directly hit by a potion to take exactly N damage, since the ramp at the center is always exactly 1. If the entity is only somewhat near a potion, and the ramp’s value is 0.5, I want the entity to take a total of 0.5 * N damage, if he remains within the area of effect for the entire duration. Since damage is dealt over time, I have to determine the total length of the damage effect, and based on that compute how much of the target damage (N) to deal each frame while the entity is inside the area of effect.

Tags: , , ,

Trajectories

Spent some time this week tuning various physics parameters to make things fit with the new size of the player sprites. Things still aren’t quite perfect, but the feel of things is pretty close to what I want.

I also spent some time working on support for one of the player characters’ special abilities – throwing potions. It took a little effort to come up with a good set of constants to give the potion a convincing arc, but I’ve got the ability to aim a potion working and I’m pretty happy with how it feels. Next, I need to get some basic art for the potion into the game so you can see the player throw it, and implement the collision detection so that a potion can shatter when it hits a surface.

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: , , ,