6
\$\begingroup\$

I'm trying to figure out how best to manage state within my game screens - please bare with me though! At the moment I'm using a heavily modified version of the fantastic game state management example on the XNA site available here. This is working perfectly for my 'Screens' - 'IntroScreen' with some shiny logos, 'TitleScreen' and a 'MenuScreen' stacked on top for the title and menu, 'PlayScreen' for the actual gameplay, etc. Each screen has the a bunch of sprites, and an 'Update' and 'Draw', managed by a 'ScreenManager'.

In addition to the above, and as suggested as an answer to my other question here, most screens have a 'GameProcessQueue' class full of 'GameProcess'es which lets me do just about anything (animations, youbetcha!), in any order, in sequence or parallel.

Why mention all this? When I talk about managing game state I'm thinking more for complex scenarios within a 'Screen'. 'TitleScreen', 'MenuScreen' and the like are all relatively simple. 'Play Screen' less so. How do people manage the different 'states' within the screen (or whatever you call it) that 'does' gameplay? (for me, the 'PlayScreen')

I've thought about the following:

  1. Enum of different states in the Screen, 'activeState' enum-type variable, switching on the enum in the Screen Update() loop to determine what Screen Update 'sub'-function is called. I can see this getting hairy pretty fast though as screens get more complex and with the 'PlayScreen' becoming a behemoth mega-class.

  2. 'State' class with Update loop - a Screen can have any number of 'States', 1+ of which are 'active'. Screen update loop calls update on all active states. States themselves know which screen they belong to, and may even belong to a 'StateManager' which handles transitioning from one state to the next. Once a state is over it's removed from the ScreenState list. The Screen doesn't need a bunch of GameProcessQueues, each State has its own.

  3. Abstract Screen further to be more flexible - I can see the similarities between what I've got (game 'Screens' handled by a ScreenManager) and what I want (states within a screen, and a mechanism to manage them). However at the moment I see 'Screens' as high level and very distinct ('PlayScreen' with baddies != 'MenuScreen' with 4 words and event handlers), where as my proposed 'States' are more intrinsically tied to a specific screen with complex requirements. I think.

This is for a turn-based board game, so it's easier to define things as a discrete series of steps (IntroAnimation -> P1Turn -> P2Turn -> P1Turn ... -> GameOver -> .... Obviously with an open-world RPG things are very different, but any advice in this scenario is appreciated.

If I'm just going OOP-crazy please say so. Similarly I'm concious there's a huge amount on this site re: state management. But as my first 'serious' game after a couple of false starts I'd like to get this right, and would rather be harassed and modded down than never ask :)

\$\endgroup\$
0

2 Answers 2

5
\$\begingroup\$

Your reasoning is sound, and pretty much all I can give here is opinion. Any of the alternatives you gave seem reasonable, although my recommendation would be to keep it simple at first, and stick with the enum, unless you really expect a lot of different gameplay states from the start.

But you are right, what you have already implemented for screens is indeed just a finite state machine (in this case using a stack based implementation) whose states are screens. Naturally, a finite machine is not limited to managing screens, and can just as well be used for managing all kinds of game state. This includes, for example, what you refer to as being gameplay states within a screen, or more specific concepts such as artificial intelligence states of a game entity.

You could abstract the screen manager into a general finite state machine class, but screens have separate update and draw methods in order to match the framework, while a state in a FSM will typically only have an update method. There's also a few other features here and there that might useful only to a screen manager. Then again, you could have a generic finite state machine base class, and make the screen manager inherit from it to provide the additional features. But your screen manager has a stack based implementation, and a regular finite state machine usually doesn't need it.

So instead of trying to cover all the bases at this point with the most flexible design possible, I'd say to just keep it simple, and use the enum. Chances are, the amount of gameplay states you'll need will never grow large enough for it to be impractical. Unlike the action chaining method I spoke about in the other question, which I find to be extremely useful, my experience so far with this particular problem of higher level gameplay state management, is that over engineering it doesn't really pay out that much.

\$\endgroup\$
2
  • \$\begingroup\$ Thanks again David, sure I owe you a beer by now! I'll stick with a switched enum for now (not a complex game at all), as anything beyond seems like overkill for this project. \$\endgroup\$ Commented Apr 10, 2012 at 12:26
  • \$\begingroup\$ I actually ended up using a GenericProcess from your previous answer with an Action that simply changes the state at the end of a queue. This triggers the switch to move on to the next state. Works great! \$\endgroup\$ Commented Apr 13, 2012 at 12:59
1
\$\begingroup\$

In similar situation I decided to go with enums. To be honest I actually didn't considered any other options though :). The main concern, I suppose is the 'PlayScreen' becoming a behemoth mega-class part. But most of the time, it should be. Very big, maybe ugly but pretty straightforward which is a synonym to "easy to understand and debug". This comes from experience of studying open-source games code (small to medium, 'indie' size).

\$\endgroup\$
0

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .