Main Loop Variations

Started by
12 comments, last by clabinsky 21 years, 3 months ago
Hi there. I have been reading through books and articles on this forum and I see an inconsistency when describing the game main loop. There are several descriptions and most of them will work, but I am curious on your take on this. For example, two similar versions are
  
while()
{
  IF THERE IS A MESSAGE
  {
    HANDLE THE MESSAGE
  }
  ELSE
  {
    DO CALCULATIONS AND OTHER STUFF
    RENDER ONE FRAME OF THE GAME
  }
}

while()
{
  IF THERE IS A MESSAGE
  {
    HANDLE THE MESSAGE
  }
 
  DO CALCULATIONS AND OTHER STUFF
  RENDER ONE FRAME OF THE GAME
 }
  
Now, the only difference between these two is the else statement. Does that really matter? Well, here is my take on this. I have no idea on how fast windows generates messages when for example moving the mouse. In the first case, all messages are handled before rendering a frame. In the second one, one message is handled for every frame rendered. Just by looking at the structure, I would think that the first solution might create a problem of changing the state of the game in one message while reversing this change in the next. If no rendering is made between the messages, things might happen behind the scene while the user gets no feedback to know of this. Using the second option might fill up the queue of messages but each change in input will be reflected on the screen. If the rendering process does not take too long this should be fine and I would suggest the second approach. See, I am thinking of using the second version having a mouse and keyboard object. For each event the appropriate object will be set which will take no time at all. Then, the current state will be handled and the input objects will be checked to see if they affect the state. Depending on the result, the rendering might be affected. Before I start implementing a new solution in my game I feel I need to know what your take is on this. So go ahead..
Why make it simple when you can make it sooo nice and complicated?
Advertisement
Actually, I do

  while(true){  while(there are events)    process events;    do the game stuff}  


This is my favorite, and I don''t see any problems with it (except that new messages will appear so fast that the main stuff isn''t executed, but that is unlikely.

"Reality is merely an illusion, albeit a very persistent one." (Albert Einstein)
My Homepage
---Just trying to be helpful.Sebastian Beschkehttp://randomz.heim.at/
well, if you only deal with one message at a time and the user is constantly moving the mouse (as with many games) then the responsiveness of the game will drop remarkedly. say the user moves the mouse really quickly (spins around in an FPS) and windows suddenly throws 10 MW_MOUSEMOVE messages at you. If you only process them one pre frame then the game will take 10 frames to catch up with something that the user did instantly (well, close enough to anyway). While I can't really think of any other messages that would be sent that quicly (WM_TIMER perhaps, depending on the time interval and if your using WindowProc to handle it and not a callback) this alone would be a major problem.

[edit]
Actually, you'd have problems even if your WindowProc wasn't handling the timers, since I'd imagine that the windows standard WindowProc that you have to call at the end would dispatch to the callback so you would still only be doing one timer tick each frame anyway.
[/edit]


Joanus D'Mentia
---------------
The three phases of me...
The twit, the tool and the lonely fool.

[edited by - joanusdmentia on December 26, 2002 3:43:21 PM]
"Voilà! In view, a humble vaudevillian veteran, cast vicariously as both victim and villain by the vicissitudes of Fate. This visage, no mere veneer of vanity, is a vestige of the vox populi, now vacant, vanished. However, this valorous visitation of a bygone vexation stands vivified, and has vowed to vanquish these venal and virulent vermin vanguarding vice and vouchsafing the violently vicious and voracious violation of volition. The only verdict is vengeance; a vendetta held as a votive, not in vain, for the value and veracity of such shall one day vindicate the vigilant and the virtuous. Verily, this vichyssoise of verbiage veers most verbose, so let me simply add that it's my very good honor to meet you and you may call me V.".....V
Got ya, randomZ

joanusdmentia, this is what I was afraid of. In my case it is only the WM_MOUSEMOVE that causes the problem.

The interesting part is then: when the mouse moves over hotspots which should be highlighted, the won''t be, if the movement is fast. If you''re painting on the screen there might be spots which will be missed. I know, I know, can''g get everything but it would be intersesting to know anyone using the second method.

I think the problem of a clogged queue seems worse than missing spots here and there.


Why make it simple when you can make it sooo nice and complicated?
quote:Original post by clabinsky
Got ya, randomZ

when the mouse moves over hotspots which should be highlighted, the won''t be, if the movement is fast. If you''re painting on the screen there might be spots which will be missed.


Hmm. Right. Well, I''m kinda new to this
Well, you have "Missing Spots" on one hand, and "Low Responsiveness" on the other. A compromise would probably be, in the painter example, to make the "Painting" part of the event handling. But in most games, this is impossible, since you need to render a frame at a time.
I still prefer my method, since, if a user moves the mouse really fast over a hotspot, he probably isn''t interested in it anyways. I think the responsiveness thing is more important.
And as I said, if it is important to not miss a spot, make "noticing that (e.g.)the mouse was there" (I''m lacking a better term) part of the event handling.

Probably I''m also wrong with this, I''m not too experienced with this.

"Reality is merely an illusion, albeit a very persistent one." (Albert Einstein)
My Homepage
---Just trying to be helpful.Sebastian Beschkehttp://randomz.heim.at/
quote:A compromise would probably be, in the painter example, to make the "Painting" part of the event handling. But in most games, this is impossible, since you need to render a frame at a time.


Might be an idea. However, it seems to create a very special case which would slow down the major part of the game to accomplish one task. As you imply, I''d avoid it.

quote:I still prefer my method, since, if a user moves the mouse really fast over a hotspot, he probably isn''t interested in it anyways.


Agree. In most cases I would not care because of what you say. Intersting to this point is if you move your mouse fast, back and forth, over a button with a tooltip, the tooltip wont display. Might not be a good comparison but anyway.

Then since you do it that way, do you store the change to be implemented when the other stuff executes or do you call game functions to change state of objects in each event?

Why make it simple when you can make it sooo nice and complicated?
I use the first method. And as for the debate of "hotspots" : did you realy experienced this? I mean let''s think for a second:
an average game is runing at lets say 30 FPS , right? so in a single second the screen is refreshed 30 times. And I didn''t made so far a game that would run slower than 65 FPS (but I only made 2 games so far ) . But let''s stick to the more general 30 FPS . So do you have any idea how fast must you move the mouse in order that the hotspot not to be acctivated meaning that the hotspot would have to be acctivated and deacctivated ( via messages ) in les than 33.33333 ms ??? If this would hapen then as RandomZ said the user is probably not interested in that spot.
MAD_Mask, you are probably right.

I am going to test it later in January.

One thing which would be of interest to know is if you guys are calling update functions from the event case or instead save the input change in an object or something. Then adjust the frame based on the last saved state of the mouse or keyboard?

I save the changes in mouse coordinates and keyboard in a separate object which can be queried by other objects.

How do you do that?
Why make it simple when you can make it sooo nice and complicated?
Well correct me if I''m wrong, but for games it is know to be slow to use windows messages to process your input, or anything for that matter.

That is why DirectInput and the like are used. Thus, they are process during frame calculation.
Programming is easy, thinking is hard.
quote:One thing which would be of interest to know is if you guys are calling update functions from the event case or instead save the input change in an object or something. Then adjust the frame based on the last saved state of the mouse or keyboard?

That''s what I do. In my loop the else statement remains. In the case when say for a FPS the player whips around quickly, a bunch of WM_MOUSEMOVE will be received by the ''mouse'' object and summed up. Then when there are no messages to process and the game code gets to run, it gets that ''summed up'' movement from the mouse object as if it were one WM_MOUSEMOVE message.
This kills the "Low Responsiveness" problem, but the "Missing spots" problem still remains. However I don''t consider that a problem: can you, the human, tell the difference between say 6 individual mousemoves:
(1,2) (2,1) (1,1) (-2,3) (0,4) (-1,1)
and one that adds to the sum of those six:
(1,12)
over a time of say 0.15 seconds? I can''t.

----------
http://www.zppz.com <- game dev stuff

This topic is closed to new replies.

Advertisement