Take the 2-minute tour ×
Game Development Stack Exchange is a question and answer site for professional and independent game developers. It's 100% free, no registration required.

I'm controlling the main loop with Game States like in pseudo code below:

loop{
      if (Not Game.WaitingForUserInput){

          if (Game.Started){
              StartTurn();
          }

          if (Turn Started){
              DoSomething();
          }
}

This works fine, until the inner workings of a method like "StartTurn()" or "DoSomething()" requires waiting for user input.

Also, Assume that calling "DoSomething()" triggers an event that is listened to by more than one object. Each object that handles the event requires user input to finish handling the event. To illustrate:

DoSomething() ==> fires an event that is handled by 2 objects with methods that follow this pattern:

HandlingMethod()
{
    // some logic

    // Here we need to get a variable X that is determined through user input
    // like clicking a UI element. So, we need to wait (or simulate wait) until X is
    // determined.
}

This means when the first object starts handling the event, the 2nd object must wait until the first object has finished handling the event.

I tried tight loops inside these methods like:

...
while (X is unknown){
   // just loop and check X until user has clicked something
}
... X here will be known

However, this leads to the UI to hang and user will not be able to interact with the application.

By the way, I'm using a windows application (windows forms) for the UI.

share|improve this question
add comment

3 Answers

up vote 0 down vote accepted

This is a design decision with countless possible answers. In the end it's related to how many states your state machine has and what the transitions are.

If StartTurn() needs to wait for user input, one possibility is to split it like you already split your method into StartTurn() and DoSomething(). This is akin to adding a state to your state machine:

loop{
  if (Game.WaitingForUserInput) {
    WaitForInput();
  }
  else {
    switch (Game.State) {
      case Game.State.GameStarted:
        PrepareTurn(); break; /* Will set WaitingForUserInput to TRUE */
      case Game.State.TurnPrepared:
        StartTurn(); break;
      case Game.State.TurnStarted:
        DoSomething(); break;
      /* More cases */
    }
  }
}

You could also make StartTurn() not change the game state until the second time it is called. This is akin to adding a substate to your state machine.

share|improve this answer
    
Thanks. I'll apply this same idea of splitting methods to handling events also. If you have a better idea for the events situation I mentioned earlier please let me know. I can't believe that I spent a week to think of complex solutions. Really, thanks again. –  Saleh Al-Abbas Apr 14 '11 at 13:36
add comment

Coroutines are a beautiful thing. They are unfortunately not well supported in most languages.

A coroutine allows a function to yield its execution to its caller (silimar to return). The magic is that the function (coroutine) can be be restarted where it left off whereas a regular function must start from the top everytime. Coroutines are known for being able to transform complex IO (waiting for input) code into simple sequential steps.

In python coroutines are created by using the yield statement in a function. Python coroutines are limited in that the coroutine can only yield to its immediate caller.

Lua has great coroutine support. In lua you explicitly change a function into a coroutine. When the coroutine.yield method is called the function will return to the top most caller.

.NET has great coroutine support with its standard fiber library.

D has great coroutine support.

C/C++ have some implementations but they are arguably black magic.

So depending on the language you're using coroutines may be available. Personally, I love using lua for level scripting because of Lua's coroutine library.

share|improve this answer
add comment

Well, if you're writing WinForms, you could just turn your whole app event based and deal with input the way a normal windows app would: let your app idle waiting for updates, and just go through the motions of a turn until you're ready to idle again.

But I suspect, having a run loop and all, that what you're after is more of a traditional game loop for a turn based game like Civilization. In that case, you need to bear in mind that your logic is turn based, but your game actually isn't.

Here's an outline of what I would normally do:

main() {
  while( true ) {
    collectInput(); // deal with common code for filling in keyboard queues, determining mouse positions, etc.
    preBookKeeping(); // do any other work that needs constant ticks, like updating streaming/sound/physics/networking receives, etc.
    runLogic(); // see below
    postBookKeeping(); // again any stuff that needs ticking, but would want to take into account what happened in runLogic this frame, e.g. animation/particles/networking transmit, etc 
    drawEverything(); // any actual rendering actions you need to take
  } 
}

runLogic() {
    // this is where you actually have a statemachine
    switch ( state ) {
       case WaitingForInput:
         // look at the collected input and see if any of it is actionable
       case WaitingForOpponent:
         // look at the input and warn the player that they are doing stuff that isn't going to work right now e.g. a "It's not your turn!" notification.
         // otherwise, use input to do things that might be valid when it's not the player's turn, like pan around the map.
       case etc:
         // a real game would have a ton more actual states, including transition states, start/end/options screens, etc.
    }
}

The idea here is that runLogic() wouldn't actually block, it would just deal with input for the current time step.

Your transition from state to state would make the game appear to be turn based in that at the appropriate states it would appear to be waiting for the player to take action, but in reality your game loop ticks on carrying out animation and rendering duties.

You can hierarchically extend this to your objects: each object would get ticked to let it decide if it needs to take action based on the current state of the game. The trick is similarly to avoid blocking by having states that represent the object waiting for input. When you're in such a state, check the current input for the motivation you're looking for and just do nothing if it's not present, allowing the rest of the game to continue.

The same goes for messaging. Rather than delivering messages immediately between objects and blocking when you get to an object that cannot continue, what you want is to post all messages to a central postmaster, and then once a tick deliver them. Return results the same way, by posting a return message. In this manner, objects that expect a response will automatically be able to wait over any number of ticks where other objects are happily ticking away. You can decouple the frequency of this messaging from your display frame rate by just ticking the postmaster multiple times a frame.

A final note on optimization: it sounds like you'll have to do a lot of ticking and checking of every object just to do nothing, but once you have everything up and running, obvious optimizations should become self evident. For instance, rather than having one object list, split it into two: actively ticking objects that need to reconsider every tick, and dormant objects that won't need to do anything until a suitable message comes along to wake them up. You should find that very few things will really need to watch the world, and that the vast majority will just respond to messages to do their work.

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.