
In object-oriented programming, State Pattern is one of the ways to implement Finite State Machines. This pattern falls under Behavioral Design Patterns.
When in our software, an object can change between multiple possible states and change its behavior according to the state, then, this type of problem can be easily solved using Finite State Machines, and this pattern helps us to achieve the same.
A glance at Mario’s State/Behaviors in Game
Here, I’m taking the example of the Super Mario game. Most people are already aware of this nostalgic game. In this game, Mario changes his states and behaviour based on the events which occurred, which you can see in the below image which I got from Mario Wiki.

Let’s observe states/behavior and events in above image.
States
- Mario (We will refer as Small Mario hereafter)
- Super Mario
- Fire Mario
- Cape Mario
- Lost Life (Apart from the image considering this state)
Events
- Got Mushroom
- Got Fire Flower
- Got Feather
- Met Monster (Not shown in image)
State Transition on Event Occurrence & Earning Coins
The following table demonstrates how the state changes with different events. Apart from the state change, coins are also earned on the occurrence of events.
| Current State | Event Occurred | New State | Coins Earned |
| Small Mario | Got Mushroom | Super Mario | 100 |
| Small Mario | Got Fire Flower | Fire Mario | 200 |
| Small Mario | Got Feather | Cape Mario | 300 |
| Small Mario | Met Monster | Lost Life | 0 |
| Super Mario | Got Mushroom | Super Mario | 100 |
| Super Mario | Got Fire Flower | Fire Mario | 200 |
| Super Mario | Got Feather | Cape Mario | 300 |
| Super Mario | Met Monster | Small Mario | 0 |
| Fire Mario | Got Mushroom | Fire Mario | 100 |
| Fire Mario | Got Fire Flower | Fire Mario | 200 |
| Fire Mario | Got Feather | Cape Mario | 300 |
| Fire Mario | Met Monster | Small Mario | 0 |
| Cape Mario | Got Mushroom | Cape Mario | 100 |
| Cape Mario | Got Fire Flower | Fire Mario | 200 |
| Cape Mario | Got Feather | Cape Mario | 300 |
| Cape Mario | Met Monster | Small Mario | 0 |
Earning Life
On every 5000 coins collected, one life will be awarded.
Implementing in Code
Just to make it clear, Nintendo hasn’t open sourced the Super Mario source code yet. I am just taking the example to help you understand State Design Pattern, like in other articles in the series we will start programming with some code and will be refactoring it gradually.
We created enum (internalState) with the name of all the states, for each event we have methods, where after validating conditions we are setting State property value which is of internalState type and represents the current state of object/Mario. Refer to the below code,
Source Code
State Pattern / Mario / Approach1
- public class Mario {
- enum internalState {
- SmallMario,
- SuperMario,
- FireMario,
- CapeMario
- }
- public int LifeCount { get; private set; }
- public int CoinCount { get; private set; }
- private internalState State { get; set; }
- public Mario() {
- LifeCount = 1;
- CoinCount = 0;
- State = internalState.SmallMario;
- }
- public void GotMushroom() {
- WriteLine("Got Mushroom!");
- if (State == internalState.SmallMario)
- State = internalState.SuperMario;
- GotCoins(100);
- }
- public void GotFireFlower() {
- WriteLine("Got FireFlower!");
- State = internalState.FireMario;
- GotCoins(200);
- }
- public void GotFeather() {
- WriteLine("Got Feather!");
- State = internalState.CapeMario;
- GotCoins(300);
- }
- public void GotCoins(int numberOfCoins) {
- WriteLine($"Got {numberOfCoins} Coin(s)!");
- CoinCount += numberOfCoins;
- if (CoinCount >= 5000)
- {
- GotLife();
- CoinCount -= 5000;
- }
- }
- private void GotLife() {
- WriteLine("Got Life!");
- LifeCount += 1;
- }
- private void LostLife() {
- WriteLine("Lost Life!");
- LifeCount -= 1;
- if (LifeCount <= 0)
- GameOver();
- }
- public void MetMonster() {
- WriteLine("Met Monster!");
- if (State == internalState.SmallMario)
- LostLife();
- else
- State = internalState.SmallMario;
- }
- public void GameOver() {
- LifeCount = 0;
- CoinCount = 0;
- WriteLine("Game Over!");
- }
- public override string ToString() {
- return $"State: {State} | LifeCount: {LifeCount} | CoinsCount: {CoinCount} \n";
- }
- }
- class MainClass {
- static void Main(string[] args) {
- Mario mario = new Mario();
- WriteLine(mario);
- mario.GotMushroom();
- WriteLine(mario);
- mario.GotFireFlower();
- WriteLine(mario);
- mario.GotFeather();
- WriteLine(mario);
- mario.GotCoins(4800);
- WriteLine(mario);
- mario.MetMonster();
- WriteLine(mario);
- mario.MetMonster();
- WriteLine(mario);
- mario.MetMonster();
- WriteLine(mario);
- }
- }

Reviewing Approach 1
On the occurrence of each event, a different operation can be executed based on current state of the object. For example, GotMushroom event -- if it occurs for SmallMario, the character would be changed to SuperMario, but if the same event occurs for SuperMario, it will remain the same. It may lead to confusion to write the same conditions in each method.
To address the problem of approach 1, here I created a separate class for each State, which all are inherited from IState interface. This interface contains respective methods for all our four events; i.e GotMushroom(), GotFireFlower(), GotFeather() & MetMonster(). All State classes are inheriting this. Now, before writing state specific code, we don’t need to check condition, because it’s being written for specific states. All 4 state classes are mimicking our State transition table shown above. Refer to the code.

jason laiPosted May 16, 2023, 6:03 AM
Great Article.Thanks a lot.
Venci VidovPosted Apr 23, 2023, 4:27 PM
I do not understand at all, what you mean with Finite State Machine, one core part is missing. I mean transitions, why? Is there FSM without transitions. I think, there is none. What is the role of Coins in FSM? They have no place in FSM. If like to have a happy hour with double coins? Do I need another FSM? NO, very bad attempt to explain something.
Karthikeyan VRPosted Oct 18, 2019, 1:46 AM
Great Article, Simple approach, Easy to understand, Thanks a lot.
Jeff JurekPosted Sep 25, 2018, 7:58 AM
Ashish, Great article. Thank you. If I may pick your brain for a moment. I am working on a text based adventure just for fun and I still can not figure out how to work timing in to an FSM. For instance, weather, turn based attacks, poisons, healing, etc.... Could you lend me some insight on how to set up the initial machine? -Jeff