In standard game development, we are taught that variables are silent containers. A bool is just a box that holds true or false. It doesn't do anything. To know if it changed, we have to pester it constantly:
// The Old Way: The Polling Trap
void Update() {
if (isDead == true) { // Asking every single frame...
PlayDeathAnimation();
}
}
This is the "Silent Variable" problem. It leads to spaghetti code, race conditions, and Update() loops clogged with thousands of if statements checking for things that haven't changed.
But what if a Boolean wasn't just a box? What if it was a Finite State Machine?
1. The FSM_Bool: The Atomic Unit of Behavior
By wrapping a primitive in an FSM, we transform it from Passive Data into Active Behavior. It doesn't just hold a value; it has a lifecycle.
- Enter True: Fire the event (e.g., "Turn on Light").
- Update True: Maintain state (e.g., "Humming sound").
- Exit True: Cleanup (e.g., "Fade out light").
Suddenly, your logic is decoupled. The code controlling the light doesn't need to check the switch. The switch tells the light what to do.
// The New Way: Reactive Primitives
var lightSwitch = new FSM_Boolean(
name: "LivingRoomLight",
startValue: false,
onTrue: (ctx) => LightFixture.TurnOn(), // Fire and forget
onFalse: (ctx) => LightFixture.TurnOff() // Fire and forget
);
// To operate it, we just change the target. The FSM handles the logic.
lightSwitch.Set(true);
2. Evolution: The FSM_FloatLimit
The concept explodes in potential when we move beyond Booleans. Consider the float. Usually, we use floats for Health, Stamina, or Mana.
In the old world, a Health System is a messy manager class. In the FSM world, a Health System is just a single Float with a Threshold.
Introducing the FSM_FloatLimit. It is an FSM that monitors a value and triggers a transition when a threshold is crossed.
The Constructor:
var healthSystem = new FSM_FloatLimit(
currentValue: 100.0f,
threshold: 0.0f,
OnThreshold: (ctx) => Player.Kill()
);
The Internal Logic (Abstracted):
Inside the black box, this FSM has two states: Safe and Breached.
- State "Safe": The value is above the threshold.
- Transition: If
Value <= Threshold -> Go to Breached.
- State "Breached": Execute
OnThreshold.
You no longer need a PlayerHealthManager.cs. You just need a smart float.
3. Complex Data Shapes from Simple Primitives
When you start composing these "Smart Primitives" together, you aren't writing code anymore; you are sculpting Logic Shapes.
Imagine a Weapon Reload System constructed entirely of primitives:
- AmmoCount (
FSM_IntLimit): Triggers "Empty" when it hits 0.
- ReloadTimer (
FSM_FloatTimer): Triggers "Complete" after 2.0 seconds.
- IsReloading (
FSM_Bool): The master switch.
The architecture becomes a chain reaction:
AmmoCount hits 0 -> Sets IsReloading to True.
IsReloading (True) -> Starts ReloadTimer.
ReloadTimer (Complete) -> Refills AmmoCount and sets IsReloading to False.
Beyond Numbers: The Reactive String
The power of the "Sentient Primitive" isn't limited to simple math. It transforms how we handle text and input.
Consider the standard way we handle cheat codes or spell casting in games: we log every keystroke into a buffer and run a string comparison every frame. It is tedious and error-prone.
In our FSM-driven world, we treat the String as a Stateful Pattern Matcher.
The FSM_Regex
Imagine an FSM initialized with a Regular Expression. It doesn't just "hold" a string; it hunts for a pattern within the stream of data you feed it.
// Defining a "Spell" using a Reactive String
var fireballSpell = new FSM_Regex(
pattern: "UP, DOWN, A, B", // The Konami Code of magic
OnMatch: (ctx) => CastFireball(),
OnFail: (ctx) => PlayFizzleSound()
);
// We just feed it inputs. The FSM tracks the sequence state internally.
fireballSpell.Input("UP"); // State: Tracking...
fireballSpell.Input("DOWN"); // State: Tracking...
fireballSpell.Input("X"); // State: Failed -> Trigger OnFail -> Reset
This turns complex input handling into a simple definition. You aren't writing an "Input Manager"; you are just defining the shape of a valid command.
The Paradigm Shift: Composition over Management
When you adopt this mindset, the "Manager Classes" that plague modern software development start to disappear.
- You don't need a
HealthManager; you have an FSM_Float.
- You don't need an
InputComboManager; you have an FSM_Regex.
- You don't need a
DayNightCycleManager; you have an FSM_Timer.
You are creating a visual language where the "bricks" of your building aren't dead clay; they are active participants in the architecture. They know when to hold together, and they know exactly when to break apart.
Visualizing the FSM_Regex

Resources & Code:
The FSM Package (Unity Asset Store):
https://assetstore.unity.com/packages/slug/332450
NuGet Package (Non-Unity Core):
https://www.nuget.org/packages/TheSingularityWorkshop.FSM_API
GitHub Repository:
https://github.com/TrentBest/FSM_API
Support Our Work:
Patreon Page:
https://www.patreon.com/c/TheSingularityWorkshop
Support Us (PayPal Donation):
https://www.paypal.com/donate/?hosted_button_id=3Z7263LCQMV9J
We'd love to hear your thoughts! Please Like this post, Love the code, and Share your feedback in the comments.
