Author Topic: "Game state"-based game loop.  (Read 37897 times)

mike3

  • Rogueliker
  • ***
  • Posts: 125
  • Karma: +0/-0
    • View Profile
    • Email
Re: "Game state"-based game loop.
« Reply #15 on: May 29, 2013, 04:20:44 AM »
How does this address the problems with menus mentioned -- namely, when the game state changes back from the menu mode, how do we avoid getting input again for that one round of the loop where we do the logic for the turn?

loom_weaver

  • Newcomer
  • Posts: 23
  • Karma: +0/-0
    • View Profile
Re: "Game state"-based game loop.
« Reply #16 on: May 29, 2013, 04:33:08 AM »
You are always gathering input.  However, when a significant input occurs, you need to act on it and resolve it.  For example, if someone dismisses a menu then your UI state must be updated as such so that it is only handled once.  In UI libraries this is commonly done by detecting the key press and dispatching a single KEY_PRESSED event.  When your code handles that event, the core game state is updated and the menu is dismissed.

When you have a continually running UI input/render loop, you no longer necessarily do logic every single pass.  Instead you might have a timer or something that invokes the logic update only once per second.

To learn more about UI states, I would study your favourite UI library to see how it does it.  For example, if you're using Java then you can study awt/Swing.

mike3

  • Rogueliker
  • ***
  • Posts: 125
  • Karma: +0/-0
    • View Profile
    • Email
Re: "Game state"-based game loop.
« Reply #17 on: May 29, 2013, 05:02:57 AM »
You are always gathering input.  However, when a significant input occurs, you need to act on it and resolve it.  For example, if someone dismisses a menu then your UI state must be updated as such so that it is only handled once.  In UI libraries this is commonly done by detecting the key press and dispatching a single KEY_PRESSED event.  When your code handles that event, the core game state is updated and the menu is dismissed.

When you have a continually running UI input/render loop, you no longer necessarily do logic every single pass.  Instead you might have a timer or something that invokes the logic update only once per second.

To learn more about UI states, I would study your favourite UI library to see how it does it.  For example, if you're using Java then you can study awt/Swing.

Why would the logic update by timer, as opposed to by turn?
« Last Edit: May 29, 2013, 06:55:46 AM by mike3 »

joeclark77

  • Rogueliker
  • ***
  • Posts: 90
  • Karma: +0/-0
    • View Profile
Re: "Game state"-based game loop.
« Reply #18 on: June 05, 2013, 06:18:41 PM »
2. A finite state machine (where you only have one state at a time) does, not quite fit games. Instead I would have something more like a state stack. You push new states onto the stack and pop them off when they are done. You could go with something as simple as calling render() for everything in the stack or you could get a little bit more clever and only call render() down the stack until you reach a state to renders the entire screen. Similar rules can be applied to the other common functions.

I've been doing something like that with my Python roguelike projects.
The pyglet library's window object allows you to stack event handlers, and you can end them with "return False" to pass the handler down the stack or "return True" to stop it.  So for example I have a main game mode which catches "ESC" and opens a menu mode.  The menu mode is "on top" of the main game. 

Rendering routines go bottom up, so the game is drawn and then the menu is superimposed on it, blocking part of it from view.  Event handlers go in reverse.  The menu mode, for example, catches "ESC" and closes the menu, but sends "return True" so that the "ESC" handler for the main game mode does not re-open the menu.

mike3

  • Rogueliker
  • ***
  • Posts: 125
  • Karma: +0/-0
    • View Profile
    • Email
Re: "Game state"-based game loop.
« Reply #19 on: June 06, 2013, 11:28:42 AM »
I've got another question about this "game state object"-based game loop: where should the data (like the map) the logic functions use go? I'd usually have it in the game object itself, if the logic function was a member of the game object, but here the logic function is a member of the game state object.

naughty

  • Rogueliker
  • ***
  • Posts: 59
  • Karma: +0/-0
    • View Profile
Re: "Game state"-based game loop.
« Reply #20 on: June 07, 2013, 10:23:17 AM »
I've got another question about this "game state object"-based game loop: where should the data (like the map) the logic functions use go? I'd usually have it in the game object itself, if the logic function was a member of the game object, but here the logic function is a member of the game state object.

If you have a hierarchical state machine (stack of state effectively) I'd put the map the the root Game state. An example state hierarchy for a roguelike could look something like:

Code: [Select]
MainMenu
    EnterName
    ChooseRace
    ChooseClass
Game
    Main
    Inventory
EndGame
HiScores

mike3

  • Rogueliker
  • ***
  • Posts: 125
  • Karma: +0/-0
    • View Profile
    • Email
Re: "Game state"-based game loop.
« Reply #21 on: June 07, 2013, 11:59:23 PM »
I've got another question about this "game state object"-based game loop: where should the data (like the map) the logic functions use go? I'd usually have it in the game object itself, if the logic function was a member of the game object, but here the logic function is a member of the game state object.

If you have a hierarchical state machine (stack of state effectively) I'd put the map the the root Game state. An example state hierarchy for a roguelike could look something like:

Code: [Select]
MainMenu
    EnterName
    ChooseRace
    ChooseClass
Game
    Main
    Inventory
EndGame
HiScores

So then the Main and Inventory game sub-state objects would operate on the data in the Game object, right?

naughty

  • Rogueliker
  • ***
  • Posts: 59
  • Karma: +0/-0
    • View Profile
Re: "Game state"-based game loop.
« Reply #22 on: June 10, 2013, 08:22:21 AM »
...
So then the Main and Inventory game sub-state objects would operate on the data in the Game object, right?


Yep, because those states always exist while a Game state exists it's ok for them to access data that Game is the owner of.

Trystan

  • Rogueliker
  • ***
  • Posts: 164
  • Karma: +0/-0
    • View Profile
    • my blog
Re: "Game state"-based game loop.
« Reply #23 on: June 10, 2013, 08:44:13 PM »
I also use a stack of state objects (I call them Screens in my code) but instead of allowing the states to grab each other's stuff, the shared data gets passed in to the sub-state objects.

That means the code ends up looking like this:
Code: [Select]
enterScreen(new ThrowItemScreen(world, player));

And each state object (such as ThrowItemScreen or PlayScreen) is completely isolated from other state objects. So the map is referenced by the PlayScreen, but also the ThrowItemScreen, ExamineScreen, and probably a few others.

naughty

  • Rogueliker
  • ***
  • Posts: 59
  • Karma: +0/-0
    • View Profile
Re: "Game state"-based game loop.
« Reply #24 on: June 11, 2013, 08:42:00 AM »
I also use a stack of state objects (I call them Screens in my code) but instead of allowing the states to grab each other's stuff, the shared data gets passed in to the sub-state objects.

That means the code ends up looking like this:
Code: [Select]
enterScreen(new ThrowItemScreen(world, player));

And each state object (such as ThrowItemScreen or PlayScreen) is completely isolated from other state objects. So the map is referenced by the PlayScreen, but also the ThrowItemScreen, ExamineScreen, and probably a few others.

This is definitely the tidiest way to do it but it depends on the state library or pattern you're using. Some of them don't allow arguments on state constructors.

mike3

  • Rogueliker
  • ***
  • Posts: 125
  • Karma: +0/-0
    • View Profile
    • Email
Re: "Game state"-based game loop.
« Reply #25 on: June 27, 2013, 08:31:44 AM »
I've got another question about this "game state object"-based game loop: where should the data (like the map) the logic functions use go? I'd usually have it in the game object itself, if the logic function was a member of the game object, but here the logic function is a member of the game state object.

If you have a hierarchical state machine (stack of state effectively) I'd put the map the the root Game state. An example state hierarchy for a roguelike could look something like:

Code: [Select]
MainMenu
    EnterName
    ChooseRace
    ChooseClass
Game
    Main
    Inventory
EndGame
HiScores

I just recently made a system with states and "sub-states" similar to this. However, I've hit a new snag: Consider the "inventory" state. The title of the inventory window may vary depending on what command is given to access it, like drop, for example. How should this be communicated? It also needs this in order to know what action to take after finishing with the window, like the just-mentioned drop.

naughty

  • Rogueliker
  • ***
  • Posts: 59
  • Karma: +0/-0
    • View Profile
Re: "Game state"-based game loop.
« Reply #26 on: June 27, 2013, 10:50:24 AM »
...
I just recently made a system with states and "sub-states" similar to this. However, I've hit a new snag: Consider the "inventory" state. The title of the inventory window may vary depending on what command is given to access it, like drop, for example. How should this be communicated? It also needs this in order to know what action to take after finishing with the window, like the just-mentioned drop.

Normally I organise it so that my states have arguments when you change to them. So I would pass the title and action on selection into that. It can be tricky to arrange it though depending on the language.

Trystan

  • Rogueliker
  • ***
  • Posts: 164
  • Karma: +0/-0
    • View Profile
    • my blog
Re: "Game state"-based game loop.
« Reply #27 on: June 27, 2013, 04:56:34 PM »
So I would pass the title and action on selection into that. It can be tricky to arrange it though depending on the language.

Parameterizing things like the title and the action is a good idea and keeps things simple. Another alternative is to create subclasses or substates for each variation. One for Drop, one for Quaff, etc.

mike3

  • Rogueliker
  • ***
  • Posts: 125
  • Karma: +0/-0
    • View Profile
    • Email
Re: "Game state"-based game loop.
« Reply #28 on: June 28, 2013, 03:03:22 AM »
Thanks for the answer.

Now I have another question. Suppose we have the player performing an action which takes multiple turns. During the monster actions for one of the turns, a monster attacks the player. We want to put a confirmation to continue or abort the action right there. But that requires switching out of the logic for that loop cycle while we go into the "confirmation prompt" state, and then back to resume the logic at that point. Or is there some other way of doing it (like making each cycle of the input-logic-render loop be at a finer scale than "one turn"?)?

Trystan

  • Rogueliker
  • ***
  • Posts: 164
  • Karma: +0/-0
    • View Profile
    • my blog
Re: "Game state"-based game loop.
« Reply #29 on: June 29, 2013, 05:34:57 PM »
Or is there some other way of doing it (like making each cycle of the input-logic-render loop be at a finer scale than "one turn"?)?

There's a lot of ways it could be done, but if you're already using different states, then I'd start with using a new "confirmation state". If it becomes a bother to use then try different things. Relying on the same way to do things (like with states) will keep your code much cleaner and easier to understand and modify. If you start doing the same thing a bunch of different ways then your codebase can quickly become a bunch of hacks and workarounds and conflicting ideas.