game timeing

BlitzMax Forums/BlitzMax Programming/game timeing

Paul "Taiphoz"(Posted 2005) [#1]
I seem to have lost a post so I'll post this again.

I was wondering if anyone has any examples of game timing in blitzmax, using the OO code.

or is everyone still using either deltatime or render tweening ??

Does render tweening even work in Max ?


TartanTangerine (was Indiepath)(Posted 2005) [#2]
http://www.blitzbasic.com/Community/posts.php?topic=49306


Paul "Taiphoz"(Posted 2005) [#3]
so would i be right then that no one has done any render tweening ?

I hate Delta , can cause to many collision problems.

Does anyone have any other timeing systems that are more stable than delta timing.


Robert Cummings(Posted 2005) [#4]
Delta timing causes all sorts of problems. Just use Blitz3D style timing code, but convert it to max. Take out the tween stuff.

ie: run your logic at 100fps, and once the logic is done, just render. obviously this means moving your render stuff into a seperate loop.

Tweening isn't really neccesary when the logic rate is high enough. Sure it's a slight performance hit, but worth it for sanity.


Paul "Taiphoz"(Posted 2005) [#5]
just running the logic at 100 frames and then flipping will neither give you a smoth game nor will it controll the frame rate.

I cant beleive that the only timing system we can use is delta, there must be something else. some one must be sitting on some cool little routine for this.

code examples would be nice ;)


Robert Cummings(Posted 2005) [#6]
just running the logic at 100 frames and then flipping will neither give you a smoth game nor will it controll the frame rate.
Funny though, thats how www.popcap.com do all their games. Smooth as silk, I recall...

See code archives for 2D timing code made in blitz and blitz3d. It is easy to convert and several do not have delta timing, but run the logic at a fixed rate.


Paul "Taiphoz"(Posted 2005) [#7]
guess the 100 cycles through the logic code before a render will have to be tested, but at a first thought id guess that running on a dated system the method would run into trouble, with a CPU or memory that cant get through those 100 cycles fast enough per second.

As for the 2D timing examples in blitz that dont use delta time and can be converted to max id like to see a link if you have the time to post one.

the main methods iv ever used are tween and delta, and i dont like dlta and dont think max handles tweening in the same way so id have to see some examples of these in max.


Tom(Posted 2005) [#8]
Check this http://www.tomspeed.com/delta_timing.bmx

I'm using it in an asteroids type game and there's been no collision problems at all, and that's with me putting in random delays e.t.c to test.


Paul "Taiphoz"(Posted 2005) [#9]
You will if your games run on a slower cpu, bottom line is to compensate for the redused processor speed the delta is increased and the amount of pixels per move goes up, if you have a sprite the wrong size its possible to step right over a sprite it should be hitting.

which is why I hate Delta Time.

What i wana know is , is there anyone else out there not useing deltatime to control game speed. and if so could you post some sample code, cos I dont think im the only one who would like to know.


Robert Cummings(Posted 2005) [#10]
You're not listening are you? the way is as described above: set your logic to run at 100fps and let the rendering take place each time the logic ends.


Paul "Taiphoz"(Posted 2005) [#11]
ok so you confused me. explain with some basic code pls.


Jay Kyburz(Posted 2005) [#12]
I think the point is if it takes 50ms to render the scene your logic is only going to get updated twice a second.

Saying "set your logic to run at 100fps and let the rendering take place each time the logic ends." doesn't mean anything. Your logic still has to wait until the render is finished.

Ideally we would use threading to make sure logic is always ticked at 100Hz and the render could just chug away as fast as it can. Unfortunately we can't do that in Blitz.

If you are making a twitch game you need to maintain a good frame rate anyhow. If the frame rate is good the physics will be good :). If the frame rate sux, your collisions will suck too.


Delta timing is good for games were you want to accommodate a varying frame rates. In a turn based strategy game for example, it would be nice to have 100fps but players will be happy with 20 or 30. You can support a wider range of video cards and polygon counts. It is still important to have the games animations playing at the same speed so we need to slow down objects that are being updated more often.


altitudems(Posted 2005) [#13]
As far as the collsion problems you have mentioned, could they not be solved by using sweep tests in your collsion code?

It seems to me that even if you had a fast computer you would still have missed collsions if objects moved to fast.


Hotcakes(Posted 2005) [#14]
You're right; that happens in my game all the time. Basically you need a loop something like For i=a To b Step yourchoice... I use 1 in my game, which is obviously the most intensive. The only problem here is that while it makes the collisions more accurtae, it bogs down the slow machines even further.

Basically if a machine can't keep up, you're screwed no matter what method you choose. The point is to find the best method to hide the problem. But you can't really get rid of it entirely no matter what...


TartanTangerine (was Indiepath)(Posted 2005) [#15]
See this bit of code here (from the thread I mentioned earlier) :-
Global Delta1:DeltaTime = DeltaTime.Create(60.0) 
Global Delta:Double
While Not EXIT_FLAG

	DeltaTime.Update()
	Delta = DeltaTime.CurrDelta(Delta1)
		
	' -------------------------------GFX FUNCTIONS ---------------------------
	ScreenUpdate = ScreenUpdate + Delta

	If ScreenUpdate => 1 Then
		RenderGFX(ScreenUpdate)
		ScreenUpdate = 0
		Timer.UpdateAll()
	EndIf	
	' ------------------------------------------------------------------------
	
	UpdateGame(delta)
	FlushMem
	Delay(1)
	
Wend


This will update the screen by calling the function UpdateGFX() at a rate of 60 FPS OR if the computer is running slower that 60FPS then every frame.

The Logic is updated every frame by calling UpdateGame(), logic is not now tied to renderspeed (except on really slow machines). Logic will now run at 100,000's times persecond instead of just 60.

If you don't think this works then try the Caboodle beta. I have tested it on a 450Mhz intel at the logic updates in excess of 1000 times per second. On my dev machine the logic updates in excess of 200,000 times per second.


Paul "Taiphoz"(Posted 2005) [#16]
@ Indipath.

Your missing the point m8, Delta Time as a game frame limiting system to control a game suck's ass, IF the game is anything with a bit of pace, the way I see it Delta should be used for puzzle games, games that are possibly turn based and other such slower paced games that dont require the higher level of delta in collision checking and movement.

On the other hand, Tweening from B3D was used more for anything that was really fast paced while still giving high level of detail and control in collision checking because it didnt alter the rate or movespeed of all of your game objects.

In a nut shell, for your caboodle or what ever its called game, delta was the right choice, but for the games I like to code that have that fast arcade style of play, I need something else. Something thats not Delta Time.

@ Altitudems
Yeah a sweep test could solve the Delta probelem, but as iv said above Delta is/should be used more for games with less pace, if you used Delta in a game that has tons of enemie's on screen and all shooting bullets, so tons of possible collisions, then your sweep test then becomes a burden on the game and drags the framerates down to nothing. as its having to do every move 100's of times.

Again like Delta Sweep testing a collison of say one sprite on another is fine, but if you have to do it to many its just not practicle.


So..

Again. I ask is there anyone out there, coding in Max, that has another method for controling game speed , frame rates on different systems.

How about you Mr Sibly, I'm sure you must have thought of this at some point, you got any little Max secrets your not letting us in on yet ?


Jay Kyburz(Posted 2005) [#17]
Hey Altitudems,

These sweep tests sound like a good idea. I assume you create volumes base on the size and position of the object between frames and calculate collisions based on these instead. Is this something that can be done in a 3d physics engine as well?



Also, I wonder if you could get you physics simulation to step through each frame that it has missed as a result of a slow render frame.

For example, the render is slow and taking 10 ms but you want your physics being tested every 1 ms. When you call update on your game code it calculates that it should have run 10 times since last time it was called. Your game could increment the position of each object 10 times and calculate collisions before handing back over to the renderer. The render would then lock up for another 10 ms, then game will tick 10 times, then the render will lock up for 10 ms. The game would play catchup to the renderer.

Anybody tried this? Is it crazy talk?



Hey Tim, Your delta code is the opposite of this right? It allows the game to tick faster than the frame-rate but if the frame-rate is very poor the game tick rate will also suffer.


Jay Kyburz(Posted 2005) [#18]
Also, can anybody point me somewhere i can read about Tweening stuff. I want to know about this topic myself.


Tom(Posted 2005) [#19]
RenderWorld(Tween#) in Blitz3D *is* Delta Timing, it just works transparently to the user. Saying that I think it only affected 3D Entitys.


Michael Reitzenstein(Posted 2005) [#20]
It's not delta timing.


altitudems(Posted 2005) [#21]
A much simpler alternative to sweep tests is to multisample; instead of performing a single static test at the object's new position, perform several tests at several positions located between the object's previous and new position.

If you make sure that the samples are always spaced at distances less than the object's radius, this will produce excellent results. In my implementation, I limit the maximum number of samples, so very high speeds will sometimes result in problems; this is something that can be tweaked based on your specific application.


Paul "Taiphoz"(Posted 2005) [#22]
yeah Alti your wseep test sounds a lot like the way i do it. although I stend to got for more steps between the two points to get a more accurate detecion. id like to see your code tho if you dont mind. always good to see how others do things.

all this collisions talk tho is going a little off topic, were trying to work out other methods for game timing and control of a games FPS in blitz max.

So anyone else got any ideas. I'm sure there must be some others working on stuff now that does not use Delta....

I hate to say it but if Delta is the only method that can really be used( I Doubt it ) then i wont be to hapy.


Paul "Taiphoz"(Posted 2005) [#23]
ok so i am board and wana keep this thread active so...

bumped..


Tom(Posted 2005) [#24]
Michael: How isn't it delta timing? The changeed position & rotation of Entitys is multiplied by the tween value of renderworld right?


Robert Cummings(Posted 2005) [#25]
Yo Tom, it's 'entities'. Sorry for being picky.

Blitz3D timing as used in the "castle demo" was very much still fixed logic rate, because you still moved from A to B based off the logic rate, not the delta time.

The delta affects only render tween. So if you took that out, it's still fixed rate logic, and didn't affect where the objects actually were, only where they were rendered.


Paul "Taiphoz"(Posted 2005) [#26]
@Tom
The Difference is that with tweening, the tween only alters the 3D objects, models, mesh's . It does not get applied to every single motion controling variable in your code, like is done when using Delta Time.

ARGHHH!!!

Could anyone out there in cyber space, please give some thoughts on other ways to control games in max, I dont want to begin any large scale projects until I have this key feature nailed down.


Robert Cummings(Posted 2005) [#27]
While I'm being picky to Tom, I might as well be fair and pick out all the spelling mistakes:

@Yavin:
board = bored
timeing = timing
controll = control
redused = reduced
practicle = practical

It's only fair on Tom :)


Paul "Taiphoz"(Posted 2005) [#28]
thanks for that....

Its always nice when people point out one of my biggest failings. or is it really fair to call it a failing when i'm dislexic ?

back on topic. pls.


Michael Reitzenstein(Posted 2005) [#29]
Michael: How isn't it delta timing? The changeed position & rotation of Entitys is multiplied by the tween value of renderworld right?

Delta timing is a method which allows the logic to be updated at the same time as rendering, you just have to modify the magnitude of the update by the time passed since the last update tick. If you do delta timing correctly, you'll actually never use the tween parameter on RenderWorld.


Hotcakes(Posted 2005) [#30]
is it really fair to call it a failing when i'm dislexic ?

You mean dyslexic ;]


Jay Kyburz(Posted 2005) [#31]
Yavin, Perhaps you could be more specific about what you want?

What exactly to you need to do to the game timing? What do you want to achieve?


Jay Kyburz(Posted 2005) [#32]
I was talking to one of the programmers here at Irrational and the methods describes above is kind of like how the physics was handled for Tribes:Vengeance. I think this is what I would like to do for my game.

Basically I'm going to have a fixed frame-rate for stepping the animation, movement and physics. Something nice and smooth like 5ms (or 200fps), then as the renderer slows, the game will step multiple times to keep up.

For example, if 12 ms have past since last time the game loop started, I know I need to run the game loop 3 times, hold for the remainder 3 ms, then pass back over to the renderer. (66 fps in this situation)

One consequence will be that the frame-rate will drop in 5 ms increments. 200, 100, 66,50,40,33,28 (i think) vsync may also be a problem?

The advantage is I don't need to have delta calculations all through my code. Its all just fixed step.

Can anybody tell me why this is a dumb idea?


HappyCat(Posted 2005) [#33]
Nope. Seems to be a recommended method. That article suggests tweeing your rendering for the remaining time (3ms in your example), but your way would save that hassle.


Paul "Taiphoz"(Posted 2005) [#34]
id like to see some code examples of this if possible. its always easier to see and get to grips with concepts when you can see the code and see how it runs for yourself.


Jay Kyburz(Posted 2005) [#35]
OMG, thats Glenn, he wrote the Tribes:Vengeance physics code. Its a small world.


HappyCat(Posted 2005) [#36]
:-D Cool!


HappyCat(Posted 2005) [#37]
@Yavin:

Okay, at it's simplest without tweening ...

Local TicksThisFrame = 0

' Update the frame timer
Timer.Update()	' updates Timer.FrameElapsedTicks

' Keep track of how many ticks are To be processed in this frame
TicksThisFrame = TicksThisFrame + Timer.FrameElapsedTicks

' Process the logic the correct number of times For this frame
While TicksThisFrame >= Timer.DeltaTicks	' Timer.DeltaTicks is fixed depending on your logic rate

	' Update the logic
	UpdateGameState()
				
	' Reduce the remaining ticks this frame
	TicksThisFrame = TicksThisFrame - Timer.DeltaTicks
	
Wend

' At this point you may have a number of milliseconds Left 
' over which will be added to the next frame's ticks

' This remainder can also be used as the tween value

Local Tween# = 1
If TicksThisFrame > 0 Then Tween# = Float(Timer\DeltaTicks - TicksThisFrame) / Timer\DeltaTicks

' Render To screen
RenderFrame(Tween#)	' how you use this tweening value within RenderFrame is the bit I haven't yet sussed in BMX



Paul "Taiphoz"(Posted 2005) [#38]
Yeah m8 I use Tweening in 90% of my B3D Projects, I also dont know how to convert this to Max..

If some one could actually give an example of how to do b3d equiv tweening in max id be a really happy chap..


SillyPutty(Posted 2005) [#39]
can you post your code so someone can try port it ?


HappyCat(Posted 2005) [#40]
Tweening in B3D is built in - you just call RenderWorld(Tween#). In BMX you'd have to to it all yourself, presumably by remembering the previous state and interpolating (is that right?) between the previous and current states.


SillyPutty(Posted 2005) [#41]
i wish i could help, but i dont know how to implement this. I will try and search some stuff tonight. The only way I know is delta timing.


Paul "Taiphoz"(Posted 2005) [#42]
yeah it interpolates from point A to point B. its rather handy for a number of reasons some of which aint documented ..

gona have to try and find my old B3D dvd with ma backed up projects.

OFFTOPIC..
"Graphics 400,400,0 | NOSYNC"
is that the right format for the DX flip flase ? cant seem to get it working.


Tom Darby(Posted 2005) [#43]
You need the depth in there, too:

Graphics 400, 400, 32, 0 | NOSYNC


Will get you a 400x400 screen with 32-bit color and no flip synchronization.


Paul "Taiphoz"(Posted 2005) [#44]
ahh I was missing the bepth. doh lol.

ok thanks tom and back onto topic.

I was thinking that creating a generic timer object, and then using one of it to control game time might be a good idea, could let you speed up and slow down game speed in real time.


Vorderman(Posted 2005) [#45]
After a bit of testing I've found that every single Bmax example program that uses 2d graphics displays the same jerkiness of movement that my test programs do, so perhaps there is just no way around it at all.

I can get system-specific smoothness - on one PC any refresh rate in multiples of 50 (but above 50hz) is silky, but run the same prog on my second PC and it's back to the usual jerkiness. Also on my first PC running at 50hz is smoother than 60hz, fullscreen or windowed, which is odd as the monitor refresh rate is 75hz.

PCs are a pig to use sometimes.


Vorderman(Posted 2005) [#46]
Also, HARDSYNC produces an "UNHANDLED EXCEPTION : UNABLE TO SYNCHRONIZE REFRESH RATE" error on my main PC whereas on my work PC it produces a sily smooth refresh.


Tom Darby(Posted 2005) [#47]
If you leave the flag out entirely, it defaults to HARDSYNC when it can, falling back on SOFTSYNC when it can't...


Tom(Posted 2005) [#48]
Yavin: "If some one could actually give an example of how to do b3d equiv tweening in max id be a really happy chap.."

Delta time :)

But seriously, I think we could all do with the same solid framework to build off, so anyone care to start?


Vorderman: As I see it there should only ever be juddering when the frame rate drops below the monitors refresh rate.

If you're moving a sprite a constant speed across the screen, and your monitors refresh rate was 60Hz, but the program is drawing at 50fps, then 10 of those 50 frames will be displayed twice, i.e they get more display time = apparent judder.

If the refresh is 60 and the frame rate is 30, every frame is displayed twice, things should look smooth(ish!) :), as is the case for 120Hz/60fps, 100Hz/50fps.

Regarding not being able to sync the refresh rate, was that with a CRT or a TFT/LCD?


jfish: <slap> :)


Paul "Taiphoz"(Posted 2005) [#49]
Yeah I think we need to create some frameworks for the community to help the others like us handle the all important aspect of game design. game time.

I think the following would be a common game loop

Function Play()
  cls

    update()
    render()

  flip
end function


This would be an Option that could be used in Max.

Const FPS# = 60;
timer = MilliSecs();
t_step = 1000/FPS;

function Play()
While KeyHit(1)
    Repeat
    Until (MilliSecs()-timer)=>t_step;
 
        current_frames = (MilliSecs()-timer)/t_step;
        For k=1 To current_frames
            timer = timer + t_step;
            update();
        Next
    
        render();
    Flip; 'Graphics 800,600,16,60 | NOSYNC - for flip false in DX
Wend
end function


pls add more.


HappyCat(Posted 2005) [#50]
Good luck Yavin - biggest problem I think you'll find is that there's a variety of different ways to do timing:

- Completely variable delta rate.
- Fixed logic rate with variable render rate, as described by Jay Kyburz.
- Variable logic rate with fixed render rate, as described by Indiepath (Tim).

and none of them are right or wrong. Each has advantages and disadvantages and each are useful in different situations. As far as I can tell:

- Completely variable delta rate is simple if you don't need physics or collisions between fast moving objects and avoids tweening.
- Fixed logic rate with variable render rate is good for physics and collisions, fixed delta means simpler calculations, but might require tweening to get smooth animation.
- Variable logic rate with fixed render rate - actually I'm not sure of the advantages of this (particularly with uncapped logic rates of 200,000 times a second, which seems a bit mad) - maybe Tim can fill us in.

And then you have questions of:

- Should you tween or only ever render whole frames (as Jay suggests).
- Should the variable rates (logic and/or render) be capped at all?

But listen to pessimistic old me :-)

Okay, my suggestion is - if you're not needing fixed steps for physics, but need steps to have a maximum size for collision detection purposes, then how about:

Local TicksThisFrame = 0

' Update the frame timer
Timer.Update()	' updates Timer.FrameElapsedTicks and sets Timer.DeltaTicks to 10

' Keep track of how many ticks are To be processed in this frame
Local TicksThisFrame = Timer.FrameElapsedTicks

' Process the logic the correct number of times for this frame
Local NumberOfPasses = Ceil(Float(TicksThisFrame) / Timer.DeltaTicks)
For Loop = 1 To NumberOfPasses

	' If less than a full frame left then "tween" the next
	' frame by reducing the delta ticks for this one frame
	If TicksThisFrame < Timer.DeltaTicks Then
		Timer.DeltaTicks = TicksThisFrame
	End If

	' Update the logic based on Timer.DeltaTicks
	UpdateGameState(Timer.DeltaTicks)
				
	' Reduce the remaining ticks this frame
	TicksThisFrame = TicksThisFrame - Timer.DeltaTicks

Next

' Render To screen
RenderFrame()
Timer.Update() sets Timer.DeltaTicks to 10ms, so logic updates (at minimum) 100 times per second. This keeps my collision detection solid. All the code in UpdateGameState() multiplies everything by Timer.DeltaTicks, so if any particular call to UpdateGameState() doesn't have a full 10ms left then it still calculates okay. So basically, Timer.DeltaTicks will never be more than 10ms, but if it's less then that's okay.

Hope that makes sense.


Paul "Taiphoz"(Posted 2005) [#51]
thanks for the add.. more pls.


Robert Cummings(Posted 2005) [#52]
Nope. Where is your contribution/research?


Paul "Taiphoz"(Posted 2005) [#53]
fish who you talking to ? and if your talking to me then your blind.