(FSM) Perform an action once when a state is first set

I have a Finite State Machine (FSM) and I want to perform an action when a state is entered/set for the first time, and only that first time. Otherwise, I want a different set of actions to run each time the state is active.

For example:

When variable 'state' = 'falling':
  Trigger once:
    [Initial action]
  [All subsequent actions]

Using ‘Trigger once’ doesn’t work though in this case. I’ve previously used a separate boolean variable to set when a state is first changed, for example:

[Some other code]:
  Set variable 'state' = 'falling'
  Set variable 'state_changed' = true

When variable 'state' = 'falling':
  When variable 'state_changed' = true:
    [Initial action]
    Set variable 'state_changed' = false
  [All subsequent actions]

But it’s not ideal since you need a separate variable. So what I’ve just started doing is setting a slightly different state initially, then changing it to the proper state after the first run:

[Some other code]:
  Set variable 'state' = 'falling_initial'

When variable 'state' = 'falling_initial':
  [Initial action]
  Set variable 'state' = 'falling'
When variable 'state' = 'falling':
  [All subsequent actions]

It’s a bit hackish I guess (since ‘falling_initial’ technically shouldn’t be a separate state), but it works and doesn’t require additional variables.

What do others use in this situation? Any better ideas?

1 Like

I use your third option (an extra state) quite a bit myself. With your example of falling, in my usage I’d name the state “prefalI”.

For me this method is preferable as it fits in with the FSM model, and wouldn’t classify it as hackish. It is a state, after all.

2 Likes

I agree with MrMen. I also feel the 3rd option is lot clearer to view/work with.

I guess it also depends on how much extra logic is in the falling_initial block, if it’s only a single change in animation I might actually prefer #2.

One of the benefits of option #2 is that the boolean variable works for different states. So you can set ‘state_changed’ to true when moving from ‘jumping’ to ‘falling’, and then again from ‘falling’ to ‘idle’. Don’t need separate ‘falling_initial’ and ‘idle_initial’ states/variables…

So it then depends on how strict you want to apply FSM.

Keep in mind you can run into trouble when that same variable is set in one state, and has the wrong affect when the FSM transitions to another state. You could end up doing more work to ensure the change of that variable in one state doesn’t interfere with another state.

1 Like