Javascript Game Foundations - State Management

Ten Essential Foundations of Javascript Game Development

State Management

As our games get more complex, we look for ways to structure our projects to avoid the dreaded
spaghetti code or the big ball of mud.
In the first article we talked about breaking up
our code into a sensible module structure, but that alone is not enough. We still have to be
careful to avoid having too many dependencies between those modules/classes.

There are a number of patterns that we can use to improve our code architecture, and the two that
we will primarily be concerned with in this article are:

A finite state machine provides events that transition between high level states, such as:

load - transition state from ‘initial’ to ‘menu’

play - transition state from ‘menu’ to ‘playing’

pause - transition state from ‘playing to ‘paused’

quit - transition state from ‘playing’ or ‘paused’ back to ‘menu’

… and allows for code to be executed when those events fire:

onLoad

onPlay

onPause

onQuit

… or, for more control, when a particular state is entered (or exited):

onEnterMenu

onLeaveMenu

onEnterPaused

onLeavePaused

A publish/subscribe event system can enhance this architecture by allowing for additional custom
events to occur at any time, e.g:

onCollectCoin

onCollideWithMonster

onOpenDoor

onPlayerDeath

State vs State

Lets take a moment to clarify some terminology. Depending on the context, when we say
game state we could mean one of 2 things:

game values - e.g. positions, lives, scores, level, etc.

game mode - e.g. loading, playing, paused, menu, etc.

This article is about the second case, managing the game mode and responding to events when it
changes. It is during these events that the other kind of state, game values, can be
cleared or set.

Finite State Machines

I would recommend using a 3rd party finite state machine library.

While I try to avoid large frameworks, I am in favor of finding small, discrete, libraries that do
one thing, and do it well. And if you can’t find one then build one, which is what I did during an
earlier game:

This kind of infrastructure allows our game to stay a clean, event driven application instead of
devolving into a complex procedural set of if/then/else statements.

PubSub Events

During the course of a game, there can be many other events that can occur in addition to the
high level FSM state transitions, examples include:

player collects some treasure

player collides with a monster

player shoots a weapon

door opens

etc

There might be many components within our game system that would like to react to these events:

The scoreboard might need to update

The particle system might need to show an explosion

The sound-fx system might need to play an effect

The game might need to transition the FSM state (e.g. if the player loses their last life)

It can be very useful to construct an event publish/subscribe mechanism to handle these custom
events. If you are already using a 3rd party library such as jQuery you might be able to use their
existing custom event framework. If you are
using very modern browsers you might be able to piggy-back off the existing
DOM event framework.

However, if none of these options are available, you can still implement a simple custom event
framework yourself using a pub/sub pattern. There are a variety of ways to implement this
(javascript is a very flexible language). One approach is to manage an array of callback methods to
be triggered when an event is published.

Here is one possible implementation that can turn any target into a pub/sub broker:

Keeping the code structure manageable, flexible, and open to future extensions.

A Note on Function Binding

When adding patterns such as a finite-state-machine, or a pub-sub event system we will find
ourselves having to provide functions as callback methods. Since we are likely to want to provide
object instance methods as the target of these callbacks it becomes very important to understand
how those callback methods are called with the correct object context.

Luckily, there are a multitude of references available to learn about javascript function
invocation:

If you are not already familiar with these concepts then I would highly recommend that you take
some time out to study these articles until you have a good conceptual understanding of Javascripts
(quirky) function invocation patterns.