Live from Seoul

It’s a twelve-hour flight from Seattle to Seoul, so I tried to make the most of it by tackling some thorny issues in the game. Even though it’s a situation I wouldn’t usually put myself in willingly, there’s something really nice about being trapped in a seat for twelve hours with no internet access. It makes it easier to stay focused on really stubborn issues like the ones I was determined to solve. And working on my laptop, somewhat less beefy than my desktop at home, is a great way to expose performance issues that I didn’t know I had.

As a first step, I decided it was past time to implement a debug teleportation system, so that I could quickly place myself anywhere on the map. The value of this feature for play testing should be self-evident. Here it is in action:

As you can see, the game doesn’t normally draw anything outside the current room, but when you manually move the viewpoint outside the room it catches on and draws the rest of the world.

One thing that might be hard to notice is that the transition between rooms is quite a bit smoother than it used to be. The room is the fundamental unit of the game world, and room changes are the very important in the simulation. To make physics simulation reasonably fast, only objects in the current room actually exist — when you move between rooms, the game destroys all the simulated bodies in the old room and creates the ones in the new room. On my desktop, this happened fast enough that it wasn’t really noticeable, but on the laptop there was a noticeable stutter every time I went through a door. To address this lag, I changed the room transition code to run in a separate thread so that the camera can move smoothly while it’s occurring. It was a conceptually simple change that was challenging to get right in all the details, but it definitely works a lot better now.

Sadly, I spent most of my time on the long flight dealing with a bug I had recently noticed when destroying a bunch of the landscape, visible in this video:

Around 45 seconds, notice how the character appears to be jumping and landing constantly? That’s because the ground is being created and destroyed under his feet every time a block disappears or reappears. Sadly, Box2d just doesn’t do a very good job managing collisions when bodies are being created and destroyed constantly, and since it’s a continuous floating point simulation it’s inherently unpredictable. The problem above is caused by the game engine erroneously reporting that the character is no longer standing on solid ground, causing him to go into his “falling” animation. As I discovered over the course of long hours debugging at 40,000 feet, the root cause seems to be that the method I was using to determine whether the character is making contact with the ground, involving examining the contacts with his feet, fails about one time in ten when the object he’s standing on didn’t exist in the previous simulation frame. As far as I can tell, there simply is no reliable way to get this information out of Box2d by examining contacts on a body. Ray casting, however, is reliable as ever, and that’s what I eventually gave up and used.

Another subtle bug that I noticed while fixing this one, also visible in the video, is much more mysterious. See how when the character ducks, sometimes he ends up above the ground a bit? As I discovered by painstakingly stepping through this process frame by frame using another debugging utility I built into the game, the problem seems to occur because when the character’s body is resized to its ducking height. Apparently Box2d interprets this change as movement towards the ground, and since the character’s bottom edge is resting against the ground it concludes that there’s a collision that it needs to correct by rebounding the non-static body (the character) upwards. This bug is annoying, but doesn’t seem to be particularly harmful, so I’m considering leaving it alone. I’m tempted to attempt to fix it by destroying and recreating the character’s simulated body instead of resizing it, except I seem to remember that I already tried that and it led to really pernicious bugs like falling through the landscape. Yeah, gonna leave it alone for now.

Next up I’m working on the next major game event, a run-in with the first mini-boss, an automated sentry robot. I have another long flight coming up on Saturday, which will be a good opportunity to get some more work done.

3 thoughts on “Live from Seoul

  1. “See how when the character ducks, sometimes he ends up above the ground a bit?”

    This is crazy, but that sounds a hell of a lot like the “door jump” bug in the original Metroid. I don’t know if it allows the player to vertically traverse collision tiles by continually ducking and standing, but wow.

    As for the falling bug, could you start a timer when falling is reported by Box2d and zero it when Box2d reports landing? If so, you could flag the player as “falling” when the timer is > x seconds (0.5 for example) and flag as “walking” when the timer is <= x, avoiding any "insta-fall" scenarios.

    • I do kind of hope there are some fun glitches for players to discover — just no game ending glitches 🙂

      The Box2d problem is complicated, and comes down to me abusing it for my terrain creation / destruction algorithms. I’ve found lots of problems with various approaches I’ve tried, but the bottom line is that Box2d just wasn’t built to handle the case where simulated bodies are being destroyed and recreated all the time, which is what happens when shooting up the landscape. I’ll probably try to get serious about fixing this particular bug before an actual release, but for now I’m happy to leave it alone 🙂

  2. Pingback: So can I jump or not? Determining if the ground is under your feet in Box2D | Escape From Enceladus Development Live Blog

Leave a Reply