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

mike3

  • Rogueliker
  • ***
  • Posts: 125
  • Karma: +0/-0
    • View Profile
    • Email
Re: "Game state"-based game loop.
« Reply #30 on: June 29, 2013, 09:16:09 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.

Yes, that's what I was thinking of, but I then run into the problem of resuming the logic routine at the right point depending on what was selected in the confirmation prompt. What to do about that?

mike3

  • Rogueliker
  • ***
  • Posts: 125
  • Karma: +0/-0
    • View Profile
    • Email
Re: "Game state"-based game loop.
« Reply #31 on: July 01, 2013, 11:39:11 AM »
Would having some kind of variable in the game state objects telling where we left off and resuming at that point be good (since the confirmation prompts occur as part of a command, this could be done in the command-processing stage of the logic)?

Trystan

  • Rogueliker
  • ***
  • Posts: 164
  • Karma: +0/-0
    • View Profile
    • my blog
Re: "Game state"-based game loop.
« Reply #32 on: July 10, 2013, 05:22:58 PM »
You could use variables to track what you need to do next. Another - I think cleaner - possibility is passing in what to do next. So in my game Pugnacious Wizards 2, there's a TargetDirectionScreen that takes a callback that get's called with the direction the user chose. I'm not sure what language you're using but most modern ones allow something like that.

Here's the game-state object where the user picks a direction:
  https://github.com/trystan/PugnaciousWizards2/blob/master/src/screens/TargetDirectionScreen.as

And here's one case where it's used. The "cast" function is passed in as a callback:
  https://github.com/trystan/PugnaciousWizards2/blob/master/src/spells/MagicMissile.as#L24

The MagicMissile spell itself also takes a callback so it can end the current turn after being cast without having a direct dependency on the core update logic.

That's one way of handling these multi-step processes.

mike3

  • Rogueliker
  • ***
  • Posts: 125
  • Karma: +0/-0
    • View Profile
    • Email
Re: "Game state"-based game loop.
« Reply #33 on: July 10, 2013, 09:20:28 PM »
You could use variables to track what you need to do next. Another - I think cleaner - possibility is passing in what to do next. So in my game Pugnacious Wizards 2, there's a TargetDirectionScreen that takes a callback that get's called with the direction the user chose. I'm not sure what language you're using but most modern ones allow something like that.

Here's the game-state object where the user picks a direction:
  https://github.com/trystan/PugnaciousWizards2/blob/master/src/screens/TargetDirectionScreen.as

And here's one case where it's used. The "cast" function is passed in as a callback:
  https://github.com/trystan/PugnaciousWizards2/blob/master/src/spells/MagicMissile.as#L24

The MagicMissile spell itself also takes a callback so it can end the current turn after being cast without having a direct dependency on the core update logic.

That's one way of handling these multi-step processes.

But how does this reconcile with the loop as specified? I notice this program isn't set up with explicitly-labeled "input, logic, render" methods in the states. In that system, transitions between states would only happen at the end of an input-logic-render cycle. So if we were to use the callback approach, how would it work there? It's due to that fact that the input-logic-render cycle has to end before transitions, as opposed to being able to enter new states "immediately", that leads to the need for some kind of control variable. How would you handle it in that situation with a callback? Suppose the handling of a command requires a menu, and then after the menu, the logic for the turn must be processed. So the menu state would take a callback to perform the command logic, which it then goes to upon completion of the menu, but if we now have a callback to perform the turn logic, we're still "in the menu state", as it's still on the stack and we have called the turn logic from the command logic which in turn was called from inside the menu state. We want to go back to the main state to handle the logic for the turn. How do you handle this?
« Last Edit: July 10, 2013, 09:22:52 PM by mike3 »

Trystan

  • Rogueliker
  • ***
  • Posts: 164
  • Karma: +0/-0
    • View Profile
    • my blog
Re: "Game state"-based game loop.
« Reply #34 on: July 10, 2013, 11:32:46 PM »
But how does this reconcile with the loop as specified? I notice this program isn't set up with explicitly-labeled "input, logic, render" methods in the states. In that system, transitions between states would only happen at the end of an input-logic-render cycle. So if we were to use the callback approach, how would it work there? It's due to that fact that the input-logic-render cycle has to end before transitions, as opposed to being able to enter new states "immediately", that leads to the need for some kind of control variable. How would you handle it in that situation with a callback? Suppose the handling of a command requires a menu, and then after the menu, the logic for the turn must be processed. So the menu state would take a callback to perform the command logic, which it then goes to upon completion of the menu, but if we now have a callback to perform the turn logic, we're still "in the menu state", as it's still on the stack and we have called the turn logic from the command logic which in turn was called from inside the menu state. We want to go back to the main state to handle the logic for the turn. How do you handle this?

I don't know mike3. All this talk is just speculation. Why don't you sit down and actually code it and see how it turns out? Don't make a full-blown roguelike - just make the minimum needed to validate some of these ideas. Try one where you use a bunch of variables to track what you were doing before transitioning to a new state. Try one where you use callbacks to say what to do next (it's called continuation passing style and is very common in javascript frameworks among other places). Try one where you have objects that specifically control the program flow and move all the transitioning logic there. Try one where states can 'freeze' their internal state and 'thaw' it when control returns to them. Try one where the states are implemented as statemachines and each main-loop moves it to the next state with a final 'update world' state.

A stack of loosely-coupled states that can be chained together with callbacks is the approach I've been trying lately and it works well for me. If you're unable to do that, or if it doesn't work for you, then try something else.

Anvilfolk

  • Rogueliker
  • ***
  • Posts: 374
  • Karma: +0/-0
    • View Profile
Re: "Game state"-based game loop.
« Reply #35 on: July 11, 2013, 01:46:33 AM »
I'm going to go ahead and recommend you try Game Coding Complete 4th Ed. again. I've been interested in these issues for a while, and had a system working already, but after reading it decided for an almost complete rewrite, which I'm doing at the moment.

I've already written about it elsewhere, but their system is pretty flexible, and you really only need to read a few of the first chapters to get the gist of how to organise an engine in a very flexible way. It includes the events discussion that has been part of this thread, as well as organisation of the main loop in a generic and, again, flexible way, composition instead of inheritance, and GUIs and stuff in there as well.

There's so much stuff around that at some point you're just going to have to make a decision and live with it. Eventually perhaps do a rewrite, refactor, or whatever you want to call it. Perhaps just a new iteration of the engine :)
"Get it hot! Hit it harder!!!"
 - The tutor warcry

One of They Who Are Too Busy