A good illustration of Hofstadter’s Law

Hofstadter’s Law would make an excellent motto for most software development.

It always takes longer than you think, even when you take Hofstadter’s Law into account.

Getting the bugs ironed out of the scooter has been a pretty good demonstration of this law, with new bugs popping up just as soon as I smack down existing ones. But I did make quite a bit of forward progress, including restricting standing up in tight overhead spaces. I also implemented the ability to manually control the game’s update loop in debug mode. Take a look below:

I probably should have done the latter a long time ago — it allows me to visually inspect things that happen too quickly otherwise, which describes a lot of the trickier Box2d edge cases.

The biggest non-bug hang up was projecting a future shape into the game world to see if it overlapped. I tried a bunch of different techniques, including futzing around with sensors some more, but the one that worked best was good old ray casting. Here’s an example, determining whether the character has enough clearance to duck down into the scooter position:

Vector2 startRay = new Vector2(_body.Position.X,
                                _body.Position.Y + CharacterDuckingHeight / 2 -
                                CharacterScootingHeight / 2 - .02f);
Vector2 endRay = startRay + new Vector2(forwardClearance, 0);
bool roomAhead = true;

_world.RayCast((fixture, point, normal, fraction) => {
    if ( fixture.GetUserData().IsDoor || fixture.GetUserData().IsTerrain ) {
        roomAhead = false;
        positionCorrectionAmount = ScooterForwardClearance - Math.Abs(point.X - _body.Position.X) +
                                    .01f;
        return 0;
    }
    return -1;
},
                startRay, endRay);

My current issue seems to have to do with unavoidable floating point error when manually moving the character around the simulation world. No matter how precise the calculation, in some instances (but not all!) Box2D decides to fire an OnSeparation event when the character’s Body is resized and repositioned, even though the bottom edge of the shape stays in the same place (or as close to same as floating point allows). I’m not sure at this point if I’ll try to revisit destroying and recreating the Body, or hack the event handlers in more subtle ways.

Finally, as promised, a picture of the bacon apple pie I made while on the east side of the state.

Check out that bacon weave

It’s an easy dessert to make (provided you get a pre-made crust), and well worth it. The bacon grease soaks into the crust for an incredibly delicious flavor combination. Yum.

Leave a Reply