Basic Order of Things

Ok… I’ve taken a look at most of the demos and tutorials. I have a couple of questions about the order of things.



There are a number of things that need to get done in every game/application.



In no specific order:

  • render scene(s)
  • handle input (mouse, keyboard, etc) and queue up changes to scene for next render pass
  • logic, and queue up changes to scene for next render pass



    I’m wondering what the best method of making these things work together is. I’ve taken a look at your different ‘Game’ type classes… Base, FixedLogic, FixedFramerate and so on.



    Let’s see if my understanding is correct.



    In the main game loop we want to do all of the above:



    Handling input we would want to do every loop, no matter what, as quickly and as often as we can.



    We want to render (at least) when there are sceen changes and/or when we want to render anyhow (when it’s time for another render pass, either based on a fixed framerate, or ASAP).



    Logic in the same way needs to be handled. Depending on the application this may only happen on user input, or based on timers (every X number of fractions of time).



    So, I was thinking that I’d like to render as quickly as possible, but put a limit on the framerate to say max 100 fps.



    I’d like to handle input as quickly as possible no matter the frame rate.

    I’d like to do other logic at every 0.1 seconds.



    So I’d have a game loop that would look something like this:



    (pseudo code)



while( not done) {

   update input handlers;

   if( we're at least 0.1 seconds from last logic update)
      update logic;

   if( we're at least 0.01 seconds from last frame)
      render;

}



Am I at all close in understanding things?

Also, while playing around with the Timer class I noticed that there really only seems to be one Timer available at a time. Based on the underlying renderer. Is this correct?

Finally, is there any advantage to threading out the logic update? If my logic is going to take longer than the time till the next frame update or longer than then time until the next user input I don't want to limit the rest of the system from doing it's thing.

What about threading off logic associated with input handlers for the same reason?


-- thanks in advance for advice and comments.[/code]
Am I at all close in understanding things?


Yes, you are correct. And your own custom game loop is correct. You would implement your own AbstractGame subclass setting the start method to be set to your frame type.

while( not done) {

   update input handlers;

   if( we're at least 0.1 seconds from last logic update)
      update logic;

   if( we're at least 0.01 seconds from last frame)
      render;

}



Also, while playing around with the Timer class I noticed that there really only seems to be one Timer available at a time. Based on the underlying renderer. Is this correct?


Correct, currently Timer is an singleton. The reason for this: timer should be updated every frame (every iteration of the loop). So, the values of multiple timers would be the same at any given time. (Basically it's a timer of the computer clock). I'm taking a guess that you were wanting a timer for each system (update, render, etc). The recommended way to handle this would be to have counters for update and render. Something like:


while( not done ) {
  update timer;
  renderTimer += timer.getTimePerFrame();
  updateTimer += timer.getTimePerFrame();

  update input handlers;

  if( updateTimer >= 0.1 ) {
    reset updateTimer;
    update logic;
  }

  if( renderTimer >= 0.01 ) {
    reset renderTimer;
    render;
  }
}



If you see a different need for multiple timers, by all means let us know.

Finally, is there any advantage to threading out the logic update? If my logic is going to take longer than the time till the next frame update or longer than then time until the next user input I don't want to limit the rest of the system from doing it's thing.


I've never done anything with threading logic. There is a test in the source (TestMilestone2) that is multithreaded, that loads new geometry (boxes) in a seperate thread.

I don't see any problems by handling logic in a seperate thread, as long as all logic is in the same thread. But I haven't tried it out.

What about threading off logic associated with input handlers for the same reason?


Again, I don't foresee a problem doing this, but I don't think you would gain much of an advantage with this. Input and display is tightly coupled, I press forward in frame 1, I want the scene to reflect that movement in frame 2. You might get some disconnect if you allow input in a seperate thread. That's known to cause motion sickness too.

Thanks Mojo… You the Monkey… ah, Man.

:stuck_out_tongue:



Yes, I’ve worked out the Timer just as you have described. I don’t see any reason to need anything more.



I was thrown a little by the Timer.update being called in the update method for the fixed logic example.

I’d advise that you avoid using multithreading. As far as I’m concerned, resolving the many problems involved in attempting to synchronize logic and rendering is not worth the effort. The sheer complexity of the locking system required to avoid race/deadlock conditions for even a simple game is rather daunting, especially considering the negligible gain. Logic, in general, is far faster compute than performing rendering. If it takes too long, you can always break it up over several frames. (Keep in mind this is pure opinion. YMMV, as always!)



A thought on handling input as fast as possible: why bother? If you’re not updating the logic, the input has absolutely no effect on the game state. It strikes me that a better solution is simply to query the current input state every logic update and handle it then.



For your game loop: it sounds like a cross between a fixed logic and a fixed framerate game. It would be a minor modification to FixedLogicrateGame to do exactly what you want. An if statement on the render() in addition to a timer would suffice. As mojo said, extend AbstractGame, “borrow” the code out of FixedLogicrateGame, and you’re set to go! :slight_smile:

The example that I’m thinking about would be an RTS or a turn based game. Here, every X number of time clicks you want the state of the underlying data to change and then get reflected for the next render, or logic happens on a ‘next turn’ click (where threading it off makes the most sense). However, the majority of the time the user interface is used only to change the perspective, or what the user may be looking at, maybe to change screens or zoom in/out of a map. Basically the user inteface and drawing routines are just data views. User interface really doesn’t change logic or game state very often. Unlike in a FPS or RPG.

I would still argue that a single-threaded model is superior in most cases. Though, perhaps if you’re offloading certain heavy tasks - such as AI or pathfinding - that can be safely decoupled from the core logic the pros might outweigh the cons. Hmm… this could be especially useful for a turn based game where the computer player could contemplate its next move while the player issues orders. Maybe the ideal model is where core game logic (such as position updates, combat calculations, …) and rendering operate in the primary thread while tertiary operations like AI, pathfinding, territory calculations, etc. are in a secondary thread?



As for game logic verus data views, I now understand what you mean by handling input as fast as possible. In your scenario, it makes complete sense. Perhaps even two separate methods - updateUI() / updateGame() - would be appropriate.

Thanks Eric! I’ve now done some experiments with this and I’ve really had to think hard how to do this the right way. I appreciate your comments and will take them to heart.

I’m glad I could help. It’s what I’m here for! :slight_smile: If you have any more questions, don’t hesitate to ask. (Or even IM me, for that matter. I think the relevant contact info is somewhere in the Developers - General forum.)