Simple: Final State Machine
a simple FSM
This is an old project. It was one of the first times I decided to do something more complex than a button, and it was also the moment I started to get interested in game development. Therefore, it is an important milestone in my developer life, and I found the idea interesting enough to be posted. The publishing on GitHub is recent, but the code is old. Very old. The kind of old where you open the file and recognize the person who wrote it, but you are not sure you would trust that person with a production deploy.
The idea here was to make a universal FinalStateMachine class for JavaScript. Did I finish the "universal" part? No. But the logic works, and that is more than I can say for a lot of things I shipped in the same year. The class stores states in a Map, runs them in order, and lets you execute a specific state with a parameter. It is small, it is a little weird, and it has a coffee machine inside it.
The coffee machine
I needed an example that was more interesting than stateA, stateB, stateC, so I built a coffee machine. It turns on, boils the water, adds coffee, dumps the coffee and tells you it is ready. The sequence runs through the states with a timeout, and each state is a callback stored by name. It is a finite state machine wearing a tiny barista hat.
class FinalStateMachine {
constructor() {
this.states = new Map();
this.lastState = null;
this.currState = null;
this.currStatus = false;
this.TurnOn();
this.BoilWater();
this.AddCoffee();
this.Dump();
this.Ready();
}
_AddState(name, callback) {
this.states.set(name, callback);
}
Init(times) {
for (let i = 0; i < times; i++) {
this.states.forEach((state, key) => {
this.currState = key;
setTimeout(() => state(), 1000);
this.lastState = key;
});
}
}
}It is not the most elegant state machine in the world. It uses setTimeout to walk through the list, the naming has underscores in places where underscores should not be, and there is a prompt in the middle of a coffee simulation. But it works, and it taught me the core idea: a state is a name plus a behavior, and a machine is just a list of those with a current position. That idea followed me into every game loop, every UI flow and every "why is this button enabled?" bug I have ever debugged.
Why a coffee machine?
Because finite state machines are abstract until they are not. You can read ten articles about states, transitions and events, and still not feel it. But when you see TurnOn → BoilWater → AddCoffee → Dump → Ready, something clicks. You start seeing state machines everywhere: a traffic light, a checkout flow, a character that can be idle, walking, jumping or falling. The coffee machine was a silly wrapper around a serious concept, and that is exactly why it worked for me.
The universal part
The original goal was to make a class that could be dropped into any project, with any set of states, without changing the class itself. I got halfway there. The _AddState method lets you register states, and execute(state, param) lets you call one by name. But the class still carries its own coffee-specific methods in the constructor, which is a polite way of saying the "universal" part is more of a "mostly reusable" part. I left it as it was because the project had already taught me what it needed to teach me. Not every project needs to become a product. Some of them are just very elaborate flashcards.
The repository
You can find the code here: DrayanInterfaceDesigner/final-state-machine-js. There is a FinalStateMachine.js, a FieldIncludes.js, an index.htm and an index.js with the demo. Open it, read it, and remember that the person who wrote it was younger, braver and much more willing to use prompt in a loop. We all have a file like this somewhere. This one is mine, and I am keeping it.