Sabbatical Log: November 26th

This blog series is running about a week behind my actual work, giving me time to clean things up.  The date the actual work was done is in the title, horizontal lines indicate when I stopped writing and started coding.

It’s the start of the final week of my sabbatical. I’m still deep in the “move components to an object pool”-branch this morning, but I expect to finish up soon. While I’m in here, I’m also reducing some repetitive passing of new Ids and trying to make the ObjectCreator class (which is responsible for creating room objects at room load time, swords when the player starts swinging, etc.) exhaustively testable.

I’ve finished getting components moved into object pools. As I said earlier, I also added some tests that verify that nothing gets leaked if an error occurs during “object”-creation – where anything is a Component, or an Entity.

When I first implemented those tests, I found I was actually leaking all over the place in failure cases. The causes were a mix of not accounting for errors at all, and forgetting to free components that I failed to attach to an entity.

To make those tests, rather than mock the entire EntityManager I added some bookkeeping that tracked how many “fallible calls” happened and added a switch to force failure after so many of those calls. Then it was just a matter of determining how many calls each sort of object needed, and then failing at N calls, N-1 calls, N-2 calls, and so on. A few objects (like the player) were created via different code paths, so I moved those to the ObjectCreator class and added tests specifically for them (since they aren’t defined via room templates).

I’ve seen it before, but this whole exercise really drove home how much boilerplate code you end up with if you’re manually managing resources. Here’s the code for creating a flower, I’ve marked the boilerplate that handles failures:

As you can see, it’s north of 50% of the code. The whole ObjectCreator class went from 330 lines when I wasn’t doing things correctly, to 1,498 lines at present with all tests passing.

While I am tempted to spend some time shaving this yak, reducing the boilerplate, I think it’s best to move on to the final exit type.

Falling through pits is half-working. New animations and yet-more-complications of the ExitSystem have gotten me to “falling into a pit”, “spawning a new room”, “fading the old out”, and “falling from the ceiling”.

As you can see, there’s still some jank to it. The camera jumps around a bit, and the animations aren’t quite incorrect. While the player doesn’t appear to be in the pit during the first half of the transition, this is actually correct – pits in the game have surrounding assets that extend the black a bit, and accordingly the player’s falling sprites are bigger than the true pit tile.

I have been able to reuse a lot of the infrastructure I built up for the other exits (things like fading and explicit camera control) which is nice, but I’m still not super pleased with the code. Even before fixing the last few things with pits the ExitSystem has 3 separate code paths, 14 different state variables, and totals more than 1,000 lines of code. I doubt I’ll get around to cleaning it up during my sabbatical, since it’s so close to ending, but if I continue this project I’ll definitely want to revisit the ExitSystem once it’s feature complete.

Continue onto November 27th