Sign in to follow this  

GameState as a game's conciousness

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

Last night I had a moment of inspiration which will either sound like utter nonsense to experienced folks or be on a right path. So I'm putting it out for review. Note that this is a purely conceptual design so far, I'm making the topic before I begin working on proper design to see if its feasible, or common sense . . . or nonsense. [i]For a summery skip the next block.[/i]

System is the root class, it has a structure composed of containers such as vectors called [b]GameState[/b].
System runs the game loop.
First 'windows messages' is checked and inputs are passed to the class [b]InputClass[/b]
[b]System [/b]runs [b]frame[/b]() in which:
[b]InputUpdat[/b]e() is called passing [b]GameState[/b] into [b]InputClass[/b]
[b]InputClass[/b] has the current frames input messages which it uses to update [b]GameState[/b]
[b]InputUpdate [/b]returns the updated [b]GameState[/b]
[b]GameLogicClass[/b] is called with [b]GameLogicUpdate([/b]) which takes [b]GameState[/b]
[b]GameLogicClass[/b] does two things: it breaks down [b]GameState[/b] to [b]AiGameState[/b] and does none entity processes with [b]GameState[/b]
[b]GameLogicClass[/b] calls [b]AiUpdate[/b]() passing [b]AiGameState[/b] to [b]AiClass[/b]
[b]AiClass[/b] breaks down [b]AiGameState[/b] to [b]EntityGameState[/b] calling [b]EntityUpdate[/b]() to pass [b]EntityGameState[/b] where there are multiple entities and thus multiple [b]EntityGameStates[/b] ([b]JoesGameState, JanesGameState[/b])
Each entity process its own [b]AiGameState[/b] subset and returns it, the returned subsets then update the superset [b]AiGameState [/b]
[b]AiGameState [/b]then updates [b]GameState [/b]inside [b]GameLogicClass [/b]after [b]AiUpdate [/b]returns it
[b]GameLogicClass [/b]returns to [b]System [/b]with an update representing the computers choices and other updates like adding to a construction timer
[b]GraphicsLogicClass [/b]then does its thing with [b]GameState[/b], particle calculations ect.
[b]FinalUpdateClass[/b] messes some more with [b]GameState [/b](placeholder class, UI ect would go here)
[b]GraphicsClass [/b]finally gets [b]GameState [/b]and renders it when it returns the game loop restarts with updated [b]GameState[/b]
To save, [b]System[/b] calls a function that writes [b]GameState[/b] to a file and before game loop begins at runtime the user can load it or start new.


My thinking behind this is the [b]GameState [/b]is like the consciousness of the game all of the classes are mental faculties. Entities get subsets of [b]GameSate[/b] because they shouldn't know everything in the game.
Also as classes breakdown [b]GameState [/b]the resulting structure is faster to update. When all of the subsets in a class are updated they can all be used to update the superset in one go. Each minor function does not have to deal with the whole [b]GameState[/b]. By using a master [b]GameState [/b]to pass to core functions I never have to worry about any class calling another except for system, everything is an independent module depending only on [b]GameSate[/b], and only affecting [b]GameState[/b]. To add physics for example I just write the class and pass it [b]GameState[/b].

Comments, suggestions, criticisms, additions are greatly appreciated. A design philosophy is what I'm after and I'm hoping Ive hit it on the head with this. If I haven't Id really benefit from knowing now while the summer semester is young.

Share this post


Link to post
Share on other sites
There is no need to provide additional encapsulation over a game state, and in fact doing so short-sightedly will likely cause need for changes down the road.

Beyond that, I agree with the ideas you have in a vague sense; but I think you're over-complicating your interface.

Here is what I usually do for my "GameMode" class (generally the same concept):

[code]
/**
@class GameMode
@brief
Encapsulates all game-implementation specific things, and allows for vast changes in
how the game might be played or how game logic might be performed between various
states, without requiring a bunch of conditionals etc.
**/
class GameMode
{
public:
/**
@fn Update
@brief
Handles player input, game logic and physics, and prepares for the next frame.
@param elapsedtime
Time in milliseconds between this frame and the last frame.
@param next
Next gamemode to be run. "this" to continue with this mode, "NULL" to quit.
@return true if the caller is responsible for freeing the gamemode.
**/
virtual bool Update(uint64_t elapsedtime, GameMode*& next) = 0;
/**
@fn Draw
@brief
Does nothing but draw the game.
@param elapsedtime
Time in milliseconds between this frame and the last frame.
@param context
The rendering context for this game -- Direct3DDevice9, GL context, SDL_Renderer, w.e you're using here.
**/
virtual void Draw(uint64_t elapsedtime, RenderContext& context) = 0;
};

class GM_TitleScreen: public GameMode
{
/* implement the gamemode here */
};

...
int main(int argc, char** argv)
{
// get a rendering context
RenderContext context = SetupRendering();
// get the time of starting the game
uint64_t lasttime = GetTimeMS();
// create the title/loading screen
GameMode* game = new GM_TitleScreen(...);
// loop as long as we have a game state
while(game)
{
// calculate elapsed time
uint64_t now = GetTimeMS();
uint64_t elapsedtime = now - lasttime;
GameMode* next = game;

// draw the game
game->Draw(elapsedtime, context);

// update the game
bool freegame = game->Update(elapsedtime, next);
// change gamemode as requested by Update
if(freegame)
{
delete game;
}
game = next;
}
Quit(context);

return 0;
}
[/code]

It's a method I learned a few years ago and it's so simple and flexible that I still use it today. You'll see it occasionally in open-source games in one form or another, too.

Share this post


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