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.