Hiatus: half-naked and intoxicated in the Nevada desert

Tomorrow I leave for Burning Man and won’t be returning until Labor Day. The day after that, I’m resuming full time employment at an actual job that pays money, not working for free as an unpublished indie game developer.

I almost decided not to go to Burning Man so that I would have another week to develop the game before returning to work-work. But ultimately, I decided that, since I wasn’t going to finish the game during my leave of absence, and that one more week wasn’t going to make a difference, not ending my time off with Burning Man when I already had the tickets and the camp would be incredibly stupid. So I’m going back to the desert for my sixth (seventh?) time.

The last three months have been incredibly rewarding, and I feel very privileged to have gotten to spend them working on this game. Don’t panic! Development isn’t stopping! It is, however, going to get slowed down by mundane things like the necessity of earning a pay check. It’s unlikely that I’m going to be able to write an update every day while also working another job full time, so I’m backing off my commitment to daily updates in favor of a Monday-Wednesday-Friday schedule.

Thanks to everyone who has encouraged me since I started this project. I’m excited to resume it in September! Until then, if you need me you can find me at approximately 7 and F in Black Rock City, NV.

50 development videos!

My video development log is now 50 videos long! Watch it if you want to see an incredibly sped-up version of the output of the last 3 months of my life. For those of you wondering what it looks like to create a relatively complex video game by yourself, here’s your chance to find out over 20 minutes.

I may have a long way to go before I finish this game, but I’ve certainly come a long way already. Thanks to everyone who has supported me for helping me hit this milestone!

Rolling critters

I gave my pill bugs the circular hull they so richly deserved, so now they roll around when they happen to fall onto their back. Check it out:

For anyone reading this hoping to generate a half circle using Farseer (the C# port of Box2D), I’m pretty sure the current version is buggy. When I asked it to create an arc pi radians wide, I got something that looked like this:

Definitely not a full half circle. I want my money back.

See how it looks like they just chopped off the top 40 percent or so of a circle? Turns out that the Farseer code to create an arc looks like the following:

float stepSize = radians / sides;
for (int i = sides - 1; i > 0; i--)
{
    vertices.Add(new Vector2(radius * (float)Math.Cos(stepSize * i),
                                radius * (float)Math.Sin(stepSize * i)));
}
return vertices;

Given the behavior I was seeing, the loop conditions seemed very fishy to me, like they were chopping off the first and last point in the arc. I changed them to take in the whole range of the angle given, like so:

for (int i = sides; i >= 0; i--)

Sure enough, that gave me my half-circle:

Now that is a decent looking half circle

I went on to add the little guy’s feet to the physics model as well (not pictured), so this particular enemy is about as well-modeled as I can make him at the moment. It’s kind of interesting to see him collide with projectiles and get knocked around. Hopefully I manage to design some levels that can be shortcut by abusing this behavior.

Watch for falling critters

I implemented the simplifications that I talked about yesterday. The change was more difficult than I had in mind, like usual, but ended up being much easier to understand for when I inevitably go back to make further modifications. I made one major one today: the pill bugs will now fall off of any terrain that gets destroyed out from underneath them. Take a look.

I kind of like their little legs waving helplessly in the air. I also might make them roll onto their backs when they fall onto their sides, since that’s what it looks like should happen. In the game’s physics model, the enemies are represented by rectangular shapes, not a semi-circle like the artwork suggests, so I’ll need to come up with some clever way to make the rolling look convincing.

You also might have noticed that the foreground tiles (the grass and mushrooms) don’t disappear when the blocks supporting them get destroyed. Oops. Not sure what to do about that at the moment. I’ll have to give it some thought.

I have a big list of bugs and minor improvements written on a legal pad on my desk. At some point I noticed I was adding to it too often, so I renamed it “the stack,” hoping that would make me pop items off of it, but so far no dice. In the two days I have left to work before Burning Man (and then the return to corporate wage slavery), I think I’m going to cross as many items off that list (or stack) as I can.

It’s been a while since I cocked something up this badly

I’m sure it was something at work that’s getting someone paged as we speak.

First, the good news: I’ve gotten the contour-following algorithm for enemy creatures working with the most complicated terrain I can throw at it. They run fine in both directions, clockwise and counter-clockwise.

I had a hard time getting this working correctly in all cases, and I made things even harder on myself with general ignorance of my libraries and by choosing a poor paradigm upfront. The issue is that I decided early on to keep track of the current direction of the critter with an enum. This wasn’t a bad idea on its own, but it led to me writing lots and lots of switch statements like the following:

switch ( _direction ) {
    case Direction.Right:
        if ( currRotation > 3 * Projectile.PiOverTwo ) {
            EndRotation(3 * Projectile.PiOverTwo);
        }
        break;
    case Direction.Left:
        if ( currRotation > Projectile.PiOverTwo ) {
            EndRotation(Projectile.PiOverTwo);
        }
        break;
    case Direction.Up:
        if ( currRotation > Math.PI ) {
            EndRotation((float) Math.PI);
        }
        break;
    case Direction.Down:
        if ( currRotation <= Math.Abs(rotationDelta) || currRotation >= Math.PI * 2 - Math.Abs(rotationDelta) ) {
            EndRotation(0);
        }
        break;
}

The above block handles stopping the creature’s cornering when it’s making a concave turn going counter-clockwise. I have very similar chunks of code to handle a convex turn, and for both concave and convex turns in the clockwise direction. Each chunk is very similar, but subtly different, and required me to perform mental rotations for every case — and I got quite a few of them wrong. This difficulty was compounded by needing to fix subtle errors more than once, and sometimes forgetting to update near-identical code.

What I finally realized, after banging my head against this wall for a good long time, is that it would be much easier to just add or subtract 90 degrees from the character’s current rotation, then set that as a target and interpolate to that angle over several frames. This is such a drastically simpler solution that I’m going to go back and rewrite the algorithm to use it, even though I got it working the exhaustive, stupid way. I’m 100% certain I will regret not fixing it if I put it off.

Similarly, I was doing a lot of unnecessary work to locate particular points on the Box2D Body in world space. Remember all those switch statements I mentioned?

switch ( _direction ) {
    case Direction.Left:
        if ( _clockwise ) {
            frontEdge = _body.Position +
                        new Vector2(0, -Height / 2f);
            rayDest = frontEdge + new Vector2(0, -Height / 2f);
        } else {
            frontEdge = _body.Position +
                        new Vector2(0, Height / 2f);
            rayDest = frontEdge + new Vector2(0, Height / 2f);
        }
        break;
...

Well, Box2D has solved this issue for me, which I would have known if only I had bothered to research the problem a little more. You can just ask a Body where a particular point in its local coordinate system is in world space, like so:

Vector2 frontBumper = _body.GetWorldPoint(new Vector2(Width / 2, Height / 2));

I’m not actually upset that I made so many mistakes on my first pass implementing this — I set out to develop this game the hard way, so I enjoy taking this kind of beating as long as I learn from it.

Enemies following terrain in both directions

Between river tubing over the weekend and Burning Man prep this week, I didn’t have a ton of time for the game the last few days. But I managed to work out the bugs in terrain-following enemies and get them running in opposite directions. Take a look:

The next step is to make the enemies react to destroyed blocks, but before I tackle that I need to do still more work on the camera system.

The obligatory contour-following enemy

I implemented a beetle enemy that clings to the terrain and follows it in a circular pattern.

Long-time readers will remember this little guy, whom I plagiarized pretty heavily in early alpha builds of the game.

On close inspection, this thing looks terrible. Pixel artists were very lenient with themselves in the 80s. I guess when you’re working with a 16 by 16 canvas, something has to give.

I always intended to have a wall-hugger enemy like this one from the original Metroid; it just wouldn’t feel right not to include one. Mine is kind of a beetle thing. You can see him in action here:

The cornering doesn’t quite work right, mostly because I’m pivoting around the center of mass, rather than the actual pivot point against the corner of the terrain. It was much too hot in my attic office this afternoon to want to do the trigonometry to implement it correctly, so I left it alone for now. I’m also considering just making the creature instantly transition from one orientation to the next when it rounds a corner, without any intermediate rotation. I’ll have to play with it a bit to see what feels right.

I painstakingly animated his little millipede legs to shuffle him along the ground, but they’re basically invisible in the game. I’m still having an incredibly difficult time drawing pixel art, seeing as I don’t know how, at all, but I’m learning. Slowly.

Meet the worm

The first original enemy discovered on Enceladus is a lowly inchworm.

This isn’t the enemy that I set out to make today, but it is the one that I was attracted to as I started drawing. Something about the worm motion was very appealing, and I realized I could just distort a single image to animate it pretty convincingly. So this is what I got. He’s a little tougher than he looks, mostly because when flattened he can duck underneath a crouching shot.

Implementation note: the code that implements the logic to turn the worm around when he reaches the edge of a platform is labeled, in a comment, as the “Roomba cliff sensor.”

Outside the ship

I drew up some tiles for the first subterranean cave section, which you can see here:

I’m still feeling pretty tenuous about my ability to create not-terrible-looking sprite art, but I figure the important thing for the moment is that it exists at all. Looking pretty is a problem for another day.

Attentive viewers will also notice a background-fade effect during room transitions, more or less ripped off from Super Metroid. It’s important in my case because I’m using full-screen background images, and to change between them smoothly requires a fade out.

Finally, I tweaked the mapping system to accommodate non-rectangular room outlines (although they are still screen-space aligned). This isn’t strictly necessary, but it does heighten realism a bit and allows for more interesting level design.

A bevy of graphical improvements

I implemented a bevy of minor graphical improvements this afternoon after spending the morning building a perimeter fence to keep my chickens in the yard. Here they are:

Briefly, these changes comprise:

  • A more interesting looking background image for the ship
  • Foreground objects that the character can pass behind
  • A smaller, denser map overlay without a flashing room indicator
  • More legible conversation text
  • Graphics for the engine room which totally look like a starship engine nuh uh yes they do
  • Chief Mizzen, the ship’s engineer

I’m feeling like I’m having trouble getting over a hill where I stop working on the game’s engine for long enough to produce real content for the game. Finding a balance between the two is paramount for keeping the feeling of momentum alive, so I’m dedicated to drawing / mapping something new every day… except when I really want to work on new engine features which happen to be sweet.

I also learned that when drawing foreground objects, it’s important they have an anchor that is likewise in the foreground, or else it looks really wrong.

The wrong kind of 2.5D

On an implementation note, I went down a bit of a dead-end with the mapping system, which I corrected today. As endorsed by the Tiled Map Editor community, I used a separate, non-graphical tile layer to track collisions, and used the auto-mapping feature in Tiled to fill it in. In retrospect, this needlessly complicated both the code and my workflow. Tiled auto-mapping can be charitably describes as “crufty and frustrating,” and in a 2D platformer, you nearly always want your main block layer to track player collisions anyway. I now have three tile layers, none of them auto-mapped: the background, the collision (“blocks”) layer, and the foreground. This scheme has some drawbacks as well, such as having to copy and paste between tile layers when moving stuff around, but on the whole I think it will be superior.

Finally, I think the new background’s a little off, somehow, but I don’t know how. Let me know what you think in the comments!