Modeling player mechanics with a finite state machine

I have three states

• standing
• walking
• jumping

When I press D standing transitions to walking. The velocity will be set to a defined value and the player moves.

When I release D walking transitions back to standing, which sets the velocity back to 0.

When I press W and the state is walking it transitions to jumping, but when the player hits the ground, it goes back to standing.

jumping has a transition land that always leads to standing because a state doesn't know about its previous states.

Since standing sets a velocity of 0 the player stops walking, when he hits the ground.

How do I prevent this?

• During the standing state, before setting the velocity to zero make sure the D key is not pressed. If it isn't pressed when you are in the standing state you can set the velocity to 0. Commented Jun 11, 2014 at 2:58

What you need is a stack based state machine. Essentially store the last state that was set when transitioning. That way, when your state ends, just pop the last state.

1. Walk
2. Jump -> stack.push(Walk)
3. Land -> stack.pop(Walk)
4. Walk

Now, you probably will have to make this work with your keyboard input as well. So you need a way to clear the stack pre-transition.

1. Stand
2. Jump -> stack.push(Stand)
3. Press D -> stack.clear()
4. Land
5. Walk

That being said, this is perfect for a Behaviour Tree instead of a state machine. I suspect your character will do multiple things at once with several conditions. A behaviour tree handles that better. NPC or Players are never in a single state.

You're not just Hungry, you are also Tired, Cold and Wounded. Get it?

State Machines are more suitable for Lightbulbs or Doors. It's either closed/off or open/on.

Until you add complex behaviours, like: breakable, lockable and etc.

• Welcome to Gamedev.SE! +1 for mentioning Behavior Trees
– Katu
Commented Apr 28, 2015 at 13:41

If your state machine engine (if you use one) supports this, add a second transition from land to walk, which is conditional and only is used if the velocity is greater than 0.

This should work, if it is true that only your standing state sets velocity to zero. If your jumping state does that, too, you may need to create a parallel state chain for jumping with starting velocity or an extra boolean value.

I only mention this because keeping the velocity value greater than zero in jumping may have unwanted effects like the player still moving during the flight. (This too is engine dependend)

Why not change from jumping state to standing or walking state depending on keyboard input? It's true you might not have information about previous state but you still have information about current keyboard input, right? So just transition to walking state when you hit land and you're holding D down.