Main Game Loop

Blitz3D Forums/Blitz3D Programming/Main Game Loop

Buggy(Posted 2007) [#1]
Here's my main game loop:

While Not KeyDown(1)

   currentTime = Millisecs()

   ;prevents timePassed being too small
   If currentTime > lastTime + 10

      timePassed = currentTime - lastTime
      lastTime = currentTime
      
      Cls

      doEverything()
      drawEverything()

      Text 0, 0, timePassed

      Flip

   Endif

Wend


...or something like that.

Everything in my game is scaled against timePassed (it's a 2D game, so no tweening), so the movement should be pretty steady.

On average, the timePassed value flickers between 16 and 17 (milliseconds), but when there's a ton of stuff going on, rather than having timePassed go to 20~ish, it jumps straight to 32 - 34, which is exactly double the normal amount. Then, when the game calms down again, it goes right back to 16 and 17. The effect is very noticeable.

Is there something wrong with my code that's causing this? The reason I have the "If currentTime > lastTime + 10" is so that I can do things like "timePassed = timePassed / 4", which makes everything go slow-mo. If I didn't make sure that the difference was greater than 10, then on a fast computer, "timePassed = timePassed / 4" could make timePassed round down to zero, effectively stopping the game.

If that made any sense whatsoever, please help me.


GfK(Posted 2007) [#2]
Problem here lies in the Flip function I would think. It'll either wait for one vertical blank, or two vertical blanks, and so on. It can't wait for one-and-a-bit vertical blanks. Hence the jump in framerate.

Try changing it to Flip False so your code doesn't wait for a whole vertical blank before flipping.


Buggy(Posted 2007) [#3]
Yeah, I had

Vwait : Flip False

...but will my taking the Vwait out make it appear sloppy on some computers?


Sledge(Posted 2007) [#4]
The display will probably tear, yes -- but then you either wait for the vertical blank or you don't, and each has its own downside.

By the way, "Vwait: Flip False" will reportedly look dodgy on some machines. "Flip True" is more reliable I believe (and in any case why use two commands when one will suffice).


big10p(Posted 2007) [#5]
By the way, "Vwait: Flip False" will reportedly look dodgy on some machines. "Flip True" is more reliable I believe (and in any case why use two commands when one will suffice).
I think that's the other way around, TBH.

[edit]
from the manual for VWait:

Note that this command is different to the vertical blank waiting mechanism in Flip because Flip will cause the graphics card (as opposed to the CPU) to wait for the next vertical blank. The vertical blank can be disabled on some graphics cards, hence it is quite common to use "VWait : Flip False" to ensure consistent updates on all setups.




Gabriel(Posted 2007) [#6]
It may be in the docs, but it's wrong, or misleading at least. VWait and Flip False will look dodgy on some machines, and Flip True is more reliable, insomuch as it produces a more reliable visual appearance. Yes it can't detect a vertical blank if there aren't any, but fake-syncing to a non-existant vertical blank isn't very good either. It won't catch you up if you're rendering below your desired frame rate ( quite the opposite ) and it won't ensure a smooth, high quality visual appearance ( because it won't be smooth and it can't stop tearing. )

The only potential use of VWait and Flip False would be if you can't be bothered to write a proper tweening/delta time system to manage game timing properly, but as I said, you end up paying a high price for that, so it would be better to use a proper timing system. Particularly since we're talking B3D which does all the hard work for you when it comes to tweening. Now if you had to write your own, I could maybe understand, but Mark's Mario demo and several code archive entries do it all for you.


Buggy(Posted 2007) [#7]
...unless you're not using any 3D commands.


cyberyoyo(Posted 2007) [#8]
Normally using flip(true) or flip false shouldn't change anything since you'll catch up on this wait time the next time you catch millisecs.

IMO the problem is that you shouldn't check if elapsed time is >10, there is no reason to do that. I think that's what's causing the jerkyness.
Just process the loop, regardless of how small the time has passed.

I'm using a very similar method (except the I don't check if time is above a certain value) and I have no problems.


Buggy(Posted 2007) [#9]
1. I like to have that, so I can do cool things like slow-mo by using "timePassed = timePassed / 4."

2. How would this check make any problems? It shouldn't double the normal timePassed, since as long as it's greater than 10, it works fine.


Gabriel(Posted 2007) [#10]
...unless you're not using any 3D commands.

I thought it was obvious that the reference to tweening was more general, since you've already said you use delta-timing, and therefore you have no need to try to force syncing with a non-existant vertical blank.


Buggy(Posted 2007) [#11]
Oh. Ok then.