Question about state design

Hello Everyone!

After watch 3 Udemy course and messing around with Unity, I decided to get my hands dirt with my 1st real project. No, it’s not a platformer :smile: More like NES Dragon Warrior 1 / Final Fantasy 1 project with a smaller scope at first.

I am currently documenting / detailing various aspect of the project and I am unsure how to approach the player states. I read about it and watch some YT videos, but one thing I am not sure about and didn’t read much about, is how to have 2 StateMachine interacting with each others or if it even make sense.

For example

StateMachine
PlayerIdleState : A simple idle animation state
PlayerMoveState : Move animation and top/right/down/left flip
PlayerInteractState : When interacting with NPC, bring the interaction UI, etc.
PlayerBattleState : Switch to BattleStateMachine

BattleStateMachine
BattleInitState : Setup Battle UI, enemy, calculate who goes 1st, etc.
BattlePlayerTurnState : Player’s turn
BattleEnemyTurnState : Enemy’s turn
BattlePlayerWinState : Player win
BattlePlayerLooseState : Player lost - back to main menu

Once the player wins, it would go back to PlayerIdleState.

I am not sure how different state handler can interact with each others or if it’s even a good idea but I was thinking it might be cleaner than having 1 state machine with all the possible states.

Any though/suggestions/tips?

Thanks

I’m definitely a fan of using enums, as a matter of fact, the project I just started has a small example:

public enum GameState
    {
        Menu,
        PlayerTurn,
    }
    public GameState gameState;

    public enum SelectState
    {
        None,
        HexOptions,
    }
    public SelectState selectState;

And to add, for more performance(less frame checking) you can add another enum reference, to be a “last” check:

public enum SelectState
    {
        None,
        HexOptions,
    }
    public SelectState selectState;
    public SelectState selectLastState;

for occasions that can sometimes help with calling something only once.

So after that, it’s just up to you how to control your “if” statements. Another trick, is when code starts to “speghetti” is you can make your own bools:

if (AllisWell()) { stuff(); }

private bool AllisWell()
{
   if (gameState != GameState.Menu) { return false;}
   if (playerState == PlayerState.PlayerTurn) { return true; }
   // etc...
   return false;
}

All depends on how you feel comfortable keeping track of what’s doing what. Because most importantly, understanding your code is rule#1!

FSM finite state machines:

I suggest never using the term “state machine.” Instead, just think:

  • I have to keep track of some THING(s)
  • That THING might change due to reasons
  • Depending on that THING, my code might act differently

That’s it. That’s all it is. Really!! The classic example is a door:

  • track if it is open or closed
  • if it is open, you could close it
  • if it is closed, you could open it
  • if it is open you could walk through it
  • if it is closed you could bump into it

Wanna make it more complex? Put a latch on one side of the door.

This is my position on finite state machines (FSMs) and coding with them:

I’m kind of more of a “get it working first” guy.

Ask yourself, “WHY would I use FSM solution XYZ when I just need a variable and a switch statement?”

All generic FSM solutions I have seen do not actually improve the problem space.

Your mileage may vary.

“I strongly suggest to make it as simple as possible. No classes, no interfaces, no needless OOP.” - Zajoman on the Unity3D forums.

It would certainly be cleaner keeping them separate. Why do you need the two state machines to “interact with each other,” though? It seems like during the battle, you just flip the battle state machine on and let it do it’s thing. There’s really not much interaction going on so it shouldn’t be difficult to coordinate this.