game timeing
BlitzMax Forums/BlitzMax Programming/game timeing
| ||
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 ? |
| ||
http://www.blitzbasic.com/Community/posts.php?topic=49306 |
| ||
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. |
| ||
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. |
| ||
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 ;) |
| ||
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. |
| ||
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. |
| ||
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. |
| ||
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. |
| ||
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. |
| ||
ok so you confused me. explain with some basic code pls. |
| ||
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. |
| ||
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. |
| ||
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... |
| ||
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. |
| ||
@ 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 ? |
| ||
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. |
| ||
Also, can anybody point me somewhere i can read about Tweening stuff. I want to know about this topic myself. |
| ||
RenderWorld(Tween#) in Blitz3D *is* Delta Timing, it just works transparently to the user. Saying that I think it only affected 3D Entitys. |
| ||
It's not delta timing. |
| ||
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. |
| ||
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. |
| ||
ok so i am board and wana keep this thread active so... bumped.. |
| ||
Michael: How isn't it delta timing? The changeed position & rotation of Entitys is multiplied by the tween value of renderworld right? |
| ||
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. |
| ||
@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. |
| ||
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 :) |
| ||
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: 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. |
| ||
is it really fair to call it a failing when i'm dislexic ? You mean dyslexic ;] |
| ||
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? |
| ||
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? |
| ||
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. |
| ||
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. |
| ||
OMG, thats Glenn, he wrote the Tribes:Vengeance physics code. Its a small world. |
| ||
:-D Cool! |
| ||
@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 |
| ||
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.. |
| ||
can you post your code so someone can try port it ? |
| ||
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. |
| ||
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. |
| ||
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. |
| ||
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. |
| ||
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. |
| ||
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. |
| ||
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. |
| ||
If you leave the flag out entirely, it defaults to HARDSYNC when it can, falling back on SOFTSYNC when it can't... |
| ||
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> :) |
| ||
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. |
| ||
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. |
| ||
thanks for the add.. more pls. |
| ||
Nope. Where is your contribution/research? |
| ||
fish who you talking to ? and if your talking to me then your blind. |