You start a game. You get a menu system. You move in and out of forms. Then you start the game. Now you're on the level select / campaign screen and things are moving around. Then you click go, you play a round of C&C or whatever and beat the level. You go back to the level select, and play another.
How do you typically go about structuring that stuff? Is there a single game loop that changes states based on what "screen" you're in? Or is there multiple game loops for each screen, and a master controller above them?
Lastly, how do you go about de-coupling and designing interfaces between those sections? Clearly, you don't want a hodge-podge mess of everything touching everything. Without good encapsulation, it would be a nightmare, so how do you go about architecting that?
For XNA, Microsoft had this package or something in which you define scenes. Each scene would be the screen on your post. You would have an active list, and you add remove scenes as needed, so the main menu would be a scene, the level select would be a scene, etc. I don't remember the details, but I think the class structure would have functions that the main loop could call when the scene needed to do something.
The way they handled it however, a scene could be transparent, so the top most scene would have focus, but other scenes could do updates. So the pause menu could be a scene, but the game could still animate stuff behind the pause menu.
Echoing this, I use a base Scene class, and all Scenes inherit this.
But I can only run one scene.
Then I have a SceneManager that is responsible for scene switching, and calling things like input, logic, and render() on the scene.
When a scene is done, it sends a message to the scene manager and on the next frame, the scene manager calls the scene end methods, cleanup is performed and the new scene is loaded.
The reason you don't want to kill the scene right away is because things will crash hard if you do.
Here is the full source of my scene manager. It does a little more than described but the idea is the same.
I'd probably do something similar to the above. Though the limit of only being able to run a single "scene" at once is a bit arbitrary though it saves a bit on work, and allows certain assumptions. I'd probably have an active "stack". So you could have the game running, but then call up the settings screen which would overlay the game, and not kill the game scene.
Or you can get fancier and have an actual scene graph, and have the game view just be a regular view in your graph.
I've seen the "state stack" model applied in some game remakes aroudn the web, but I can't say I'm a fan of it.
What jmsterx supplied is more along the lines fo how I was doing it, albeit I never managed to get through.
I've seen the "state stack" model applied in some game remakes aroudn the web, but I can't say I'm a fan of it.
And is that the fault of the underlying concept, or the implementation?
What I'm currently doing could technically work with multiple scenes in a stack.
Much like how it works in iPhone programming, I allow for a single 'RootViewController' and that thing could be a NavigationVC that keeps a stack of scenes in itself.
But at that point, might as well have that in the first place via SceneManager.
The way I did it works fine for me, but a scene graph sounds way cooler.
When I started my game project 4 years ago, I had no idea how to do scenes, and what you see there is what I came up with without researching anything. I might do it differently now if I started over though.
The design forced me to create a class called ClientShared where I keep data structures of the state of the lobby, chat etc while the player is in a game so that I don't have to send the client the full state of the lobby when they return.
And is that the fault of the underlying concept, or the implementation?
Ah more about the concept itself, implementaiton mileage may vary....and of cours eI am not experienced enuff to go over what's basicalli my impression.
Sure enough, I'd prefer for example a graph like you suggest which in my mind might handle better "scene concurrency" and "realtime passing by".
Of course if I think about games of the past (I am nostalgic
) , a scene is actually a "screen" and you VERY RARELY get more than one at a time, and maybe the most common case regardless of game "age" is that you basically have more often than not just two states: game and menu .
In such situations I guess popping and pushing states might make sense and be actually easy to implement and maintain, though when I see a moltitude of "screens" and behind the scenes the engine is preparing->pushing->showing->processing->popping states, I find it difficult to follow along the code, which in my mind makes maintenance (by a third party, which I usually am
) a pain.
I am aware that I haven't said anything really valuable on the technical point of view
I would normally use a single game loop combined with a state machine for keeping track of the different game states such as start menu, settings, play, pause, etc. If needed the state machine can have a stack to keep track of "previous" states and return to them. For the detailed state, I maintain the GUI state, the engine state and the game state separately in different structs or in the scripting engine.
I would normally use a single game loop combined with a state machine for keeping track of the different game states such as start menu, settings, play, pause, etc. If needed the state machine can have a stack to keep track of "previous" states and return to them.
IMO that's the same as a regular old scene state. Just a bit inside out.
State machine is not adequate if the same screen can be reached from several ways, ex:
- main menu -> options screen -> (back to) main menu
- (ingame) -> pause menu -> options screen -> (back to) pause menu
A lot of game menu systems can be nicely represented by stack:
main menu (user clicks new game, push "difficulty select" state)
difficulty select (user clicks "easy", pop 1 and push game state)
game (user presses ESC, push "pause" state)
pause (user selects options, push "options" state)
options (user presses esc : pop 1)
pause (user selects "end game" : push "confirm quit")
confirm quit (user selects OK: pop 2)
main menu
Yes, in such a case a stack is needed, combined with a state machine to keep track of the actual state and to forbid disallowed state transitions.
Which ends up being about the same as a scene stack
You can also have "in game" screens and "out game" screens.
In the first case the game is still running realtime. And the screen could be a translucent overlay. In the case of a out game screen you would want to pause the game logic. You couls still draw the game scène and draw the out game screen as a translucent overlay, still showing the paused game. Which looks cool