The long awaited FSM has been implemented, an an alternate title for this post might be “Many steps taken, back where we started” since for the most part the only outwardly visible change to anything is some console output and the fact that you can no longer move the player avatar while a ball is dropping through the maze (which presumes you ever tried).
Still, this lays the groundwork for what’s to come and I’ve already built out some new framework for the upcoming changes, so that’s good.
I don’t think I ever mentioned in any post, but an FSM is a Finite State Machine. You can read the linked Wikipedia page for a bunch of gory detail if you so desire, but basically speaking it’s just an abstract machine that has a finite number of states it can be in, and it can be in only one of them at a time. There are specific rules in place that indicate when the state of the machine changes and to what new state, and this is the logic that drives our game.
This took a little longer today that I originally anticipated because I went down a few TypeScript research rabbit holes based on how I was originally envisioning implementing the machine. I wanted to have the states built right into the machine class itself (instead of as a separate enumeration) and discovered that I could do that if I updated my TypeScript compiler to the latest version. After doing that and starting implementation, I decided that I didn’t like how that was going, so I ditched it.
In the end I went with a simple standard implementation of a class that can tell you what state it is currently in, what state it was in before the current state (to help assist with logic choices when swapping states) and changing the current state. I also implemented a short list of states that should probably exist, although this can be fleshed out as we expand, for example a state specific to deciding the coin toss for who plays first (currently it’s always the player).
Using the new state logic existing code was modified to use it although the end result is that the same things happen as they did before, except for a different reason. Previously the Maze entity would generate the maze when it was finished loading its images, but now it generates the maze when the scene its in becomes active. Similarly there is now also an active state when it is the player’s turn and when a ball is currently dropping.
If you look in the console of your browser you can see the engine swapping states as they happen. Additionally the input handling for player controls has been factored out to its own method that does nothing when it is not the players turn. Thus the other visible change is that once you push the ball, you can no longer control the player until the ball has finished moving.
Tomorrow I will continue slowly filling in the various states and shifting the code around to handle them as appropriate. Already the code is reading a lot cleaner than it was previously, which makes further development easier, I think.