I'm not sure if it belongs here or somewhere else so MODS, feel free to move it you think it's inapropriate here)...:
In my game, my player character has a set of 9-possible "animation states" consisting of Normal, Shield, Boot, Glove, Shoes, Spring, Kite, Ball and Rope. Furthermore, he also has a set of 4 "internal states" consisting of Normal, Jumping, Flying and Falling.
Now, having done some preliminary designing, I've decided the following "interactions" were possible (CODE snippet used for brevity):
1) When the player's "internal state" is Normal, the player may
change from any one animation state to any other animation state
except for the Kite animation state.
2) When the player's "internal state" is Jumping, he may change
from his current animation state into one of the following: Kite,
Rope or Spring; assuming he has attained those skills.
3) When the player's "internal state" is Falling, he may change
from his current animation state into one of the following: Kite,
Rope, Spring (assuming he has attained those skills) or Normal
(indicating special power has depleted).
4) A change of "internal state" from Normal to Jumping occurs upon
user demand ("Jump" key is pressed). The "internal state" of
Jumping represents the fact that the player's Last Y-Position is
Less than the player's Current Y-Position in world-space (the
player is now higher in altitude than the last check).
5) A change of "internal state" from Normal or Jumping to Falling
occurs automatically. The "internal state" of Falling represents
the fact that the player's Last Y-Position is Greater than the
player's Current Y-Position in world-space (the player is now
lower in altitude than the last check).
6) When the player's "internal state" is Flying, he *must* be in
the Kite "animation state". This also means that the
player's "internal state" *must* be set to Flying whenever the
player's "animation state" is Kite. Since a player may only change
to the Kite "animation state" while either Jumping or Falling, it
is impossible for the player's "internal state" to go from Normal
to Flying without first entering either the Jumping or
Falling "internal state" first.
Now I've been researching all weekend for ways to:
1) Document this set of interactions - specifying the various relationships between "internal state" and "animation state" beyond the textual descriptions I provide above...
This research has led me to believe that Z-Notation would be the most succint in defining the relationships; however, from what I can gather Z-Notation is not very standard and is thus a more-specialized form of notation. Perhaps a series of tables (1 for each "internal state") would be more graphically appealing and intuitive to understand by an outside reader of my design/technical documentation? I've considered "state diagrams" as well, however, they are (in my opinion) a "fluster cuck" of jibberish and icons to understand - perhaps, that's just my lack of understanding on the subject...
2) Implementing these proverbial "rules" in code in an as "straight forward" means as possible without turning my code into speghetti by nesting switch() inside of switch() for each set of relationships.
Again, my research leads me to use the proverbial "state" class here (and further suggests a "state machine" class; however, I'm not quite understanding how to relate "internal state" with "animation state" using this approach... Perhaps some guidance from some of you may assist me in this particular matter?
At present, my current thoughts on implementation are to take 3-values:
1) current "internal state",
2) current "animation state",
3) proposed "animation state"
and combining them into an int value (32-bits) using a formula such as:
test_value = (((internal_state << 16) | (curr_anim_state << 8)) | prop_anim_state);
switch(test_value)...
In this way, I can define my case values such that all "internal state" values are *grouped* together. Of course, this means that in a worst case scenario, I could have up to 16+ million possible case values to test (ie: speghetti code) if I were to ultimately define another 252 "internal states" with another 247 "animation states" (overkill I know, but I want extensibility/flexibility without complications)...
Right now, however, I am left with 4*9*9=324 possible case values to test; of which, 90% or so can be left to the *default* action of "do nothing"... But is this the way to go?
So, my real question is; How would you attack this scenario in your own projects? Please be as specific as possible (technically speaking) so that I may understand *what* you are doing, and more importanly, Why!
I'm not asking for code (per se) except as illustration. What I need, is to understand the choices that you would make in this situation and why those decisions make sense...
Unfortunately, this is now the hold-up of my current project. And it disappoints me to think this is the "player" character and not the AI entities... What throws me is the dual-level of hiearchy in the state-machine (hence the HFSM in the thread's title)...
How would you approach this in your own projects?
Your Responses and Advice would be greatly appreciated,
JTK