top of page
Search
  • Writer's pictureFox Forge

Game Development - Finite State Machines: Entry 3

Updated: Apr 25

One of the aspects for our game development this period was AI. With personal experience in the area, I was take lead with implementing behaviours for the agents in our game to provide a compelling gameplay experience.


What are they and how do they work?


Simple finite state theory dictates that given context A and current state B, an agent will move into State C. It’s an extremely logical architecture which is effective at illustrating characteristic behaviours where an agent is in one state at any given time.

Fig. 1 - Basic two state principle of finite-state-machines



Over the years, adaptations and advancements to FSMs have involved hierarchies of sub-states which create further in-depth behaviours. Furthermore, frameworks have been made to secure states with transitions, which make development extremely easy since the code is verbose and clear to programmers.


Fig. 2 - Diagram of a Hierarchical Finite State Machine (HFSM)



State machines apply commonality between states for managing by a controller or agent. Generally, a state will be defined as some type of abstract class with an update function and transition function at the bare minimum. They could also have utility methods to invoke around the main functions such as before leaving or entering the state. This abstract base class is then derived from for each characteristic state, and all the pure virtual functions become the target of overridden implemented state behaviour.

Fig. 3 - Example Code of an abstract state class to be used for an FSM



Fig. 4 - Example Code of a basic behavioural state and how it should be implemented with the inherited abstract base state class. (Links with Fig. 3)



This makes it extremely easy to define specific behaviours given a certain transitional context. Not only will this help create a believable gameplay experience for the player, but it will help hugely for development cycles as the FSM can be debugged and traced to exact states and transitions.

When the systems are first created as instances, you should add all states you want to a system, along with the transitions to other states from them.

The system should keep track of a pointer to the current state and should invoke the update and transitional functions wherever you need an update – mostly you want this every frame. This way, any transitions are made naturally alongside the actions and you can just sit back at let it run!

Fig. 5 - Example Code of an FSM system being updated inside a coroutine



When to use them and Why?


There are many options when it comes to AI architectures, so it is important to find the right one to suite your game. As mentioned and shown, Finite state machines are very good at logical behaviour and can do a great job when it comes to delivering a solid and robust framework. However, they have a distinct disadvantage when it comes to creating complex agent behaviours. If you are looking for an agent to learn and adapt, there are only so-many sub-states you can create within a hierarchy before the FSM quickly becomes

un-maintainable, due to the creation of many states and sub-states which can be hard to keep track of in a large project. As such, FSMs are the ideal architecture for basic logical behaviour such as “Idle”, “Patrolling” and “Attacking”, with simple transitions such as “Player In Sight” or “Player In Attack Range”. However FSMs should be avoided when trying to create complex entities for your game.


How our game uses FSMs


In our game development, we are using FSMs for the behaviours of all agents apart from our Boss. Once again this is due to the logical behaviour of our enemies whereas our boss has a slightly alternative approach as a specific encounter with many dynamics which are not best suited for an FSM.

Fig. 6 - Example Code of a further derived state for variety in agent characteristics.



The behaviours for our enemies are not far from the common conventions. However, I have adapted some states to derive their functionality further to give multiple options of states to choose from when the agents awake. For example, the ChaseBehindState derives the ChasePlayerState to change the chasing position behind the player it has chosen, rather than their exact position. Different behaviours like this will stop players exploiting loop-holes and patterns with predictable AI, which basic FSMs tend to fall victim to. On the other hand, this should be in balance with what the agents are intended to do. You do not want to create options for behaviours which will make the agent unbeatable or unrecognisable.


Fig. 7 - Example code of selecting from a variety of similar behaviours and adding them to the FSM for a specific entity.



Some of our enemies are characterised to chase and be aggressive, while others are characterised to attack once they are in range at a moderate distance. A good starting point for anyone creating for an agent is to design its behaviour on paper. Once this is done, they should make sure they keep their implementation within the general characteristic for the entity.


Future AI development

With regards to larger systems and future work, our game intends to use a director to control the agents much like Left for Dead 2. Once the director has placed the agents in the scene, their FSMs will take over and follow programmed behaviours.

76 views0 comments
bottom of page