Tuesday, May 07, 2013

One must FAIL.

I've been investigating that "stuck in walls" bug for some times now, with little luck to fix it. I'm finally reaching the conclusion that this is not an usual bug, but the bitter outcome of some short-coming in the current implementation of the game engine.

The behaviour of Bilou and NPCs in the game is ruled by some iGobController classes, such as DPAD processing, momentum, gravity and the like. At each frame, each of them think() to evaluate the current game state and adapt the character's state accordingly (e.g. make it fall faster in the case of gravity controller).

The outcome of this "think()" function in turn defines whether some transitions on the state machine should be evaluated. It may either be NONE (no transition involve, we happily stay in the current state), EVENT (something special happened, like the direction reverting or some key being pressed, for which an change in the animation might be desirable), and FAIL (impossible to hold the current state for longer, e.g. we've landed on the ground, there's no further falling possible).

Initially, when Bilou FAILed to fall, it usually meant that the next move would take him into a wall, and so the move itself was cancelled. Yet it proved to be impractical alone. I had need for the impact speed so that e.g. I could decide to make Bilou bounce if the speed was high enough. Then I had need for aligning the move to the closest wall, and not simply cancel it.

All in all, the remaining code is killing speed where it should better not, and obviously not killing it where it would have to. That smells like some legacy code that need to be re-thought from cleaner base.
[done] FAIL => can't do more than this frame in this state. (but move isn't necessarily cancelled)
[done] no longer sticks on walls
[todo]  hspeed is reset to 0 when Bilou leaves a platform. That should only be the case if forced so by a GobExpression
[think] smoother slope-to-fall transition required.

No comments: