0

I have been attempting to make a game engine in C++ and have come across the dilemma of game state management. I have done a lot of research and found numerous ways of accomplishing from game engine with derived classes to using enums and I would like to know the most effective/efficient way of managing game states.

EDIT
I would like to know how other people implement their game state management, i.e. what you like the most and why you like it. Also, any tutorials/code examples that are generally about game state would also be much appreciated.

Kromster
  • 10,643
  • 4
  • 53
  • 67
I Phantasm I
  • 211
  • 1
  • 5
  • 9
  • 9
    There is a lot of questions like this: "What is the best way to..." The sad answer to these is that there is no best way, especially not with the little information given. It all depends on the constraints of the system. How do you need to work with it? Does a non programmer have to script it? How often will you update? The list goes on. – void May 24 '11 at 11:45
  • @The Communist Duck: it's not a duplicate the question you refered to is a possible solution to this one. – Ali1S232 May 24 '11 at 13:37
  • @Gajet They both seem to answer the same idea (how to manage game states), so I would say duplicate. – PrettyPrincessKitty FS May 24 '11 at 15:08
  • 2
    I think void hit the nail on the head. It's a hard question to answer in a generic way. – CiscoIPPhone May 24 '11 at 15:13
  • 1
    Just do whatever makes the most sense for you. If you're comfortable with enums and a switch, go for it. If you prefer a pattern of derived classes or function pointers, go for that. Don't worry about efficiency until you have a need to. At this point in the game it's all about expressiveness and malleability, and that's a somewhat subjective field. – Tetrad May 24 '11 at 15:40

3 Answers3

1

In most of my games (that are all small in scope) I have used an enum and a switch (in some cases an if..else if...) and it has always been sufficiently fast. I've never had more than a few states, which helps.

enum GameStates
{
    Running = 1,
    Menu = 2,
    Credits = 3
}

// update loop

switch(this.CurrentState)
{
    case GameStates.Running:
        UpdateRunning(gameTime);
        break;
    case GameStates.Menu:
        UpdateMenu(gameTime);
        break;
    case GameStates.Credits:
        UpdateCredits(gameTime);
        break;
    // add more states here
}

void UpdateRunning(GameTime gameTime)
{
    if(running == null) LoadRunning(); // 
    // perform the rest of your game logic
}

This gives you a few things worth mentioning:

  1. You can change state anywhere, as long as you have a pointer to your main class.
  2. You can load/unload as necessary to save memory (if your game is big it might be nice)
  3. You've kept your very simple and easy to follow. This is the single most important thing a programmer can do IMO.

(Please excuse my C#/XNA style this was copy/pasted and tweaked, shouldn't be to hard to adapt to C++)

Nate
  • 5,054
  • 2
  • 29
  • 46
  • 4
    if you define a class for each state, it'll help you organize your code and also let you to define OnEnter and OnExit events for every event, very useful for loading unloading unnecessory data. – Ali1S232 May 24 '11 at 19:10
  • Loading and unloading becomes a lot easier when you can just delete an instance of a class instead of having to manually free stuff. An OOP approach here would probably be cleaner and have the same (and more) benefits as your enum system here. –  Jul 27 '16 at 14:13
0

The most common approch to GameState algorithm is to have some game states and program can freely choose to run any one of them, this means there is a GameDirector which has a pointer to current running state, and in each update cycle it'll call 'currentState->run()`. in this approch GameDirector is a singleton and every one can access it, and also every one can change game state. also gameDirector is responsible for game's main loop.

class Director
{
private :
    RendererEngine* rEngine;
    SoundEngine* sEngine;
    PhysicsEngine* pEngine;
    GameState* gState;
    static Director* instance;
    Director()
    {
        rEngine = sEngine = pEngine = gState = NULL;
    }
public :
    static Director* GetDirector()
    {
        if (instance == NULL)
            instance = new Director;
        return instance;
    }

    RenderEngine* getRenderEngine() {return rEngine;};
    SoundEngine* getSoundEngine() {return sEngine;};
    PhysicsEngine* getPhysicsEngine() {return pEngine;};

    void runGame(GameState* pState)
    {
        return instace;
        rEngine = new RenderEngine;
        sEngine = new SoundEngine;
        pEngine = new PhysicsEngine;
        gState = pState;
        gState->onEnter();
        while (gState)
        {
            gState->onUpdate();
            gState->onDraw();
            rEngine->swapBuffers();
        }
    }

    void changeState(GameState* pState)
    {
        gState -> onEnd();
        gState = pState;
        if (gState)
            gState -> onEnter();
    }
}
Ali1S232
  • 8,687
  • 2
  • 40
  • 59
  • 9
    No, there is absolutely no need for a Singleton here. – DeadMG May 24 '11 at 14:00
  • 2
    @DeadMG No, there is absolutely no need for a Singleton anywhere (with a few extreme corner case exceptions) <- Fixed it for ya :) – PrettyPrincessKitty FS May 24 '11 at 15:09
  • 2
    @The Communist Duck: That's not a fix, it's saying something completely different. I specifically only stated anything about this particular use. – DeadMG May 24 '11 at 15:10
  • who said anything about a need for singleton, i just mention i've worked with 3 engines and in all of them director was defined as a singleton, and i think this approch is the easiest! sure you can change your data structure to avoid using singleton but as long as i can imagine, it will only make it harder to code using your gameEngine.

    and by the way i used esenthelEngine, GameBryo and cocos2d, and tried Unity3D, Shiva3D and UDK, in all of them there is a singleton which works as a director (i'm just guessing about Unity and Shiva since these ones are only scripting engines)

    – Ali1S232 May 24 '11 at 16:19
  • Singletons may make it easier, but they're still not a good design. They were designed for when >1 instance would break the code - such as a low level driver thingy. – PrettyPrincessKitty FS May 24 '11 at 16:30
  • Uhm, Singleton in UDK? Nonsense, a global pointer is not the same as a singleton! -1 – Maik Semder May 24 '11 at 17:39
  • 1
    Singletons are also hell if you want to do anything with threads. Or touch something by mistake when shutting down you game that will reinitialize all singletons again ;) It's just Bad Design (TM). – void May 24 '11 at 17:48
  • @The communist duck : your game does initialize Rendering system and it's only initialized once, it does initialize sound system and it's only initialized once, also there is physics engine, and many other things that only initialized once in every game, why is it a bad thing to have a singleton class which initialize them only once and give their pointer to anyone who needs it? – Ali1S232 May 24 '11 at 18:54
  • @Maik isn't singleton a global pointer within a class, and a functino to return it? and when i'm talking about unity, shiva3d, and udk i told you i'm jst guessing about them since there are some classes which only has one pointer to some only-once initialized objects so there has to be a singleton taking care of them (or at least each of them should be singletons) – Ali1S232 May 24 '11 at 18:56
  • and to all who think singletons are bad thing for game development : plz just name some game engines which doesn't have singletons for to manage gamestates, and not even only in gameengines for example those who tried somthing programming somthing with Qt know that also Qt decleres QCoreApplication as singleton which also works as director for Qt applications. – Ali1S232 May 24 '11 at 19:04
  • @void: agreed to the point you made out but Directors are usualy readonly singletons so they won't make any trouble even if access it from more than one thread in a same time. – Ali1S232 May 24 '11 at 19:05
  • @Gajet You're missing the point. Why force yourself to ONE instance when you only WANT one, not only NEED one? – PrettyPrincessKitty FS May 24 '11 at 19:34
  • 3
    @The Communist Duck: when i'm talking aboat game resources it's realy somthing that should only be initialized once ,eg. you'll only get error for trying to initialize DirectX with same configurations, or same window. and on the other hand there is no restriction to use singletons, you can use multiton whenever you feel there is need for more than one instance to a class, the main point is all the resources should be shared with all other classes in game and singleton(multiton) is an acceptable pattern to share your resources across your application. – Ali1S232 May 24 '11 at 20:25
  • @Gajet A multiton is not a singleton. – PrettyPrincessKitty FS May 24 '11 at 20:29
  • 1
    @The Communist Duck: the only diffrence is that it can handle more than one instance, so it won't force you to have only one instance of an object. it's same as singleton in every other aspect, and you asked "why should we force ourselve to only one instance?" – Ali1S232 May 24 '11 at 20:45
  • @Gajet It can handle more than one instance, so any issues related to having only one instance go out the window. – PrettyPrincessKitty FS May 24 '11 at 20:55
  • @the Communist duck: this time you are missing the point, what I need is an object to share resources between all my game classes it doesn't matter if it's a singleton, multiton or even a global variable or any other approch that you can think of, there only is a need to share all game resources to all game objects and it's also possible to have that shared object to manage states too! that's what i mean when i say there is a need for a director class! – Ali1S232 May 24 '11 at 20:59
  • @Gajet I think this has descended into some kind of chaos. I never questioned the need for an engine/director, I was simply making the point that a singleton is nearly never a good design choice. – PrettyPrincessKitty FS May 24 '11 at 21:06
  • @Gajet That's exactly the description of another well knwon Anti-Pattern, called the God Object – Maik Semder May 24 '11 at 21:08
  • @The Communist Duck: agreed on the point you made out but I think this is one of the rare use cases of singleton – Ali1S232 May 24 '11 at 21:15
  • @Maik Semder: i don't think my sample of director class is a type of GodObject (it sure knows alot but doesn't do any thing on his own), it only shares all the resources between all game objects. – Ali1S232 May 24 '11 at 21:30
  • 1
    @Gajet Nope, this is not one of them. http://stackoverflow.com/questions/228164/on-design-patterns-when-to-use-the-singleton Lists a few of them. Even if it's not a god object, it seems to be an amalgamated blob of all the subsystems. It may be to share the subsystems around, but why not have drawables have a reference to the render system? Why do they care about the game state, or the input manager, or the sound system? If it's simply so you don't have to pass parameters, it is not a valid reason. – PrettyPrincessKitty FS May 25 '11 at 09:41
0

Something I found interesting when looking around was the Advanced Ogre Framework which has a state management implementation. It is designed for the Ogre3D rendering engine but that part can be replaced pretty easily.

http://www.ogre3d.org/tikiwiki/Advanced%20Ogre%20Framework

Tim
  • 679
  • 5
  • 19