Game Development Community

Possibly stupid FSM question

by John Haley · in Torque Game Builder · 10/24/2006 (3:14 am) · 5 replies

I was asking a lot about FSMs before my recent wedding. I mention the wedding to explain my lack of progress over the past 3 or 4 weeks. Anyway, I just discovered that this outdated platformer tutorial uses a state machine!

So I'm going backwards by using an old tutorial... and just wanted to check with the experts here, is it OK for me to do this? The tutorial is outdated, so I just want to make sure I'm not doing more harm than good by following this. In other words, I'm worried that the state machine in the tutorial might be outdated, or at least inefficient.

(...also worth noting, I have the file: "t2dFSM.cs" and successfully created my own "echo" test.)

I'm off to pick up my wife at work now. If I don't see any warnings from the community, I'll just give that section of the tutorial a try tonight, and at least see if I can get it to work at all.

EDIT - I see you worked on a Tank Buster demo!! Can I run this game on my Mac?
...Ah --no Mac version. Now I know! And that's half the battle.

About the author

SUMMER PROJECT: Currently working on PSK tutorials. SHORT-TERM GOAL: Make a basic platformer level. LONG-TERM GOAL: Make a co-op platformer in which the two protagonists use their unique abilities to support each other.


#1
10/26/2006 (4:22 pm)
You could go ahead and use the older method if you like. You should know, however, that I wrote t2dFSM.cs to meet the need for an FSM while developing the new platformer framework that's in the works now. The AnimFSM we are using was designed using t2dFSM by the person who wrote the tutorial you're referencing and we both prefer it. Its basically just a subclass that overrides the state registration process and state switching process so it actually stores the animation assciated with each state in the state hash. We did this so it can automatically play that animation when you switch to the state. By default I think the registration just drops an underscore in the hash, this turned out to be really useful and I highly suggest taking advantage of it.

Here is the meat of actorAnimFSM that makes it so slick:
function actorAnimFSM::registerState( %this, %newStateName, %animation )
{
   if( Parent::registerState( %this, %newStateName ) && isObject( %animation ) )
      %this.stateLookup[%newStateName] = %animation;
}

function actorAnimFSM::setState( %this, %newState )
{
   %success = Parent::setState( %this, %newState );
   
   if( %success )
      %this.actor.playAnimation( %this.stateLookup[%newState] );
      
   return %success;
}

The initialization would be something like:

function Actor::initializeAnimations( %this )
{
   %animFSM = new ScriptObject()
   {
      class = "actorAnimFSM";
      superClass = "t2dFSM";
      actor = %this;
   };
   
   
   %animFSM.registerState( "idle", %this.idleAnimation );
   ...(more states below)
}

This creates an animation FSM with a state called 'idle'. When you switch to that state, the animation thats stored in %this.idleAnimation is played automatically. You use the same kind of filter functions you would use for a regular t2dFSM, but now they have the extra functionality to play animations.

Here is one of the old idle state filter functions:

function actorAnimFSM::filterState_idle( %this )
{
   if( %this.actor.attacking )
      return "attack";
      
   if( %this.actor.isOnGround() && %this.actor.jumping )
      return "jump";
      
   if( !%this.actor.isOnGround() )
      return "fall";
   
   if( mAbs( %this.actor.moveSpeed ) > %this.actor.groundSpeed * 2 
      || mAbs( %this.actor.moveSpeed ) >= %this.actor.maxSpeed )
         return "run";
}

Hope this helps!

You can look forward to a lot of nifty and customizeable stuff in the platformer framework, once I have time to finish it. ;)


Edit:...

P.S. - Because of how the t2dFSM works you can switch to a state without playing the animation for that state by calling %MyFSMObject.forceState(stateName). Next time you call checkstate, the FSM will call that state's filter function. Be careful with forceState though because it doesn't check if the state exists and if you force a state that wasn't properly registered (or not registered at all) your FSM will basically be frozen until you explicitly give it a state that exists (via setState or forceState).
#2
10/26/2006 (6:19 pm)
The language within this state machine is WAY easier for me to follow... and I'm happy you're focusing on platformers, since I (finally) decided that my game can work well as a side-scroller. (I want the hero to lift heavy things and throw them, and just thought that would be easier to pull off in a side-scroller rather than overhead view.)

I have the day off (it's Friday morning in HK) and am no longer distracted by thoughts of "is my wife pregnant?" ...so I will devote the next 8 hours to trying to make an FSM animate a player!!

Just wondering... is there any further documentation on this (I mean online, but if it's legal/possible/not too inconvenient to send a file that would be cool) in case I'm still confused? Will there be a new platformer/FSM tutorial once you finish?

I appreciate your help, and look forward to the completion of the new platformer framework!
-John
#3
10/26/2006 (7:26 pm)
I would like to put it up on TDN to replace the current one as a free resource for everyone, but it's really up to the higher up's. It might even be a starter kit full of art and extras similar to the Adventure Kit where you have to pay a small fee for it - I have no clue. I immagine it will depend largely on what it is when it's done.

I was kinda the main one working on it and I had to put it on hold temporarily, so I don't know when it will be finished. Out of the six projects I'm working on right now, that's about number three on my list of priorities. I've been giving it occasional love here and there but hopefully I'll be able to dedicate some serious time to it soon.

As for right now, there are only the few snippets posted on the forums to help people through problem areas but I would be more than happy to answer any questions or help you through issues you might run into.
#4
10/26/2006 (8:41 pm)
Thanks! I can anticipate several problems. If you're still working now (must be late, even on the west coast), here's a quick question:

For defining what it means to run and jump, can I still use the old tutorial? I mean just this page. There is probably a better way, but as long as it will work...

...well, I'll just give that a try anyway. I'll post my player.cs with a "what am I missing" question if I still can't get a successful test today.

EDIT - No working code today, but I did find a helpful post showing me what to do with that isOnGround function! I may be able to find more answers by looking at your post history!! Just the same, I hope the higher-ups allow you (or someone) to create a new platformer tutorial soon. I realize that using out-dated techniques will do more harm than good.

If I make more progress, I'll ask a more specific question...
#5
11/29/2006 (6:55 pm)
Thomas, any progress on the new platformer framework?

As I said I would in my posts last month, I looked through the boards and found some helpful info... but in the end, I was still missing pieces of the puzzle. Or maybe I have all the pieces, but don't know what to do with them. (Ex: which code goes in my player.cs vs. my dataBlockConfig.cs)

As far as I can tell, the current platformer tutorial is that out-dated one that does not use FSMs, pick-line collisions, or anything else I had to dig for in the forums. An experienced programmer could work around this, but me? I don't even have the right to call myself a programmer.

Anyway, I'm hoping to get a hold of a tutorial that can tell me what to do from the beginning to get my character to stand, walk, and jump... from there, I think I could figure out the other states (as long as I can bind diagonal motions)... at least until I get into the fighting, AI, and other tricky stuff!

So where I'm going with this is...
Do you think there will be a new tutorial anytime soon? Or a "Platformer Starter Kit"? (--which I would gladly buy! ...the Adventure Kit was actually quite helpful to me, although I ultimately realized that my game would work better as a side-scroller.)


In the meantime, I need to improve my art skills, so I'm working on making half-decent "programmer art." I do have a question though. Call it a reality-check.

There are basically nine "motion" states (not including transition states, falling, etc.):

UL: Jump Back ----- U: Jump ----- UR: Jump Forward
L: Turn -------------- Idle ----------- R: Walk
DL: Walk Back ------ D: Crouch --- DR: Run

The idea here is that the character is always facing right until he presses "Left" and enters the "Turn" state. This will flip the player's controls as well as the image. Could I bind keys in this way?

Ex: For bindkey "up" and "left"... if flip x = "false" then "jump back", else "jump forward"
The "Turn" state is used to flip x. It's a short animation (~0.2 sec), and the flip would occur in the middle of the animation. That way, if you hit left-down when you mean to walk backwards, you won't accidentally turn and run. (I play-tested this on GameMaker before I purchased TGB... using diagonally-down to run felt surprisingly natural to me!)

Anyway, can I have those "if statements" when I'm binding keys without causing a performance issue? I just want to make sure I'm on the right path...