Tuesday, April 8, 2014

Blob game

I implemented about a quarter of a 'blob game', and it was an honest nightmare.

A 'blob game', in this context,  is a game built on a mass-aggregate physics system. You control a 'blob' made of constrained point masses (in this case an icosahedron formed of rigid rods and spheres) and maneuver that through an obstacle course  made of point masses, rods, cables, springs, spheres, and maybe also planes if you're feeling ambitious. In addition, the spec called for a level editor of some description, an AI controlled enemy, and a collection system.

I have the character controller. This project was a disaster.

My collisions and constraints only work by the tiniest possible margin, after consuming four times the time they should have to implement. I tried to implement my own version of the collisions algorithm from memory, which went very poorly and produced all manner of strange glitches. I eventually gave up on that and implemented the one in the book very directly. This solved about half of my problems. After sinking three hours into a bug stemming from an improperly-constructed constructor, and another few hours flipping signs basically at random, collisions worked. (A handful of the signs in the examples I was working from were wrong, and another handful were broken due to disparities in my existing code and the existing code in the sample. For example, my code stores mass directly, and calculates inverse mass, rather than storing inverse mass and calculating mass.)

Getting hard constraints (rods) working was a similar process of sign flipping and blind exploration. It's actually a very satisfying way to work when something does finally work, although it's not as efficient as really knowing what you're doing going in. For a while my rods were acting like a sort of strange spring, where they would stop two objects coming too close, but if they ever separated beyond their desired distance the rod would actually push them farther apart forever. Another permutation just made the balls group up tightly as soon as they were destabilized from their desired distance. A combination of these two malfunctions resulted in a stable rod, which is what I'm still using.

Once I had rods working properly, making the blob character controller only took a few minutes. Unfortunately, those were the last few minutes I had, so there isn't terribly much more completed.

My strangest bug is as-yet unfixed. If a collision occurs that has a velocity below a specific threshold, my interpenetration solver would push it at exponentially scaling speeds in the wrong direction, sending the unfortunate point mass to {-infinity, -infinity, -infinity} over the course of the next half dozen frames. My best guess is that it's a floating-point rounding error on a near-zero divisor somewhere, but I couldn't find anything like that, and after a few hours of searchign I gave up. I ended up disabling the interpenetration code entirely, and, surprisingly, it worked fine. At the speeds that objects in this simulation move, the interpenetration code does nearly nothing, and the velocity solver is more than capable of handling collision resolution entirely on it's own. "Comment out the whole function that's screwing up and pray" is never the best solution to a problem, and it's very rarely a functional one. But sometimes you get away with things.