A simple but useful Finite State Machine (FSM) in C++

Why?

When developing games, I often need FSMs. Most of the time, they are simple with only a few states. Some examples of state machines I used in previous or current games:

  • Tutorial: each state represents a step in the tutorial
  • UI : The animated elements are using a FSM to transition from “on-screen” to “off-screen” going through a “moving” state.
  • Game State : Playing, Paused and End-of-level screens

Some complex FSMs are often used in AI. I used some in this prototype.

Features

I realized that I always implemented the same methods when adding a FSM into an object, therefore I took a few minutes to implement a simple class I could re-use easily. Here are the features of this FSM:

  • The states are represented by an enum (easy to debug)
  • To run the FSM, just call SetState and UpdateFSM( float delta_time )
  • Get the current state using GetState()
  • Many transitions are based on timing. Therefore, I implemented a GetTimeInCurState() method
  • Perform your specific actions in methods BeginState, EndState and UpdateState

Source Code (.h)

// (c) Francois Guibert, www.frozax.com (@Frozax)
#pragma once

template<typename T>
class fgFSM
{
public:
	fgFSM() : _time_in_cur_state(0.0f), _cur_state(-1)
	{
	}

	virtual void BeginState( T state ) {}
	virtual void UpdateState( T state ) {}
	virtual void EndState( T state ) {}

	void SetState( T state )
	{
		EndState( (T)_cur_state );
		_cur_state = state;
		_time_in_cur_state = 0.0f;
		BeginState( (T)_cur_state );
	}

	void UpdateFSM( float delta_time )
	{
		if( _cur_state != -1 )
		{
			_time_in_cur_state+=delta_time;
			UpdateState( (T)_cur_state );
		}
	}

	float GetTimeInCurState() { return _time_in_cur_state; }
	T GetState() { return (T)_cur_state; }

private:
	float _time_in_cur_state;
	int _cur_state;
};

Usage

First create the enum you will use for the states, such as:

enum EState
{
	STT_OFF = -1, // optional, -1 is the initial state of the fsm
	STT_WALK,
	STT_RUN,
	STT_STOP,
	STT_EAT
};

And inherit from the class fgFSM:


class ObjectUsingFSM: public fgFSM<EState>
{
public:
	// ...
	void UpdateState( EState t );
	void BeginState( EState t );
	void EndState( EState t );
	// ...
};

Improvements, Closing Words

That’s it, feel free to use the code in your games/projects. This is very simple but often more than enough. The other feature you might need one day is having a GetPreviousState() or even a GetNextState() usable in EndState().
Questions? Contact me on twitter @frozax or comment here.