As I was working on State Machines vs Behavior Trees video (btw check it out, it turned out amazing), I realised something: Designing AI with Finite State Machines is much more cumbersome than with Behavior Trees.
Find out why…
What is a Finite State Machine anyway?
A Finite State Machine (FSM) is a structure made out of States and Transitions. A State can be any action that an enemy performs e.g. Move, Attack, Patrol while a Transition holds the conditions to move from one state to another e.g. is enemy in range, is health low (Picture from above).
By chaining multiple States with Transitions we will get a structure that can simulate different types of behaviors which can create a believable AI System.
FSMs are one of the first systems used in Games to implement Artificial Intelligence. While they are still in use today, better and more modern solutions appeared to tackle the same problem: make the AI behave more realistic.
As easy to set up they also easily fail. FSMs have a lot of limitations that can hinder your Game AI development.
Basically, with each new state, a FSM complexity increases. It’s workable with just a couple of States that have Transitions between them. The real trouble comes when those states increase. Suddenly you need your AI not only to Move, Patrol and Attack but also to perform complex Searches of Buildings, Looting Stashes or Collaborating with other AIs.
The diagram below seems manageable…
… until you realise you also need transitions between the other states …
For a second, the Game Engine stopped and I thought it had crashed. Luckily, it did not. But, it’s clearly visible that Finite State Machines can quickly spiral out of control just by adding 3 more states.
Transitions are not the only issue…
While transitions can make a huge mess out of a FSM (as in the example above), Finite State Machines have another problem that I’ve encountered: code re-usability.
Let’s take the function to move an AI Agent from position A to position B: MoveTo(new_position). This is a good example, as its use can be in both patrolling and following the player.
There are two options to tackle this: A) keep it at the code level, embedded inside the states or B) make it a standalone state. Each with pros/cons.
A) Keep MoveTo in the code, hidden inside the state implementation means that it’s not easily accessible for game designers or people who don’t know how to code. Not only this, but having multiple actions in a state that are not easily visible might make later maintenance a pain, even for people that made them in the first place.
B) The other fix would be to make a state that does the moving. The huge disadvantage to this is the fact that for every other state that requires movement will require a transition to this one. And having multiple points of entry means that the state needs to have multiple points of exit – with the issue of keeping track where to go back.
Still worth using?
Finite State Machines do have a lot of limitations. If you are designing simple Game AIs that do not have more than a couple of different states (IDLE, PATROL, ATTACK) it’s worth looking into.
FSMs work great for Animations, UI interactions, and other game flow control implementations.
Pro tip: you can repurpose most of these systems to create game AIs, instead of building your own Finite State Machine from scratch. And, as a bonus, you will also get a visual editor in most cases.
What about Game AI?
What if you want more complex behaviors, more re-usability? Then you might have to look into other systems like Behavior Trees. Unreal Engine has them out of the box for a reason.
I also did a benchmark between Finite State Machines and Behavior Trees. You can find the video below.
All the best,