Questions about state driven games

Started by
11 comments, last by Norman Barrows 10 years, 7 months ago

Questions about state driven games:

by "state driven" i mean something like a pong clone with states like "titlescreen", "mainmenu", and "rungame".

IE one loop that displays output and processes input based on the current "game state".

while that might be all fine and good for pong, what happens when you get dozens or hundreds of states?

state driven seems to take the hierarchical call structure of a game and "flatten it out" into a bunch of "states" at the same level.

IE:

void rungame

while ! quitgame

renderall

process_input

updateall

void runprog

// do main menu

// if select new game

{

initgame

rungame

endgame

}

// if select load game

{

initgame

loadgame

rungame

endgame

}

void main

initprog

titlescreen

runprog

endprog

becomes states like:

uninitialized

titlescreen

mainmenu

load game dialog

rungame

which means you'd have a state for the in-game menu, and each stats screen, and so on..... correct?

Norm Barrows

Rockland Software Productions

"Building PC games since 1989"

rocklandsoftware.net

PLAY CAVEMAN NOW!

http://rocklandsoftware.net/beta.php

Advertisement

Why do they need to be flattened on the same "level"?

Who says gamestates can't have children?

And why can't you run more than one gamestate at once?

Why can't gamestates have their own state machine as well?

And, uh, why would you even have an "uninitialized" state? blink.png

I still think states should be kept as horizontal as possible.
For me it's easier to understand when the priority between states is dictated by their position on a stack rather than a hierarchical relationship. "Only the top-most state is executed, period". The rest are waiting for their turn.

// if select new game
{
initgame
rungame
endgame
}
// if select load game
{
initgame
loadgame
rungame
endgame
}


It could be the following when under a different paradigm.

500px-Data_stack.svg.png

[hr]


// Starting the game.
Program
    -> Sponsor_Screen.


// Entering the menu. The Sponsor_Screen state popped itself and pushed a Menu state on the stack.
// This pair of operations can be called a 'change'.
Program
    -> Menu.


// Changing options and displaying an option screen, a state pushed on top of Menu.
// It's on top of the Menu state because you want this screen to fall back to the menu gracefully.
Program
    -> Menu
        -> Options_Screen.


// Starting the game. The menu state 'changed' to a Start_Game state.
Program
    -> Start_Game.

[hr]

Further reading: http://gamedevgeek.com/tutorials/managing-game-states-in-c/


And why can you run more than one gamestate at once?

QFE. A lot of people forget about this case when they try and design a state/screen system for their game.

What happens when you want to overlay your options menu on the game, but keep the game itself visible and running in the background?

Tristam MacDonald. Ex-BigTech Software Engineer. Future farmer. [https://trist.am]

+1 for SotL and swiftcoder. Modal UI is poor design in many cases, so supporting multiple UI elements active concurrently is usually necessary for nontrivial games. What if Call of Duty made you press a button to pause the game and pull up your Current Health and Ammo menu?

Wielder of the Sacred Wands
[Work - ArenaNet] [Epoch Language] [Scribblings]


Why do they need to be flattened on the same "level"?
Who says gamestates can't have children?

game states with sub states. ok, that makes more sense.


And why can't you run more than one gamestate at once?

don't quite follow you there.... you mean an overall state which is a combo of two or more sub states?


And, uh, why would you even have an "uninitialized" state?

Don't ask me man.... It was in an example i saw! <g>

Norm Barrows

Rockland Software Productions

"Building PC games since 1989"

rocklandsoftware.net

PLAY CAVEMAN NOW!

http://rocklandsoftware.net/beta.php

ok, now for the 64 dollar question:

except for things like HUD_on as a sub-state of render scene,

isn't a lot of the "control flow" of states already implicit in the call hierarchy of traditional code?

i do have places where i use something like a state variable to determine whether to render an indoor, outdoor, or underground scene, or whether or not to display a stats overlay on top of the normal game screen (HUD_on). but most things are handled automatically by call hierarchy.

Norm Barrows

Rockland Software Productions

"Building PC games since 1989"

rocklandsoftware.net

PLAY CAVEMAN NOW!

http://rocklandsoftware.net/beta.php

Why do they need to be flattened on the same "level"?
Who says gamestates can't have children?


game states with sub states. ok, that makes more sense.

And why can't you run more than one gamestate at once?


don't quite follow you there.... you mean an overall state which is a combo of two or more sub states?


Another way to look at this is not to contain the state in the main loop at all. In my little tutorials project my entire state is controlled via the html/css+lua UI system (well, not completely there yet, working on it) which means for instance my splash screen is:


<rml>
 <head>
  <link type="text/css" href="Splash.rcss"/>
  <script>
   function RunSplashScreen()
    RegisterUpdate( 'SplashCountdown', 0,
     coroutine.wrap(
      function()
       ... Snip .... Basically three states:  FadeIn, Hold, FadeOut
       ... just written in a coroutine.
       UnregisterUpdate( 'SplashCountdown', 0 )
      end ) ) end
   </script>
 </head>
 <body onload="RunSplashScreen()"
       onunload="LoadDocument( 'UI/Menu.rml' ):Show( Document.Focused )"
  >
   <img id="Splash" src="Images/SplashScreen.png" align="middle" />
  </body>
</rml>
So, when I kick off the game, I load a startup script, which loads this. This does the splash screen, then finishes and loads the next item which is the menu. So you can think of those items as your rough 'big state' blocks. I can add/remove arbitrary items to be updated from the game loop once a frame or at certain intervals, so I can load in dialogs (both modal and nonmodal) etc, grab data from the engine to update with, or other various things even open up other OS windows for debug purposes whatever and do it all with a fairly nice little Lua script without futzing about with the main loop code.

So, getting to your description, I could have all of those different states encapsulated in these scripts and the game engine itself remains oblivious to such things and simply acts as a flow control system. Now, getting to object systems and such obviously gets a bit more complicated but that's another story. smile.png

What happens when you want to overlay your options menu on the game, but keep the game itself visible and running in the background?

What if the game and the options screen both listen for the same keyboard input? If they are concurrent states, you would have behavior such as moving the cursor on the options screen and having the player character move in the background. You would have to make the game state be aware that there's an options screen state active, and so it should 'pause' or 'ignore' its input listener.

With a stack (and with an effort to keep states horizontal, equally important), the options screen can still update the animations, collisions etc. and render the background game (which is the same call to Engine.Update() and Engine.Render() etc. that the game state was performing), while taking input and only performing actions related to options, since its own input listener is the only active.

In other words, with a stack you can have an overlayed options screen with an active game running in the background.

Or you could implement a notion of focus like every GUI on earth has done for the past 40 years :-P

Wielder of the Sacred Wands
[Work - ArenaNet] [Epoch Language] [Scribblings]

This topic is closed to new replies.

Advertisement