Gamasutra: The Art & Business of Making Gamesspacer
Finite State Machines
Printer-Friendly VersionPrinter-Friendly Version
arrowPress Releases
April 24, 2014
PR Newswire
View All
View All     Submit Event

If you enjoy reading this site, you might also want to check out these UBM TechWeb sites:

Finite State Machines
by Robert Plante on 02/11/13 12:55:00 am

The following blog post, unless otherwise noted, was written by a member of Gamasutra’s community.
The thoughts and opinions expressed are those of the writer and not Gamasutra or its parent company.



To expand on my earlier post about enumerations I'm going to look at Finite State Machines in a relatively general sense. Let's start with breaking down what exactly a Finite State Machine is. We can look at the descriptive words to see that it is a machine, or system, that consists of a finite number of states. Great, but what does that mean? In a sense it is a way to package your code so only the desired pieces run at the desired time, this makes them very useful for succinct organization. In the rest of the article we'll look at different ways to implement the system, as well as the pros and cons of each.

The first thing to look at is how to define the states within the machine. Many coders will jump to strings as they allow infinite descriptive variation for the states. Another option is to use numbers to label the states. The real question is, why not take advantage of both? I strongly recommend using enums for states whenever possible, they give you the descriptiveness of strings while retaining the efficiency of numbers. Since enums are technically numbers you can increment (++) and decrement (--) them, but refer to them by a text definition.

There are also a few different ways to actually make a state machine. A state machine usually will reside within the main loops of an object, or its update function if it has one. Popular ways to do a state machine include either a switch statement, or if, else tree:

public void Update(){    switch (state) {    case State.state1:        // TODO        break;    case State.state2:        // TODO        break;    default:        // etc.    }        if (state == State.state1) {        // TODO    } else if (state == State.state2) {        // TODO    } else {        // etc.    }}

Here is where I disagree. Instead of a switch or if, else tree I think that it is important to keep the states as separate if statements. This way when your logic changes the state, you can compute the next state right away instead of waiting for the next update. Sometimes you may want to wait for the next update for some particular reason, but typically this is not necessary. While this only works for states going up the tree in progression, you can very easily structure your program as it is below thereby making sure all logic is complete before continuing.

public void Update(){    bool done = true;        do {        if (state == State.state1) {            done = DoState1();        }                if (state == State.state2) {            done = DoState2();        }                if (state == State.state3) {            done = DoState3();        }                // etc.    } while(!done);}

You may have noticed that I am calling functions for each state. I firmly believe in having a modular approach to one's code. It's better to break it off into a function and end up only having one place calling it, then to have to restructure it into a function later. It's also a lot easier to take advantage of return to only use as much of the code as you need. With the functional approach you can also call the logic of an earlier state in a later state if you happen to switch states, or need to correct any missing data. Enclosing your state machine within a while block is really not necessary, but it can allow you to have less frequent update functions and not waste an update cycle on a change.

In a nutshell this is what makes a FSM (everything has an acronym). Your game, or object, works on a series of states thereby limiting the code needed to run. States help keep things well organized and can even prevent erroneous errors bleeding in from rogue code by limiting exposure. Later I will get into the importance of Classes and Object/Aspect oriented programming (OOP / AOP) and how important organization and convention is.

Related Jobs

Io-Interactive — Copenhagen, Denmark

Gameplay Programmer
Io-Interactive — Copenhagen, Denmark

Generalist Tech Programmer
Crytek — Shanghai, China

Mobile Programmer
2K — Novato, California, United States

Senior Tools Programmer