Jump to content
  • Advertisement
Sign in to follow this  

Game State Management

This topic is 2248 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Recently I've been pondering what the best implementation of game states(or really a game state manager) would be for a game developed in C++. I mention C++ specifically due to the fact it adds the options of OOP and pointers into the mix of possibilities for design, I was curious what other people's opinions are on the topic.

Really I just kinda sat down and pondered, "What does a game state manager have to do?" I came up with the few following points:

  • Redirect program flow from the game loop, either by branching into switches or using a function pointer or some other method.
  • Encapsulate the different things that need to be loaded or updated in a subset of the program into "game states" how these objects are updated can vary as well.
  • Provide a way to control which states are loaded/unloaded and be able to swap between them with relative ease/efficiency.


    Given those few guidelines I was wondering what opinions are on different aspects of traditional game state management. Is using a singleton game state manager the most effective way to control? Is a stack the best way to control game states? There is of course good points to using a stack such as: an efficienct way to track which states are loaded and to unload them as they pop, a simple way to designate an "active" state, at the top of the stack, without having to jump to an "active" state in an array each iteration of the game loop. There are negatives too though, for one a function pointer is usually what you need to reroute the "flow" of the program to the top state, a stack also can present problems in situations where you may want to jump from one state to another, not neccesarily in a hierarchy.

    My idea thus far was to have states as a class inheriting from a base, a game state manager would be used with a pointer to the current state to redirect program flow. An interesting idea I heard before was to use the stack as an "efficient" container for states, in that you could have two forms of access: one is to simply push and pop and states will unload when popped and load when pushed, thus giving simplicity to hierarchial menus. The second point was also having a sort of "jump to" method, which would clear the stack and push a new single state ontop, this lets you have the efficiency of keeping states loaded where need be but also being able to "dump" the stack when you need to move to an unconventional state.

    /textwall

Share this post


Link to post
Share on other sites
Advertisement
I usually use state classes that use the run and return successor pattern. Basically every function called on a state object returns a smart pointer to the state that the system should be in now. This can be a pointer to the original state. This allows inter-relation of states to happen without whatever is holding the state to explicitly know what's going on. For example, a state can go to a pause mode by constructing a pause state object and passing itself to the pause state constructor and returning a smart pointer to that pause state. When the appropriate event occurs, the pause state can return the original state object to transfer control back. This avoids needing anything like a singleton. One down side is that the constant assignment of smart pointers isn't free, but I've yet to run into a situation where it's been a bottleneck.

Share this post


Link to post
Share on other sites

I usually use state classes that use the run and return successor pattern. Basically every function called on a state object returns a smart pointer to the state that the system should be in now. This can be a pointer to the original state. This allows inter-relation of states to happen without whatever is holding the state to explicitly know what's going on. For example, a state can go to a pause mode by constructing a pause state object and passing itself to the pause state constructor and returning a smart pointer to that pause state. When the appropriate event occurs, the pause state can return the original state object to transfer control back. This avoids needing anything like a singleton. One down side is that the constant assignment of smart pointers isn't free, but I've yet to run into a situation where it's been a bottleneck.

That's an interesting way of doing it actually, hadn't thought along that path before. I like the fact you're using smart pointers so you can essentially destroy any objects you no longer need simply by removing reference to them. I'm a little iffy about the constant assignment of smart pointers though, seems like when you call basically any little task, especially in the game loop, you'd be doing a lot of almost "goto" jumps between states and even simply to the start of the same state(creating a new pointer along the way) unless I'm understanding your method incorrectly. Essentially even if I was just sitting in a "playing" state I might be creating and passing a smart pointer to the same memory time and time again.

I guess simplicity is the merit to that though since you could literally branch the program any which way you want.

Share this post


Link to post
Share on other sites
Right, probably at least 99.9% of calls just return the original pointer, which sounds like a lot of overhead. But then each call only happens a few times per frame. It doesn't really add up to that much in total.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!