proper game timing

BlitzMax Forums/BlitzMax Programming/proper game timing

flying willy(Posted 2004) [#1]
Hi,

What is the correct way to have game timing? I want the loop to both speed up and slow down to provide a stable movement rate without using delta timing, which is complex and hideous.

Something like:

While...

do logic until catch up
draw

wend...

And in addition to this, what HZ should we be using? Obviously I want it flicker free like their desktop settings. Will 0 suffice for this?


Warren(Posted 2004) [#2]
How is delta timing complex and hideous? The simplest case is: check how much time has passed since the frame started and if it's not enough, wait until that much has passed.

You're never going to "speed up" your loop, you can only slow down. Now, if you're taking more time than you have alloted for each frame, you're going to start dropping frames. At that point you're either going to have to reduce your desired frame rate or start optimizing your code. :P

Very few professional games do that though. They generally measure how much time has passed since the last frame and time step the world based on that. It's easier than you might think...


ImaginaryHuman(Posted 2004) [#3]
Using 0 as the depth will open in a window mode. If you simply don't specify the Hertz, the Graphics command will use the default it seems. Figuring out what that default it is a bit trickier and not something I've looked into.

By default, I found, the Flip command is synchronized to the verticle-blank of the display refresh, because when doing speed tests I was getting sudden jumps from say 60fps to 30fps to 20fps to 15 fps to 10fps, etc, ... using bglSetInterval(0) seems to remove that synchronization, but I did find (as it says in the docs I think?) that it isn't compatible with ALL graphics cards or OpenGL implementations. In fact on my G4 iMac with a Radeon 4MX it ignores the (0) version but setting it to bglSetInterval(1) has the same effect.

As for adjusting the timing, I would think you may need to keep track of not only the time between the last frame finishing and the current frame's position, but also the time of the previous frame before that - because let's say the previous frame overran - you don't want to go wasting 3/4 of a frame doing nothing so you can pick up immediately where it left off and hopefully finish before the verticle blank.

Anyway, tinker. :-)


flying willy(Posted 2004) [#4]
Thanks Angel :)

Warren - I quite liked the fixed timing of Blitz3D castle demo (albiet without tweening). I can't progress with delta timing.

Any other tips or code snippets, anyone?


flying willy(Posted 2004) [#5]
Sorry to bump this up - but I'm a little bit worried about the timing stuff in blitzmax. Now we have a refresh rate parameter, it's fairly important to get it right.

My game is being ported, hence it's rapid progress.


skidracer(Posted 2004) [#6]
If it's a scroller my gut feeling would be to force 60hz and run to a frame (literally so your characters running speed causes screen to scroll horizontally n pixels per frame where n is an integer amount) or alternatively just pick the highest refresh rate available on user's system for the screen resolution you are going with and run your game clock at something like 333Hz which is delivering very nice results with Anthony Flack's Cletus.

I'll look into the zero hz option, I think at the moment it picks first match in the list which we don't sort but could. I would also like to have the first entry in the list be the current desktop resolution so people have the option to default to that which is by far the most sensible for users with LCD displays.


jhague(Posted 2004) [#7]
A nice feature would be able to fake a specific hertz when running into windowed mode. It's simple and clean to force 60Hz when running fullscreen, but then it's harder to test when running in a window.


flying willy(Posted 2004) [#8]
Thanks skid - yes it's a scroller. I had problems with smoothness in windowed mode and had to specify the Hz of the desktop (in this case 85).

I think it's sensible to return the os preference hz when you query a resolution, and agree with your idea of first in list.


Jeroen(Posted 2004) [#9]
Junkster, that sounds like a good idea!
But, it's hard to translate to practicle use I guess.
Because: you need to compensate moving objects by multiplying with a factor (deltaTime) OR you need to tween movement (frame tweening).
What I mean that the following is not possible, because it will result in an actual choppier playback:

Graphics 800,600,32,75
SetVirtualFPS 60;
' so, we run at 75 Hertz, and set the GameClock to 60.


in the main game:

CompensateVirualFPS;
UpdateWorld
Renderworld
Flip


I guess something would be possible on the UpdateWorld front, but with 2D I don't know.


marksibly(Posted 2004) [#10]
Hi,

Flips are automatically synced to the hertz you specify, so in many cases you can ignore timing issues altogether - your game will just 'go' at the rate you tell it.

For trickier stuff, CreateTimer/WaitTimer are still in there.


AaronK(Posted 2004) [#11]
Couldn't you just keep a timer value that while under say 1.0 wouldn't do anything, but while it's over 1, loop through update, then subtract 1. Once finished updating, then draw. Crude but would work for most things unless you get into the situation where you're getting slower and slower and slower. Ways around this too, by just timing the draw stuff and letting the game get slower if logic is too much - this is the oldschool way and I did it this way in Loderunner

Pseudo Code

While playing game
timepassed = get time since last update
while timepassed > timetowait
timepassed = timepassed - timetowait
do game logic
wend
draw stuff
wend

Then you don't have to multiple or anything like that.

Aaron


flying willy(Posted 2004) [#12]
Mark please clarify : So I don't need to speed up my logic code for slower machines?

What about hz refresh rate/flicker? I don't understand this clearly...


marksibly(Posted 2004) [#13]

Mark please clarify : So I don't need to speed up my logic code for slower machines?



Yes you do - it only handles the case when the machine is 'fast enough'.


What about hz refresh rate/flicker? I don't understand this clearly...



It tries to use vsync if possible. If not, it disables vsync and uses an internal timing system. This makes for much smoother graphics than if the vsync is left enabled and 'fighting' the update rate. It also provides surprisingly flicker-free results for systems with no vsync.

See mod/brl.mod/glmax2d.mod/glmax2d.bmx for how it all works.


flying willy(Posted 2004) [#14]
Thanks Mark. I had mistakenly thought this affected the monitor refresh rate.


marksibly(Posted 2004) [#15]

Thanks Mark. I had mistakenly thought this affected the monitor refresh rate.



Well, it tries to. Here's the basic idea:

1) Set display mode with requested refresh rate.

2) Check refresh rate is actually in effect, as not all refresh rates are supported on all cards and, even more fun, my ATI driver LIES!

3) If so, simply use vsync for game timing - all is nice and smooth.

4) If not, disable vsync and use custom timing - all is still fairly smooth.


Jeroen(Posted 2004) [#16]
Mark,

Great! So you already took care of the infamous timing issue! It "adapts" and I love that :)


teamonkey(Posted 2004) [#17]
Oh, that's really nice! Top stuff!


flying willy(Posted 2004) [#18]
Jolly good.

But that also means we need a good way of looping through all the available display modes and looking for the one used by the os for that resolution.

For example in windows, I find my opengl games magically know I use 85hz for a specific res and they go with that.

Would this be at all possible? I would like the users to have the smoothest -and- safest experience.


Steve Elliott(Posted 2004) [#19]
Thanks Mark, it seems my refresh rate set to 60hz should run correctly on all systems - about to ask about this myself.

I just love how smooth my game is now running - it's like the good old days of the Amiga and ofcourse todays consoles - ie in sync with the refresh rate.


flying willy(Posted 2004) [#20]
there's a problem with this under windowed mode if your refresh rate is higher than 60. On pc's it usually is.

Remember, 60hz is bloody horrible to look at... flickering and so forth... usually 85hz is the smoothest.


Hotcakes(Posted 2004) [#21]
I read in a report somewhere a long time ago that the human eye updates at roughly 72 times per second (varies from person to person of course). So a refresh of much more than that is actually pointless overkill.


flying willy(Posted 2004) [#22]
This varies: I can see a little over 85. Please realise that you need the highest you can get for a given display mode.

switch your monitor to 75 from 85 and you will see it. Switch it to 60 and you will get a headache.

I'm betting nay-sayers and even Mark are using TFTs, where it doesn't matter.

CRT users HATE 60hz.


John Pickford(Posted 2004) [#23]
The human eye is not digital. It doesn't have a refresh rate. Some people can see flicker at 60hz some at 80hz.


BlitzSupport(Posted 2004) [#24]

The human eye is not digital.


Steve Austin's was.


Warren(Posted 2004) [#25]
Excellent point.

James: 1, Thread: 0


John Pickford(Posted 2004) [#26]
Actually it wasn't.


flying willy(Posted 2004) [#27]
What point? can we be realistic please?

Now back to refresh rate: I would like to be able to obtain the user's operating system preference of hz for a given resolution. I will likely make that the default with a "safe mode" which merely runs in a window on the desktop. Everyone wins.

My other issue was - what is the best way to code catch up stuff like in the castle demo code?

Thanks


LarsG(Posted 2004) [#28]
the lighttubes (pipe thingy with gas in it) flickers at 50/60 Hz.. I really don't think anyone is able to notice that.. :p


Warren(Posted 2004) [#29]
Yet, if I set my monitor to 60hz it drives me insane...


Steve Elliott(Posted 2004) [#30]
Yes it has to be fullscreen, and is not as smooth at higher refresh rates - probably because the frame rate has to be maintained constantly at a higher refresh.


flying willy(Posted 2004) [#31]
None of these problems were in Blitz3D.

You would set your res and it was 85hz or whatever the windows setting was.

Why isn't it the same here?


Diordna(Posted 2004) [#32]
Since it seems a little bit relevant, here is some code I came up with that, given a desired width and height, cycles through all display modes until it finds one that you want so it can set a correct refresh rate. If it doesn't find one, it picks the one with the best resolution and sets the origin viewport to be a rectangle in the center the size that you wanted it to be:

Function BetterGraphics(desiredWidth,desiredHeight)
	Global numGfxModes=CountGraphicsModes()-1
	Global depths[numGfxModes+1]
	Global hertzs[numGfxModes+1]
	Global widths[numGfxModes+1]
	Global heights[numGfxModes+1]
	Global width
	Global height
	Global depth
	Global hertz
	For a=0 To numGfxModes
		GetGraphicsMode(a,widths[a],heights[a],depths[a],hertzs[a])
	Next
	
	foundMode=False
	highestDepth=0
	bestMode=0
	For a=numGfxModes To 0 Step -1
		If widths[a]=desiredWidth And heights[a]=desiredHeight Then
			width=widths[a]
			height=heights[a]
			depth=depths[a]
			hertz=hertzs[a]
			foundMode=True
		End If
		If depths[a]>highestDepth Then
			If widths[a]>=desiredWidth And heights[a]>=desiredHeight Then
				bestMode=a
				highestDepth=depths[a]
			End If
		End If
	Next
	
	If foundMode=True Then
		Graphics width,height,depth,hertz
	Else
		GetGraphicsMode(bestMode,width,height,depth,hertz)
		Graphics width,height,depth,hertz
		SetViewport(0,0,800,600)
	End If
End Function



Steve Elliott(Posted 2004) [#33]
"None of these problems were in Blitz3D."

You must be joking. Basically you can use delta timing - never really liked it because the framerate will vary too much and your characters movement will jump - even when averaging out the frame times.

2nd option is render tweening which seems to work well in smoothng frame rates but I've heard problems with physics occuring. To be honest I've not written any 3d and so the 3d guys here will know about the problems with this system.

The 3rd option I've heard about and have been using is basically a simulation of syncing with the refresh rate. ie run logic at a high rate and scale to the user PC - and then flip when the screen refreshes.

This is an excellent system but the logic has to be run many times to be able to scale correctly.

I've always hated the fact of PC programming that every bodies PC runs at a different speed so we have to compensate and compromise our efficiency to overcome this problem.

Each console (and past computers) all ran at exactly the same speed and synced with a constant refresh rate (which Max now seems to give us). Running at a constant speed - rather than fluctuating has got to be smoother and really does give a much better result.

Any comments on what I've said Mark?


Jeroen(Posted 2004) [#34]
The human eye "reads" about 200 fps I read, but it's your brains that have to analyse the picture and that makes it hard to tell how much you "practically see".


flying willy(Posted 2004) [#35]
Damn right those *refresh rate* problems were not in Blitz3D. It would automatically take the best refresh rate for that resolution.

I'm not a newbie at B3D btw...


Hotcakes(Posted 2004) [#36]
switch your monitor to 75 from 85 and you will see it.

I don't see any differences between 75 and 120, or anything in between.

And I wouldn't mind betting some people say they can more out of talking themselves into believing it, like how some people used to tell me 'there really is a huge difference between 32 bit and 24bit colour on my desktop' before they understood what those 8 bits did =]

the lighttubes (pipe thingy with gas in it) flickers at 50/60 Hz.. I really don't think anyone is able to notice that.. :p

It might not be registered in the visuals by your brain per se, but if you stare at it long enough your eyes -will- be strained and you will start getting headaches and such. And it's probably bad for epileptics too.

You would set your res and it was 85hz or whatever the windows setting was.

No it wasn't. I had my refresh rate on 85 but my DX apps popped up in 75.

I'm not a newbie at B3D btw...

Not saying you're new, just misguided. Obviously you had one experience. I had another. I also had an experience of one guy's DX choosing 60 for him.


flying willy(Posted 2004) [#37]
So you're saying you'd rather not have improvements?


Hotcakes(Posted 2004) [#38]
I'm all for improvements, but I don't think we have any problems with the way BMax is doing things now. I had many problems with B3D. I much prefer to set my game to run at one speed and let Blitz sort out the choppiness for me (which from what I can tell is working fairly well). Seems to me setting the refresh rate in the Graphics command to 85 or so will get good results on most machines - people who can't view at 85 will have a lower refresh rate but the game will still run at 85 fps internally... I think 75 is a safe minimum for most machines, altho if you want ultra smoothness, just set it to like 150 or 300 or so and use the 'logic overkill' method. If the CPU can handle it you'll get beautiful updates no matter the refresh rate then.


flying willy(Posted 2004) [#39]
therefore I can just set it at 85 and it won't blow up their monitor?


Steve Elliott(Posted 2004) [#40]
Do you think we can get a definitive peice of BlitzMax code(for 2d and 3d) to allow our games to run at the same speed on all systems?

Preferably not delta timed and taking into consideration the aforementioned problems - including higher refresh rates means faster game.


Diordna(Posted 2004) [#41]
Fixed my code. Sort of.


BODYPRINT(Posted 2004) [#42]
if i set my game at 60 Hz fullscreen, my monitor stays at 85 Hz.

How do you change the screen Refresh Rate?


BODYPRINT(Posted 2004) [#43]
OK, I got it sussed.

I had the refresh rate override in my Graphics drivers set to 85. I disabled the override and it works now :-)


flying willy(Posted 2004) [#44]
I second what steve says.

I'm looking for THE piece of code which will work roughly like this...


While...

...special logic loop to catch up on old pcs

...your normal rendering goes here

wend!

Something like that! :)


Hotcakes(Posted 2004) [#45]
therefore I can just set it at 85 and it won't blow up their monitor?

As long as their drivers (at least for windows) don't lie. Any semi-modern monitor will display an 'out of sync' msg instead of blowing up these days though... =]


flying willy(Posted 2004) [#46]
Yes but it would be NICE if it chose the windows default hz for that resolution - which is WHAT BLITZ3D USUALLY DOES.


Hotcakes(Posted 2004) [#47]
Stop saying that! B3D let DX choose the default refresh rate, which in my experience was just about anything! =]


flying willy(Posted 2004) [#48]
Well all I know is that it was great. I want to do the same and would like to know if it's possible? :) pretty please? :)

60hz deeply annoys me and if it's the only safe setting then that doesn't amount to much does it?


BODYPRINT(Posted 2004) [#49]
It depends on your resolution as well skunk.

Any old monitor can do 640x480 @ 85Hz, but not 1024x768.
If your resolution is low, you could safely use a higher refresh rate.

What resolution is your game?


flying willy(Posted 2004) [#50]
Hi Phil,

640,480 to 1024,768. Any higher and you don't get much benefit under 2D with all the antialiased edges.

Here's a real world scenario: the user chooses high res in the menu (1024,768) but his monitor does 75hz at that resolution, and higher will show an out of range signal.

Isn't that going to be a problem that could be avoided by gathering what settings the os and driver has determined for each resolution?

I just don't trust using the parameter otherwise. And if I don't use it, the game will flicker.


ashmantle(Posted 2004) [#51]
why not simply make it an game option, so that people can choose their preferred refresh rate, and you just keep track of that selection.. much better to code for 60hz, 75, 85 and let the user choose between those..
if the user choose a setting he/she can't run, just reset the value after a set time, just like good old windows does :)


Steve Elliott(Posted 2004) [#52]
Setting the refresh rate is just one part.

1) Refresh rate - fixed rate - at what rate?
2) Refresh rate - variable - and compensation for a variable refresh rate (game runs too fast or slow).
3) compensation for slow computer's not able to maintain refresh rate.


skidracer(Posted 2004) [#53]
skunk, the docs need updating, if you set the hz value in Graphics to 0 (it defaults to 60) windows WILL pick the default refresh rate for that resolution.


Hotcakes(Posted 2004) [#54]
Hey, cool. So if the gfx parameter is left off it defaults to 60? I always thought it defaulted to 60 if it was 0. That's damn handy. Damn, DAMN handy!


flying willy(Posted 2004) [#55]
Just to clarify,

My game will switch to 85hz @ 1024x768 if I pass a parameter of 0 using that res?

This is because my windows setting has it as 85hz for that res...

What happens with linux and mac - also favourable I assume?

I think if this is the case, I can relax...


Paul "Taiphoz"(Posted 2005) [#56]
I think its going to be good to see what timeing solutions will come out over the next few weeks.

I was and still am a big fan of render tweening, am I right in saying that we cant do it in Max ?


Takuan(Posted 2005) [#57]
Hi, its a little confusing for me.

If i have a game set to a certain refresh rate, flip will work at these rate and the game logic is at same speed on every machine with same refresh rate, as long the pc is fast enough?

So i have at least 2 options in BMax to have the game run at same speed on different machines?

1) Slow down the loops to a level every machine could handle.

2) Use a Delta Timer

First option would be a bad one because you cant expect poeple having always updated there game/Gfx at refresh rate.

So only the joy of messing with delta timers is left if you want to make sure game logic is handled similar even at slow PCs?

@warren "How is delta timing complex and hideous?"
Huh? Its easy doing that for a rocket movement.
Its hideous if you have some complex AI stuff and many counter etc.
Its easy to forget a single delta timer at line 15000 which then screws your game.
Not hard to fix but hard to discover right in time ("The Fall" beta testers wouldnt find it for sure..hehe).


RexRhino(Posted 2005) [#58]
What is the big deal of using a delta timer? Why is it so bad?


Takuan(Posted 2005) [#59]
correct me if i am wrong:
Makes your code harder to read
Easier to blow your game by a wrong used d_timer
Hard to find out if you missed a d_timer
Time consuming
Isnt as accurate as render tweening:
You cant use:
A:+1
if A=10 then
exit

You have to use:
A:+1*d_timer
if A>10 then
A=10
exit


"How is delta timing complex and hideous? The simplest case is: check how much time has passed since the frame started and if it's not enough, wait until that much has passed."

Ever thought delta timing works a different way.
If the FPS is 30 but your game should usualy run at 60 FPS the d_timer gets a value of 2 which then doubles i.e an entitys movement distance if multiplied with d_timer.
That way you have same speed even if the loop is ten times slower, but choppy movement.


Since BMax mainloop wouldnt cycle faster then the refresh rate if flip used, d_timer wont turn into something floaty like 0.3 which is fine.

Sorry, didnt want this to turn into a "no d_timer", which would make no sense.
Just take it as test if poeple understand my english.
I am just very excited about the OO thingy in Bmax which i got today;-)
Outstanding delivery time by the way, expected to wait several days.


Bot Builder(Posted 2005) [#60]
I agree though, 60hz is a pain in the eyes. You look in one corner and you can see flicker in the other corner. I've heard some people cant see it some people can. Play it safe and set it to 85. 60 gives alot of people headaches and is distracting.

BTW, dont play the argument that TVs/Movies are around 20 or 30 fps. They are often times interlaced, blurred, or farther away. Your eyes do not have a set fps. It is a combination of factors that give you a since of being able to see higher/lower fps.

Anyway, seems to me that my managed2d lib could help with your problem, lowcost (skunk - you are blood right). I have abandoned the project but the basic idea was a module in which you create your images, primitives as you would entities in B3D. Then, you can move them around, set objects alpha, zorder, etc. As such, I would be able to implement some easy delta timing thats invisible to the user since the lib would provide an interface for all graphics.

Is there a demand for such a lib? Would people use it? I've already done most of it.


teamonkey(Posted 2005) [#61]
I agree though, 60hz is a pain in the eyes. You look in one corner and you can see flicker in the other corner. I've heard some people cant see it some people can. Play it safe and set it to 85. 60 gives alot of people headaches and is distracting.

60Hz is more than adequate for a TFT display without causing eye strain, plus it gives you an extra 40% processor time to play with in your main loop.

As it's such a subjective thing, the best thing to do is simply to let the user choose for themselves. c.f. Halo PC, GTA and many others.


flying willy(Posted 2005) [#62]
The majority of people are going to be using CRT displays, where 60hz is a problem.

I don't believe in adding another layer of options for the user. This is the year 2005, I'm sure something elegent can be done.

Ideally choosing a refresh rate of zero will pick the host os desired refresh rate for that resolution, -not- 60.

If I wanted 60, I'd put 60 in the box, wouldn't I?


Gabriel(Posted 2005) [#63]
I agree though, 60hz is a pain in the eyes. You look in one corner and you can see flicker in the other corner. I've heard some people cant see it some people can. Play it safe and set it to 85. 60 gives alot of people headaches and is distracting.


Except that 85 isn't safe if the monitor can't do it and either shows nothing ( as above ) or just plain breaks ( With the Law-Suits and the OH nice judge, don't hurt a person.. )

It's still decidedly unclear to me exactly how to do this properly, as it's also unclear exactly what the hz setting is doing. Is it setting the monitor hertz? Is it setting up BMax internal timing? Is it doing both? From the comments I've seen from BRL and users, it appears to be doing both. If that's the case, I think it's wrong, and should be separated so that you can lock the timing to 30 or 60hz ( for example ) and leave the refresh rate alone.


Dreamora(Posted 2005) [#64]
For timing purposes there is bglsetswapinterval which sets to 0, hertz, hertz/2, hertz/3, ... ( at least on Windows, on Linux it is useless )


teamonkey(Posted 2005) [#65]
skunk wrote:
Ideally choosing a refresh rate of zero will pick the host os desired refresh rate for that resolution, -not- 60.

If I wanted 60, I'd put 60 in the box, wouldn't I?


Earlier, skidracer wrote:
skunk, the docs need updating, if you set the hz value in Graphics to 0 (it defaults to 60) windows WILL pick the default refresh rate for that resolution.


Graphics 640,480,32 is the same as Graphics 640,480,32,60 which is not the same as Graphics 640,480,32,0


Sybixsus wrote:
It's still decidedly unclear to me exactly how to do this properly, as it's also unclear exactly what the hz setting is doing. Is it setting the monitor hertz? Is it setting up BMax internal timing? Is it doing both? From the comments I've seen from BRL and users, it appears to be doing both.



Earlier, marksibly wrote:
It tries to use vsync if possible. If not, it disables vsync and uses an internal timing system. This makes for much smoother graphics than if the vsync is left enabled and 'fighting' the update rate. It also provides surprisingly flicker-free results for systems with no vsync.

See mod/brl.mod/glmax2d.mod/glmax2d.bmx for how it all works.


This only applies to the Graphics/Flip mechanism. If you want to avoid the timing mechanism, use bglSwapBuffers instead of Flip.


Hotcakes(Posted 2005) [#66]
But then the refresh rate problem still exists, which is exactly the part of that that Sy wanted to leave alone...

I'm taking a black and white approach to the matter and taking the attitude that it's all fine and dandy and everything is how it is supposed to be and I can do watever I want because I'm me and I'm special. If a user's monitor drivers are reporting incorrect refresh rates it is not my problem. Still, if I actually released anything, I would probably put it down to user choice anyway.


flying willy(Posted 2005) [#67]
So providing we use a parameter of 0, it should be okay?

One thing equally important is the "catch up" code. What do we use for making the code repeat on slower machines to catch up?