Game Development Community

Possible bug: FSMState.Execute called before FSMState.Enter

by Kzoink · in Torque X Platformer Kit · 07/09/2007 (12:56 am) · 1 replies

FSMState.Execute is called before FSMState.Enter on the first state (Idle animation state) in the Platformer demo. I think this is a possible framework bug in the finite state machine as FSMState.Execute is allowed to run before Enter() has been run and Enter() gets called only when transitioning back to that state from another state. This can lead to some unexpected behavior, because Enter() is usually used for setup of the state, and no transition occurs on the first state that gets run by the FSM, so it is not called when running that state for the first time.

In effect, this means the Idle animation specified in the ActorComponent doesn't even play until you have transitioned away and back again. The only reason why the dragon plays the idle animation when you first start the game is that the T2DAnimatedSprite it is based off of is set to the idle animation.

I will fix this in my own code base but I wanted to point it out for others and also ask if this was intended behavior or an oversight? If it is intended, I would be curious as to the reason.

You can test it by placing a breakpoint on the Enter() function of the IdleState class and starting the Platformer demo.

#1
07/09/2007 (1:39 am)
I tracked it down to FSM.Execute.

Basically, the FSM class does not execute Enter unless transitioning from one state to another.

I've run through a few solutions in my mind such as adding a flag for the first run or checking if PreviousState is initialized, but they don't seem very elegant, and I have OCD, so...

I think I will create a dummy state that doesn't require any setup and that immediately transitions to my intended first state and that will solve the problem without any modifications to the framework...

Here it is:
/// <summary>
            /// This state is used to skirt around a small issue in that the FSM only calls Enter when transitioning from
            /// one state to another, and therefore the first state run does not get the benefit of an Enter call.
            /// </summary>
            public class DummyFirstState : FSMState
            {
                public override string Execute(IFSMObject obj)
                {
                    return "idle";
                }
            }

Register it with the FSM as with any other state and then set it as the CurrentState of the IFSMObject you are executing. Whatever string is returned by Execute is the state it will immediately transition to.