I'm creating a 2D Sidescrolling Action RPG with MonoGame and I am using a finite state machine. A state consists of an animation and some behavior, only one state can be executed at once, however:

If the player is moving left/right and then jumps, or if he's jumping and then moves left/right I want to play a specific horizontal jumping animation while executing the behavior of both states at once. How is this usually handled? Should I make a completely seperate state for this and copy the behaviors over? That doesn't seem right in accordance to the DRY principle.

BTW I'm going to have a lot of similar merge states, so just making an exception this time won't do.

  • \$\begingroup\$ Can you explain me why you are using a finite state machine? What are it's benefits in your scenario? \$\endgroup\$ – Cedric Martens Jun 27 '17 at 20:56
  • 1
    \$\begingroup\$ Look at this game patterns book chapter As mentioned below, pushdown automaton could work, or a hierarchical state machine. As @CedricMartens mentions, is it any real benefit? I would probably just add moving inside the jump state etc. Sometimes DRY can be in conflict with YAGNI or KISS, I wouldn't swear by any principle in particular. \$\endgroup\$ – lozzajp Jun 28 '17 at 8:48
  • \$\begingroup\$ Thanks, guys. I'm going to look into the pushdown automaton to see if it fits the situation. Each character in my game has a set of states, most of which they share. The most simple would be Move, Jump, Fall, and Attack. For the player what triggers entering another state would usually just be a button press, but the AI is going to be a little more complex with an upper controlling layer with more general goals, for example Patrol and Chase. Each state has an animation and some behaviour. Is this not the ideal situation for a fsm? What else would you recommend? With fsm I can reuse states. \$\endgroup\$ – Martin Jun 28 '17 at 11:38

There is a state machine called "Pushdown automaton". It is basically a Stack structure where you store your states. In your case, you could implement such a state machine, which isnt as hard. If your move state should be able to continue with jumping, you have to implement a dependency check(like in the code below).

This is an pseudocode example implementation in C# style(not tested):

Stack<State> states = new Stack<State>();

public bool ApplyState(State state){
    State latestState = states.Peek();
    // Immagine your latest state is STATE_MOVE
    // STATE_MOVE can continue with STATE_JUMP, so you can push STATE_JUMP to the stack
    // WARNING: "latestState" has to check if the parameter "state" alreay is its parent.
    // If you move and jump and move, you would have STATE_MOVE twice, because both can continue with each other. 
    if(latestState == null || latestState.CanContinueWith(state)) 
        return true;
    return false;

// This function updates your state. 
// Keep in mind that you may have to change the update order
//  of the states because it is Last-in-First-out
public void UpdateStates(){
    foreach(State state in states){

This is how my implementation would look like.

Maybe this can give you an idea how to solve the problem.


A good solution example for such a situation is how animations are handled in different engines. Let's take for this example the unity engine and it's mecanim animation framework. The animations in there are also finite state machines. So if you need to play 2 animations at the same time, they introduce layers. So you have let's say a layer for the feet and one for the upper body. So if the character has to run and do shooting the feet layer will play the run animation and the upper body layer will play the animation for the shooting. So in your example I would break down the animations and states into different layers. So when you need to add up states, you simply have each layer played. So basically multiple finite state machines that run simoltanious.


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.