Take the 2-minute tour ×
Game Development Stack Exchange is a question and answer site for professional and independent game developers. It's 100% free, no registration required.

I'm making a game that plays a bit like Diablo, but you can harvest resources like in an RTS.

I have the following states in my FSM: IdleState, ApproachingTargetCoordinateState, ApproachingTargetEntityState, CuttingTreeState.

When a user clicks a tree, Player.targetEntity is set to the corresponding Tree instance (which inherits from Entity) and the player's state is set to ApproachingTargetEntityState. When the player reaches the tree, a transition is made to CuttingTreeState. Shortly after, the tree is cut down, and state is changed back to IdleState.

At this point, I'd like the Player.targetEntity reference to be removed because its no longer needed. Where should I put the logic that does this?

I could do this in the CuttingTreeState#exit() method but that would only work in situations where everything happens as described above. If for instance the user clicks a random coordinate (not a tree) before the player reaches CuttingTreeState, CuttingTreeState#exit() is never run and so Player.targetEntity is never removed.

I can't put it in ApproachingTargetEntityState#exit() either, as that would remove the reference to the tree before we get to CuttingTreeState.

Another solution would be to just not care about Player.targetEntity. But it just feels wrong to me that the attribute is set for example when the player is in the IdleState.

How can I solve this problem? What is usually done?

share|improve this question
    
How about clearing it on entry to the IdleState? –  Nathan Reed Aug 5 '13 at 17:59
    
Thank you for your reply @NathanReed! Potentially the player could be walking around in the ApproachingTargetCoordinateState for a long time before hitting IdleState, so clearing it in IdleState is only a half solution I think. Also, if you consider the concept of "separation of concerns", IdleState ideally shouldn't know anything about trees. –  Rasmus Rønn Nielsen Aug 5 '13 at 18:15
add comment

1 Answer

up vote 2 down vote accepted

One option is as Nathan's comment, just identify when and where the values need to be cleaned up and do it manually there.

If you implement callback on the edges of a FSM rather than just the nodes, meaning chunks of code that are run on transition, then you can have a specific implementation of an edge from any of the Tree states to Idle allowing the idle state itself to be unaware of tree-specific details but allowing code to be reused for all of the possible ways into the idle state.

Another option is to use a hierarchical FSMs. You could have one "parent" state that is the Tree state or Idle or Combat or whatnot, and then a number of sub-states for Tree including Approaching, Cutting, etc. Now the variables are only stored in the Tree state so they are cleared/discarded when switching from Tree to Idle. The substates should have easy access to their parent's shared data.

You can make a base Targeting state class/definition that Tree/Combat/etc derives from which can then allow some common code and even sub-states to be shared between tree cutting, combat, whatever since your targeting is likely going to be common.

share|improve this answer
    
Great advice. Really helps a lot. I understand your idea about implementing edge callbacks, but I'm not sure how you'd be able to reuse code that way. Could you elaborate on that? Also, you are insinuating that I should store state attributes on the state instances themselves. I thought that was bad practice (compared to storing it on the game entity object), have I misunderstood something? –  Rasmus Rønn Nielsen Aug 6 '13 at 7:07
    
There's no such thing as bad practice, only designs that don't work well for a particular solution. That said, you could store them on the object and use on OnExit in a particular parent state to clean them up if you want, whatever works best for you. So far as your other question, just focus on a data-driven design and it should fall out of that. –  Sean Middleditch Aug 6 '13 at 16:39
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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