If you're not familiar with finite state machines (FSM's) there's an excellent chapter on State in Game Programming patterns by Robert Nystrom which you can read for free online. It also points out a number of limitations to the FSM pattern which are good to know before you adopt the approach for something.

I use the FSM library in ContentEdit's HTML parser to manage the parser's states (e.g TAG_NAME_OPENING) and transitions between them.


For the purpose of our example we'll define a machine to simulate the states of our pet dragon who we'll call Burt.

// Build a finite state machine for our pet dragon Burt
var burt = new fsm.Machine();

// By default any action will enrage Burt

// If Burt is sleeping then any action will wake him (he's always
// grumpy when he wakes up).
burt.addTransitionAny('sleeping', 'grumpy');

// Various things will sooth Burt when he's grumpy
burt.addTransition('stroke', 'grumpy', 'content');
burt.addTransition('feed', 'grumpy', 'content');

// The only way to get Burt back to sleep is by singing to him
burt.addTransition('sing-to', 'content', 'sleeping');

// Burt is sleeping right now

Now let's interact with Burt:

// Wake him up (he'll be grumpy)
burt.process('call'); # sleeping -> grumpy

// Stroke him to stop him being grumpy
burt.process('stroke'); # grumpy -> content

// Sing to him to put him back to sleep
burt.process('sing-to'); # content - > sleeping

// Let's make Burt mad
burt.process('prod'); # sleeping -> grumpy
burt.process('kick'); # grumpy -> enraged

// The only way to calm him down now is to reset him
burt.reset(); # enraged -> sleeping

Callbacks for transitions

You can provide a callback function whenever you add a transition or set the default transition for the machine, for example:

// Growl when Burt wakes up
burt.addTransitionAny('sleeping', 'grumpy', function () {
    var growl = new Audio('growl.mp3');

If you want your callbacks to be called against another object you can specify the context when creating the machine, for example:

var burt = new fsm.Machine(otherObject);


machine = new FSM.Machine(context)

Create a new finite state Machine, optionally specifying a context for callback functions to be called against.

machine.addTransition(action, state, [nextState, callback])

Add a transition for a state. If nextState is not provided state will be the next state.

machine.addTransitions(actions, state, [nextState, callback])

Add multiple transitions for a state. If nextState is not provided state will be the next state.

machine.addTransitionAny(state, [nextState, callback])

Add a default transition for a state. If nextState is not provided state will be the next state.

machine.setDefaultTransition(state, [callback])

Set the default transition.

machine.getTransition(action, state)

Return the transition for the given action and state.


Return the current state of the machine.


Set the initial state of the machine.


Reset the machine to its initial state.


Process an action.

Always set the initial state (using the setInitialState method before calling the process method).