Hello! Welcome back to our module on Advanced FSM Patterns.
In the previous lesson, we diagnosed the two primary "growing pains" of complex Finite State Machines: state duplication and transition explosion. We saw how adding more behaviors can lead to redundant code and a tangled "spaghetti" web of transitions that becomes nearly impossible to manage.
Now that we understand the problem, it's time to learn the solution. This lesson introduces a powerful extension of the FSM pattern designed to bring order to that chaos. Our learning outcome is to define a Hierarchical Finite State Machine (HFSM) and explain how it solves complexity issues.
This pattern allows us to organize states into parent-child relationships, much like you'd organize files into folders, enabling logic reuse and dramatically simplifying our state diagrams.
What is a Hierarchical FSM?
At its core, a Hierarchical FSM is simply a state machine where states can contain other state machines. This creates a tree-like structure, or hierarchy.
Let's start with a concise video definition.
The AI of Half-Life: Finite State Machines | AI 101
This clip from the AI and Games channel, which we saw briefly in the last lesson, provides a great high-level definition of what an HFSM is.
Please watch from 05:14 to 06:17. The video explains the core idea: you can group states together, allowing a transition to go to a single state or to a whole collection of states.
As the video explains, you can "group states together" into what are essentially modular, nested state machines. This introduces some new terminology:
- Super-state (or Parent State): A state that contains other states. For example, a
Combatstate could be a super-state. - Sub-state (or Child State): A state that is contained within a super-state.
ChaseandAttackcould be sub-states ofCombat. - Leaf State: A state at the bottom of the hierarchy that has no sub-states of its own. An FSM is always in exactly one leaf state at any given time.
- State Configuration: The full "path" to the current leaf state. If the machine is in the
Chasestate, its configuration is[Combat, Chase].
To dig a bit deeper into these concepts, let's turn to a helpful article.
Hierachical Finite State Machines
This article by Luca Davidian provides a clear, formal definition of the core concepts of HFSMs.
Read the sections titled "HFSM basic concepts:" and "States and state configurations". Focus on the ideas of 'composite states' (super-states) and how the machine is always in a 'state configuration' (the leaf state plus all its parents).
How HFSMs Solve Complexity
Now that we have the basic definition, let's connect it directly to the problems we identified in the last lesson.
1. Solving State Duplication and Code Redundancy
Remember the problem of having Patrol and PatrolWithGun? Or the issue of duplicating logic between Chase and Attack? HFSMs solve this through behavioral inheritance. Common logic can be placed in a parent state, and it will be active for all of its children.
Let's look at a concrete example.
Hierarchical Finite State Machine | by Johan Svensson
This article by Johan Svensson on Medium provides a perfect example of using a parent state to avoid code duplication.
Read the section titled "The hierarchical finite state machine". Pay close attention to the example of a MoveState parent with RunState and JumpState as sub-states. The shared camera logic can live in MoveState, while the specifics live in the children.
This is a powerful concept. The MoveState's update function can handle the camera logic, and then call the update function of its active child (RunState or JumpState). This way, you write the camera code once, and it automatically applies to all movement sub-states. If you add a CrouchState later, it automatically inherits the camera logic just by being a child of MoveState.
2. Solving Transition Explosion
Hierarchies also elegantly solve the "spaghetti FSM" problem. Instead of drawing dozens of lines from every state to a common state (like Dead), you can create one transition from a high-level parent state.

Imagine your NPC is in combat. It might be in the Chase, Attack, or Taunt sub-state. If the player runs away and is no longer visible, the NPC should go back to patrolling. In a flat FSM, you'd need three transitions:
Chase->PatrolAttack->PatrolTaunt->Patrol
With an HFSM, you can group Chase, Attack, and Taunt under a Combat super-state. Then you only need a single transition:
Combat->Patrol(triggered by the "player not visible" event)
This transition is inherited by all of Combat's children. The system checks the current state for a handler for the event; if it doesn't find one, it checks the parent, and so on up the tree. This dramatically cleans up the state diagram and makes the logic much easier to reason about.
How it Works in Practice (A Conceptual Look)
So, how does the machine actually execute this hierarchical logic? While we'll get into the Luau implementation in the next lesson, the core idea is based on traversing the state tree.
A key concept is that a state is an object that can have its own state machine. This allows for a recursive structure.
Code Class - Hierarchical State Machines
This video by AdamCYounis, though using Unity and C#, provides an excellent conceptual breakdown of how to think about executing an HFSM. The principles are directly applicable to our Luau OOP approach.
Watch from 12:45 to 15:54. Focus on the explanation of how states can have their own states, creating a tree. The idea of a doBranch function that recursively calls update on the active states down the hierarchy is the crucial takeaway.
This recursive processing is what enables the behavioral inheritance we discussed:
OnUpdate(): To update the FSM, you callupdateon the root state, which callsupdateon its active child, which callsupdateon its active child, and so on. This cascading call ensures all logic in the current state configuration is executed.OnEnter(): When transitioning into a state deep in the hierarchy,OnEnteris called from the top down. To enterChase, you first enterCombatand thenChase.OnExit(): When transitioning out,OnExitis called from the bottom up. To leaveChase, you first exitChaseand then exitCombat.
This ensures that setup and teardown logic for parent states is handled correctly.
Conclusion
In this lesson, we've formally introduced the Hierarchical Finite State Machine as a solution to the scalability problems of simple FSMs.
Key Takeaways:
- An HFSM is an FSM where states can be nested inside other states, forming a hierarchy or tree structure.
- HFSMs solve state duplication by allowing common behavior to be placed in parent states, which is then inherited by all child states.
- HFSMs solve transition explosion by allowing transitions to be defined on parent states. A single high-level transition can replace many individual transitions from sub-states.
- The execution of an HFSM involves traversing the state tree, typically with
updatecalls cascading down the active branch andenter/exitcalls moving sequentially up or down the hierarchy.
You now have the theoretical foundation needed to build more robust, scalable, and maintainable AI and game logic. You understand why HFSMs are useful and how they solve common design problems.
Next Lesson Preview:
Theory is great, but code is better. In the next lesson, we'll get practical and modify our reusable FSM ModuleScript to support nested sub-states. We'll lay the groundwork for implementing the very patterns we've discussed today.