1
\$\begingroup\$

I am currently struggling really bad to make the game states management. Before we dig into the problem, I must point out that I do know about state machines, I do have both implemented (states and state machine) and they look SIMILAR to this, or you can also see my real outdated implementation from my github. Alright, my questions are:

  1. Do states usually operate state machines? Eg.: when the LoadingState finishes (based on the 'update' method) loading something, it tells the state machine to pop the stack (which would pop the LoadingState) and to push a new state, such as PlayingState OR should the LoadingState only notify the state machine and the state machine itself will be responsible of knowing whats the next state based on the state that has requested a pop? Knowing which state has requested a pop (pop, push or whatever) is kind of difficult because it needs some advanced C++11 stuff, which requires a lot of 'not-easy-to-understand' code and validations (asserts), unless we use an enumeration inside each state and do a simple switch (again, more typing).

  2. Should the state machine be opperated/accessed (pointer/static functions) by any component (class, system, manager...) of the game? Eg.: the main player has moved into a map teleport and it triggered a map load, since it should be teleported to a new map. Should the Map class notify the state machine to push the MapTransitionState into the stack, through a static (it doesnt really make any sense to have a pointer to the state machine in the map class) public function?

Thanks a lot!

\$\endgroup\$
2
  • \$\begingroup\$ "again, more typing" This is the worst reason to avoid doing a design made to resolve the task at hand. Use the right tool for the task, if it requires more complex stuff, then do it. There is no reason to jeopardize an important part of a design just to stave typing. \$\endgroup\$
    – Vaillancourt
    Commented Feb 24, 2016 at 14:55
  • \$\begingroup\$ First of all, thanks for your input. I'm aware that "more typing" shouldnt be an excuse to adopt a certain design. In this particular case, however, I chose the enumeration option, which is in my opinion, the best, simplest, easiest to maintain and even offers portability between older compilers. All I wanted, in this case, is to keep track of the type of an object (typeid from C++11). \$\endgroup\$ Commented Feb 24, 2016 at 18:01

1 Answer 1

1
\$\begingroup\$

The state machine is used to change its behaviour depending on the current state active, it:

  1. Contain states
  2. Execute the behaviour of the current state
  3. Contain the behaviours and values shared by every states it contains

Some implementations of state machines do not know the states they contain. This makes hard for them to know to which state transition. So the 'decision' to change state, and to which state, is made by the state itself. This makes the code more localized: State A only knows about State B and C, while State C only knows about State D. It's easier to look at the code and see right away what's going on from that state.

And the "Tteleporter" class should not know about the concept of "state machine". Your play state should know about the Teleporter, and detect a 'collision' between the Teleporter and the Player, and then do what's appropriate.

\$\endgroup\$
3
  • \$\begingroup\$ "the 'decision' to change state, and to which state, is made by the state itself. This makes the code more localized: State A only knows about State B and C, while State C only knows about State D. It's easier to look at the code and see right away what's going on from that state." Thats exactly what I have done. I'm glad I chose the right design then. Did you see my githib, btw? \$\endgroup\$ Commented Feb 24, 2016 at 18:12
  • \$\begingroup\$ "Teleporter class shouldnt know about the state machine. Play state should know about the Teleporter" Thats my current approach. Teleports should trigger events and notify the play state (observer pattern). Is it what people usually do/sounds correct? PS: accidently hit Enter and couldnt edit my comment just in time. \$\endgroup\$ Commented Feb 24, 2016 at 18:18
  • 1
    \$\begingroup\$ @YvesHenri I did not look at your git repo, and I will not. "Is it what people usually do?" There is no way to know. It sounds correct to me. I generally think about the design, implement it, work with it, and change/improve it if I notice there could be improvements. Each project is unique, and there is no one unique way to achieve the desired effect. \$\endgroup\$
    – Vaillancourt
    Commented Feb 24, 2016 at 18:23

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .