Jump to content
  • Advertisement

Archived

This topic is now archived and is closed to further replies.

STORM76

Handling States in Game Engines?

This topic is 5275 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

Hi there, I''m currently working on an OpenGL engine with a tetris-clone as a sample project. In order to make things the best way as possible I''ve included a FSM class with states representing each game state (i.e. MainMenuState, GameRunningState, and so on). My question now is, if this way handling states (meaning to create a State-instances for each game-state with methodes implemented for event-handling, drawing, animating and so on) is the way to go. The problem I see is that there will be too complicated dependencies between the engine-class (holding world-instances including the actual game-content) and the states, because each state needs to know about the world it handles, and so on. Has anyone made experiences in handling engine states? My goal is to have a robust engine which is able to handle the most complex game-behaviour :-) Thanks for advice! Greetings, STORM!

Share this post


Link to post
Share on other sites
Advertisement
quote:
Original post by STORM76
My question now is, if this way handling states (meaning to create a State-instances for each game-state with methodes implemented for event-handling, drawing, animating and so on) is the way to go. The problem I see is that there will be too complicated dependencies between the engine-class (holding world-instances including the actual game-content) and the states, because each state needs to know about the world it handles, and so on.


If you didn''t do it with states, what would be the difference? Your Loop would still have the same dependencies. I think the problem is not engine-state but more state-state dependencies. The engine is meant to be shared, and depended upon, you know The one major aspect of an engine that should not be mixed up, are client and server sides, if you have an engine designed like that.

That''s my thoughts anyway, but you have to make sure that every states are mutually exclusive, and be careful about the transitions.

If they have dependencies (like game/in-game menu, where the game is displayed and maybe updated behind the menu, the user settings, from menu to in-game, ...), it''s good to think about it and reduce them to a minimum.

Deriving two states that share something from a base class that handles the shared behaviours seems an obvious solution.

an FSM can reduce dependencies, compared to a bloated non-state code, for example, the main-menu state may not need the game stuff, only the GUI.

I think a good FSM helps a lot, keeping the code tidy and predictable. Believe me, I''m working on a game that had ONE game state machine (main menu, loading, game), none for managing entities, it''s 100,000s lines of code, and I''m doing the multiplayer stuff for it... shooting myself in the foot would be less painful.

Share this post


Link to post
Share on other sites
Yeah, have the game class containing the game data either global or pass it in to each gamestate in its constructor

Share this post


Link to post
Share on other sites
I always saw state handling like this: you Initialize() all your states when your program loads. They load all their resources, etc. When you switch from one state to another, you Deactivate() the old state, and Activate() the new one. Your program calls the state''s Run() handler every frame. When your program quits, all your states are Shutdown().

Perhaps you could pass game world information between states when they are activated and deactivated? Perhaps you could keep all game world information in a global CApp, so that all states can access the game world information without having to communicate with each other (but it''s still encapsulated within the CApp object)? In this latter situation, the CApp would hold on to all assets, and the states would call CApp functions to load models, textures, shaders, maps, sounds, music, etc. They would get pointers to the objects loaded that they could use (this would need to be used with a renderer and sound system). This is the way that engines like Quake III and Half-Life work. The engine part holds on to the assets, and the game code (stored in DLLs, in this case) calls engine functions to load assets. The engine returns a number, or a pointer in the guise of a 32-bit unsigned integer.

Went off on a bit of a tangent there, didn''t I? Anyway, I''m interested as to how other people manage states in their games. How do you do it? Do you just instantiate an object of each state class and add it to an std::vector, or something similar? Then each state could call a CApp (or global) function to change the state? Also, do you have state hierarchies? For example, the menu state could have a series of child states like front-end, options, credits, etc. which it manages.

Share this post


Link to post
Share on other sites
I don''t new/delete states myself. I''d rather create all the states I need at init, and activate the one I need, insanity said. I might need to get back to a previous state, in the status I left it before. But it varies on the application and your requirements, of course.

Share this post


Link to post
Share on other sites
quote:
Original post by iNsAn1tY
They would get pointers to the objects loaded that they could use (this would need to be used with a renderer and sound system). This is the way that engines like Quake III and Half-Life work. The engine part holds on to the assets, and the game code (stored in DLLs, in this case) calls engine functions to load assets.


That sounds good. Actually I''m thinking of a structure like this:

class IWorld {
public:
virtual void Initialize() = 0; // called once upon creation
virtual void Update(IEvent pEvent) = 0; // called every frame
virtual void Animate(float fDeltaTime) = 0; // called every frame
virtual void Draw() = 0; // called every frame
};

class CGameWorld : public IWorld {
public:
virtual void Initialize();
virtual void Update(IEvent pEvent);
virtual void Animate(float fDeltaTime);
virtual void Draw();
};

class CMainMenuWorld : public IWorld {
// ...
};

class CInGameMenuWorld : public IWorld {
// ...
};

class IState {
public
virtual void Enter() = 0;
virtual void Exit() = 0;
};

class CEngineState : public IState {
public:
virtual void Update(IEvent pEvent) {}
virtual void Animate(float fDeltaTime) {}
virtual void Draw() {}
};

class CWorldState : public CEngineState {
public:
CWorldState(IWorld* pWorld) : m_pWorld(pWorld);

IWorld* GetWorld() {return m_pWorld;}

private:
IWorld* m_pWorld
};

class CMainMenuState : public CWorldState {
private:
CFSM* m_pFSM; // holds all states of the main-menu and share the world with them
};

It''s just a quick idea and of course not thought out. What do you think of this class hierarchy?

STORM!

Share this post


Link to post
Share on other sites
Ze classic ''state design pattern''. There''s actually more articles on this than you would believe (don''t believe me, type ''state design pattern'' into google).

The way Im currently handling states in my engine is to have a abstract base class for all states (with functions such as Initialize(), Destroy(), Update() ). The ''Application'' class holds a pointer to the current state, and when it recieves a message that is state dependent, it calls a function on the current state.

You also need to provide a mechanism for state transitions in your ''Application'' class. Each state can also hold a pointer to the application class, so that the main application can be informed when a state has ''finished'', and is requesting a transition.

I''ve posted some pretty UML pictures (doxy-generated) from my current project. Even though development has more or less come to a complete halt, I feel the state machine is quite well developed.

Visual representation #1
Visual representation #2

Share this post


Link to post
Share on other sites
global variables are your friends, dont forget, or you could also just have a sloppy share member in your interface class. Just ignore this.

Share this post


Link to post
Share on other sites

  • Advertisement
×

Important Information

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

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!