Fixed Rate Logic and Tweening

BlitzMax Forums/BlitzMax Programming/Fixed Rate Logic and Tweening

plash(Posted 2008) [#1]
Modified code from (by HrdNutz): http://www.blitzbasic.com/codearcs/codearcs.php?code=2039

Is delta timing better then Fixed Steps and Tweening?
Shambler makes a good point about the fixed step issue.

I haven't really looked for anything on delta timing yet, still tackling the idea with tweening.

Grey Alien says he can slow down the update frequency to see graphical effects in more detail, if I make the update frequency lower the objects still move at the same speed and they stay still at first.
Am I missing something that he is explaining? Like how in an animated object is tied to the update frequency?

code:


exe+source: http://files.filefront.com/timestepzip/;11893606;/fileinfo.html

Is there anything wrong with the code I'm using? (Few important changes, all variables used for updating and whatnot are now floats - used to be all integers)


MGE(Posted 2008) [#2]
Seriously, do yourself favor and just buy Grey's framework. If it saves you a few hours work/research it's worth it. I purchased his framework for 2 reasons:

1) Visa ready file support.
2) Timing code.

Everything else I don't need......yet..but I'm glad it's there...waiting. :)


plash(Posted 2008) [#3]
Seriously, do yourself favor and just buy Grey's framework.
I may, but right now I don't need a full engine. The work I'm doing now is educational - though it may yield a good framework for when I decide to make a game.

If it saves you a few hours work/research it's worth it.
What if I want to research? I don't really need this for a project, I'm just determining things for a future date - Grey's framework uses FR right? Is delta timing better?


Grey Alien(Posted 2008) [#4]
Grey's framework uses FR right? Is delta timing better?
It actually uses BOTH. The fixed rate logic runs at 200FPS (you can change this) so for each frame drawn you get 3.something logic loops at 60Hz refresh rate and the last logic loop is drawn with a Delta value for ultimate smoothness. I don't use Tweening which is basically a third method. For slow motion all I need to do is modify the delta value by a multiplier (for the fixed rate loop it's normally 1 and it's a fraction of 1 on the last loop).

Problem with delta timing is that if a big chunk of time is skipped due to some background task all the game objects will jump ahead and may move through solid objects. Fixed rate logic resolves this. Problem with fixed rate logic is that it may not work well on very slow PCs.


Muttley(Posted 2008) [#5]
I much prefer fixed timestep to delta timing. It's just a cleaner solution in my opinion.


dmaz(Posted 2008) [#6]
I prefer tweening vs the other two.


Gabriel(Posted 2008) [#7]
It actually uses BOTH. The fixed rate logic runs at 200FPS (you can change this) so for each frame drawn you get 3.something logic loops at 60Hz refresh rate and the last logic loop is drawn with a Delta value for ultimate smoothness.

I know I've mentioned this before, and I'm sure you think I'm just being picky, but it's very important. You don't do fixed rate logic. If you do three loops of one delta and one of another, that's not fixed. I understand that the games you're making don't even need fixed rate logic, so you can't see the difference, but if you're making a game which does need fixed rate logic, it will make a huge difference, and your system won't suffice. It's either fixed or it isn't, there is no "partly fixed" or "mostly fixed". What you do really is high-frequency logic with delta timing.


plash(Posted 2008) [#8]
I prefer tweening vs the other two.
Now I'm just confused.. HrdNutz' code uses FRL, but with tweening?

Is there anything wrong with the way I'm using this method?


Grey Alien(Posted 2008) [#9]
I know I've mentioned this before, and I'm sure you think I'm just being picky, but it's very important. You don't do fixed rate logic. If you do three loops of one delta and one of another, that's not fixed. I understand that the games you're making don't even need fixed rate logic, so you can't see the difference, but if you're making a game which does need fixed rate logic, it will make a huge difference, and your system won't suffice. It's either fixed or it isn't, there is no "partly fixed" or "mostly fixed". What you do really is high-frequency logic with delta timing.
Sure, if there's a physics system that depends on Fixed Rate Logic 100% it won't be suitable, but you can very easily turn off the extra fractional logic iteration and accrue it until it rolls over an interger if you want to but things may not look as smooth which is why some people use tweening instead. I don't like tweening as it can result in objects drawing inside other objects due to interpolation.


dmaz(Posted 2008) [#10]
Is there anything wrong with the way I'm using this method?


yeah, it's wrong....:) I made my tween/game object quite a while ago but a quick look makes me your capture is off.... I'll take a closer look.


dmaz(Posted 2008) [#11]
I would suggest you modify your method, otherwise it will get messy since you are also updating each of your objects with a deltatime. What I do when tweening; I run my UpdateAll() at a fixed rate... ie a 60 updates per second. this way you don't have to worry about updating each object with a timed fraction. timing my loop is setup to catch up if it falls behind. then I draw as fast (or slow) and the computer can using the tween number. Maybe I should post my code.... actually I'm pretty proud of the whole thing :) but I could just post the timing code with example I suppose. I was going to at one point make it a module but I didn't get around documenting it... I'll get an example together.


plash(Posted 2008) [#12]
I'll get an example together.
Kewl.

I really have no idea what I'm doing.
Something interesting btw, if you change the UPDATE_FREQUENCY to 0.25 the objects stay still for a moment, and if you remove the last position set's in the creation of an object they will move towards their actual positions! Kind of kewl - but bad!


dmaz(Posted 2008) [#13]
here is and example with my timing code (slightly modified mark sibly blitz3d code). I think it's pretty easy to implement.

you need these 2 calls in your main loop
Local tween:Double = stage.Update( TObject.CaptureAll, GameUpdate )
TObject.DrawAll tween

those are function pointers to functions you write that capture the old locations/values and update the objects. the example shows how easy that is.

player interaction and control should also be called from GameUpdate but you can put some -interface- controls in the main loop like I did with the calls to SetFrameRate




plash(Posted 2008) [#14]
Thanks for the example.. Still having a rough time plowing through all this.

Code looks much simpler then I thought it would be.


HrdNutz(Posted 2008) [#15]
Any method can work for some situations, even a loop without any timing code. Timing is obviously required for real time applications to be executed on different platforms correctly. Video games are generally more appealing with high framerates, so programmers try to squeeze every ounce of performance and technological advantage. With game logic and simulation getting more complex, rendering isn't the only bottleneck we have to face.

With pure Delta Timing, application runs (and renders) as fast as possible with no artificial slowdown. Delta is used to scale values, like position, and make app speed independent of framerate. Application progresses at the same rate on any platform, and executes the fastest it can, making Delta Timing a great solution. Implementation is also simple.

Limiting the framerate can remove the need for timing, but has adverse effects for those who wish to experience best possible performance. However, limiting logic updates, but allowing rendering to go as fast as possible, gives an opportunity.

Fixed Step Logic has a few benefits. Logic progression happens on a steady interval, so there is no time or frame variation when the application is restarted. This has huge benefits for debugging and reproducing behaviour. Application will go through same exact state iterations every time it is rerun, so you can expect exact values on frame basis from previous runs. This simplifies instant-replay mechanics, where application can record user input, save it along with current frame number, then replay those commands and get identical results every time. It is also beneficial for physics calculations, where variations in time steps may be unwanted.

Motion Interpolation (or Tweening) is a technique for Fixed Step Logic, when actual framerate exceeds logic update intervals. Say an application is set to run at 30 hertz (logic updates 30 time per second), but a computer is rendering at 100 FPS, motion might appear jerky because there are redundant frames being rendered. Approximately, every frame will render identically 3 times, before an update happens, then next frame will render 3 times, and so on. Because logic is running at lower rate than actual framerate, this is essentially limiting the framerate as well. Tweening is something to fill and smooth out those redundant frames.

Cheers,
Dima


plash(Posted 2008) [#16]
Does anyone have code for delta timing?


dmaz(Posted 2008) [#17]
did my example not work for you? I could reduce it down just to what required...


plash(Posted 2008) [#18]
did my example not work for you?
Ya it works.


HrdNutz(Posted 2008) [#19]
Here is example of Delta Timing (dt)

Graphics 640, 480, 0

Global t, dt

' boucing ball
Global X#
Global dirX# = 1

t = MilliSecs()
While Not KeyDown(KEY_ESCAPE)
	dt = MilliSecs() - t 'dt is how long it took to render last frame
	t = MilliSecs()

	X:+ (0.1*dt * dirX) 'multiply speed (0.1) by delta (dt) to get timing
	If X < 0 Or X > 640 Then dirX = - dirX

	Cls
	DrawOval X - 16 , 200 , 32 , 32	
	Flip
Wend



MGE(Posted 2008) [#20]
Dmaz - You're timing w/ tweeing example runs very nicely and handles interruptions nicely as well.

GA's comment "I don't like tweening as it can result in objects drawing inside other objects due to interpolation." concerns me. Have you experienced this with your code?

You mention all of your games use this method, do you have a link to one of your games I can check out?

Finally, is there a game type/style this would not work on?

Thanks!


dmaz(Posted 2008) [#21]
finished games.... yeah right, I have tons of unfinished projects! actually I am pretty close on my space invaders :) here is a really old 2 level demo.
http://www.blitzbasic.com/Community/posts.php?topic=71599#800251
use the F5-F7 keys to change the update speed.

it's amazing how many little things hold you up and how much the "support" parts of the game take to complete.

I'm not completely sure what GA means by that. my guess is that since it's interpolated, anytime you move an object it will always move from your old position to the new position, which is what it's suppose to do. but, lets say you have a ball and it goes off the right side and you want it to appear on the left... when you set the x back to 0, you may see the ball actually move across back to the left instead of just appearing there. if this is the case, it's an easy problem... you just have to make sure you equalize the old values to the new values.

another example is the space invaders demo... the aliens, when they move look like then move a large amount in one frame. actually, if you slow it down with "F5" you can see they move through the space inbetween the old and the new spot. but again easily remedied if you want by equalizing the old values. in the demo, I saw no need to do that.... actually I prefer that they do move inbetween.

other than that, I've not seen any issues and I think tweening is by far the best.

I can't think of a style where this would not work.


MGE(Posted 2008) [#22]
Thanks dmaz, this is something I'm going to look into for my next project. Could you give an example of "equalizing the old values" ? Thanks.


dmaz(Posted 2008) [#23]
all the "tweening" that I'm doing here is just interpolation between 2 values. so for tweening the x coord you need 2 x coords one of which is the value just before the last update of x. so that means we have an x and a oldx, or ox as in the example above.

basically what happens is the update function runs at a fix logic of say 30 fps. in be"tween" each update, the draw function calculates it's x by interpolating between the oldx and the new x coord. you can tween most values... like rotation and scaling too. I generally only do movement though.

so... all equalizing means is that when you need to immediately move something someplace else, all you do is set the oldx to be the same as the newx. what that means is that instead of

oldx = x
x :+ 1

you do

x = newLocation
oldx = x

see... now the draw routine has nothing to interpolate.


one other thing... I only draw in my draw routines.... that means all collision detection happens in the update routine. that includes CollideImage (if you use that) if I update at 60 fps that's usually fine... if you update at 30 you might want to have more checks so in that case you either do you collision detect in the draw function or up your updates per second.

I hope that helps...


MGE(Posted 2008) [#24]
Thanks for the continued info on this. Very, very interesting. ;)


HrdNutz(Posted 2008) [#25]
heres an older post regarding this, maybe it will help.

http://www.blitzbasic.com/Community/posts.php?topic=70516#794074


Grey Alien(Posted 2008) [#26]
So let's say you have a bullet moving towards a wall. You'll be checking its position each logic iteration and when it hits the wall you'll show an explosion. For fixed rate logic this will work fine, but with tweening it may not work fine. If you have a low logic rate (say 20FPS which some people do) but a high display frame rate the bullet may be "tweened" and shown midway in the wall because the next logic iteration has not yet been reached where it says "hang on, the bullet has hit the wall!". Hope that makes sense...


dmaz(Posted 2008) [#27]
got ya... yep that's what happens. -if- you need better collision resolution you up the logic as you said or you can keep the core logic the same and just move collision detection to the drawing routine. I personally run my logic at either 60 or 30 depending on what I'm doing.


Grey Alien(Posted 2008) [#28]
yep either faster logic or change the collision detection code to move along the movement path one unit at a time.


MGE(Posted 2008) [#29]
So if we up the logic to say 60hz, and the game is rendering at 60hz. Does tweening become useless at that point?


dmaz(Posted 2008) [#30]
no....not in my experience, tweening dramatically helps with slowdowns or hiccups. you should also be using timing code to render at 60 unless you are just waiting for vblank which is not good considering you are not in any way guaranteed 60 vblanks per second.


MGE(Posted 2008) [#31]
Right. I was just curious "under the hood" what tweening was doing when logic and render are the same speed. Is there actually any tweening going on at that point?


Grey Alien(Posted 2008) [#32]
Good question. You logic and render may not be in sync though, so I guess some tweening is still going on each frame...


dmaz(Posted 2008) [#33]
the function is still being performed but the tween value should be 1.0 most of the time.


Trader3564(Posted 2008) [#34]
In reply to GA,
So let's say you have a bullet moving towards a wall. You'll be checking its position each logic iteration and when it hits the wall you'll show an explosion. For fixed rate logic this will work fine, but with tweening it may not work fine. If you have a low logic rate (say 20FPS which some people do) but a high display frame rate the bullet may be "tweened" and shown midway in the wall because the next logic iteration has not yet been reached where it says "hang on, the bullet has hit the wall!". Hope that makes sense...


Basicly this is easly solved by taking the new interpollated position, and afterwards run a fince collision instead of just setting its X,Y you loop to it. THen if you have a hit, you stop it and ignore the interpolation.

@dmaz
thats some pretty neat code. Its the best i have seen yet.


TaskMaster(Posted 2008) [#35]
Actually, when doing tweening, you should be drawing from the last position up to the position of the last logic check. So, if it says you hit the wall, you should not have drawn any tweened frames yet.


Grey Alien(Posted 2008) [#36]
Basicly this is easly solved by taking the new interpollated position...
Yes I know that but it's something "extra" that needs to be done on top of the timing system that you don't need to do with other timing systems.

@TaskMaster: And if the logic is slow enough, I guess this could result in a visual lag?


TaskMaster(Posted 2008) [#37]
And if the logic is slow enough, I guess this could result in a visual lag?


I do not think so. Unless your logic is crazy slow, and that would be kinda silly.

If you draw at the same time as the logic frame and it is slow you get a user who wonders why nothing is happening while he is pushing a button waiting for the next frame. So, if that lag is not perceived, then the same lag while drawing tweening frames is also not going to be perceived.


Trader3564(Posted 2008) [#38]
10 updates per sec, means its only busy rendering visuals the other time. Game logic can hardly be slow with this system.


Grey Alien(Posted 2008) [#39]
10 updates per sec sounds very slow to me...


dmaz(Posted 2008) [#40]

@dmaz
thats some pretty neat code. Its the best i have seen yet.


thanks but I can't really take the credit since I just adapted a routine to Max and 2d that Mark Sibly used for Blitz3D.


TaskMaster(Posted 2009) [#41]
OK, sorry to revisit this, but I noticed something that pertains to this discussion.

I took the tweening out of my framework and set it to use fixed rate logic like Grey suggests. And here is what I have found:

Lets say your logic is set to 50 fps, and using Flip 1, you are drawing 60 frames per second. Without tweening, 10 times a second, your frames are going to update without something moving. If you have something moving smoothly across the screen, 10 times a second it is going to stay in place for the duration of two frames instead of one. That is 17%. I have a star field scrolling in the background of a game I am writing, and when I removed tweening, I notice the stars stuttering. 10 frames out of 60 is 17% of the time, it is a lot and very noticeable. With tweening on, I never saw the stars stutter.

So, without tweening, to not see stuttering, your logic would either have to be equal to the Refresh, or an equal ratio of it. If the refresh is 60, your logic would need to be 60, or 30, or 15. So that your logic would always have the same number of frames drawn per logic change.

But, with tweening, you are always going to draw the correct amount between frames and your logic does not have to be related to the refresh in any way. If you are unable to control the refresh, then your program would have to be written with a logic rate that you can change. Find the refresh rate, then make your logic run at a proportion of it.

Is my logic here flawed? Maybe something else is making my stars stutter, but I do not think so, because it was instantly noticeable when I removed tweening. My refresh is 60 and my fixed logic was set at 50.

I think I am going to keep my tweening.


Gabriel(Posted 2009) [#42]
I don't like tweening as it can result in objects drawing inside other objects due to interpolation.

No it can't. You could only draw objects intersecting other objects if you were interpolating between the current position and an imaginary future position you pulled out of thin air. The whole point of tweening is to tween between the last update and the previous update. If you've already run your collision code and not spotted that the objects will intersect, there's a problem in your collision code that will show up with or without tweening.

Is my logic here flawed?

Your logic seems perfect to me. Fixed rate logic is very, very good at creating a stable, predictable game. It will help you no end in fixing bugs, and it will enable you to do cool stuff like action replays with a minimum of fuss, but it won't make things super smooth unless you tween. But I'm not entirely sure why you wanted to try removing tweening.

EDIT: Oh, I've read back a bit. I think you tried disabling tweening because of what GreyAlien said about lagging and collisions. He's confused about both of those issues. You're correct that collisions are never a problem because you've already performed them before you tween them, and you're correct that there won't be any lag unless you set a crazy low fixed rate. I do agree with GreyAlien that 10 updates/sec seems low, but 30 updates/sec is very responsive and anything above that is gravy.


Taron(Posted 2009) [#43]
It somehow hurts the hell out of me, when I read that! You've set your fixed logic to 10 fps lower than the vblank? I'd think, just don't remove your fractional (floating point) stepping. Tweening keeps it interactive in case of interruptions of varying duration, but the fix logic just sets it to a specific pace. If you were dropping floating point steps, then you certainly get quantized motion (object stuck on location for more than 1 frame...hence stuttery.).

I'm running my last game on 60fps completely relying on the vblank and fixed logic. The slowest stars in the background are running silky smooth over the screen as far as I can tell.

What I never liked about tweening is the extra madness to everything. One could certainly get used to it, but I just don't like it, especially when you start testing for values...but well...not always necessary.


Gabriel(Posted 2009) [#44]
I'm running my last game on 60fps completely relying on the vblank and fixed logic.

So what happens if I have my vblank disabled in my driver settings?

What I never liked about tweening is the extra madness to everything.

What madness? You write it in your base class, everything inherits from it, nothing has to write any code for it. It's completely effort-free.

One could certainly get used to it, but I just don't like it, especially when you start testing for values

Testing for values? What has testing for values got to do with tweening?


ImaginaryHuman(Posted 2009) [#45]
If your vertical blank is not working and you're using Flip 1, it's going to do the same thing as if doing Flip 0 - ie flip the screen immediately and return immediately. You framerate would be all over the place, and probably way too fast.


TaskMaster(Posted 2009) [#46]
Right, I see that we are in agreement. Tweeining is necessary. I will turn my tweening back on. I had turned it off as a test to compare against Grey's theory, which I believe is incorrect.

And to Taron, you cannot rely on the Refresh rate to control your framerate. For one, a user might have vblank disabled. But also, you cannot guarantee that your users display will be able to do the refresh rate you choose. Sure, you may be choosing 60 which is the most common refresh, but it is possible someone may have a display incapable of 60. Then you will tell the graphics driver to give you 60 and you end up getting 75. Your program would then run 25% faster and be crazy impossible to play for the user.

Also Taron, I set my logic rate to 50 because it is a good number. I am not going to force the users refresh rate, as you may find that that will fail. Also, if you run your app in windowed mode, then you do not get to control the refresh rate. So, I do not plan to choose a refresh rate, I plan to allow the system default and just do a logic rate that works well.

So, tweening is important to make the game look smooth.


Grey Alien(Posted 2009) [#47]
@Taskmaster: So remember I don't just use fixed rate logic, I also use a delta value for the fractional part of the fixed rate logic interation so that your star would always move the same amount in each frame when vsynced. You were not doing that bit. Gabriel has pointed out before that my method is not true fixed rate logic, and that's true, it's a kind of fixed rate logic and delta combo which services my purposes nicely and never suffers from real or imagined collision issues. But if tweening can give equally good results, as is reported, then go for it.


TaskMaster(Posted 2009) [#48]
Can you explain how you are figuring this delta value?


Grey Alien(Posted 2009) [#49]
@Taskmaster: http://greyaliengames.com/blog/fixed-rate-logic-and-delta-time-combo/


TaskMaster(Posted 2009) [#50]
Thanks Grey. I had never thought to run logic faster than the frame rate.

What do you do in the case that there isn't even time for one complete logic frame? Like if I am running my refresh rate at 250Hz. Do you just run a partial delta logic each loop?

Also, do you check to see if you logic rate is adversely affecting the video frame rate?

For instance, if I am running at 60Hz, you are running just over 3 logic frames per draw (200Hz). What if those three logic frames take so long that my video frame rate starts to slow, do you then lower your logic rate dynamically, or do you allow it to cause the video frame rate to drop? Couldn't this then spiral into disaster, as each time a vysnc is missed your logic thinks there is time for 3 more logic frames.

It seems that you are using the performance from the last cycle to determine how long you do the next cycle.
Example: 60Hz Refresh, 200Hz Logic

Logic - Draw- Calculate =3.4 Logic
<FrameRate Suffers, so a vsync is missed>
Logic - Draw - Calculate = (6.8 Logic)
<Now 2 vsyncs get missed>
Logic - Draw - Calculate = (10.2 Logic)
<gonna miss 3 vsyncs now>
etc...

Do you have some method of making sure this doesn't happen? Or am I missing something? Also, if you do miss a vsync, then your video will stay static for 1 draw frame, which will then cause an apparent stutter.

I am not trying to shoot down your method, I am trying to understand how you are implementing it.

Thanks.


HrdNutz(Posted 2009) [#51]
HI, I just want to plug that current mini project I am working on runs at 10 logic updates per second, and interpolates positions, angles, and scales at render time. Considering my project is a Boulder-dash type game (sequel to my experimental learning project RoX, this was made in 2001 in Visual Basic 6- http://www.bd-fans.com/RoX.html), and movement is entirely tile based, 10fps for logic worked out really well.

What makes it work for my project:

Movement slides objects from one tile space to another, there is no pixel precision controls. Objects don't use variable velocity, their speeds are based on how many updates it takes to slide from one tile to another, so an object will always land exactly at the center of a tile when it passes it or stops in it. The fastest ANY object can move is 1 update, so at 10fps it translates into 10 tiles per second. This is something I considered and accepted as a limitation for my project, so my max move speed is 10 tiles per second.

User input is processed by an object inside the low freq loop, but i set traps outside, in the high freq loops (render) to remember last inputs, and use them in the low freq update. This results in very responsive control, you can tap an action button as quickly as possible and the input will register in the update.

I also stack the processed input in a list, then just reload a level and pass the values from that list instead of real input back to the game, and it replays back EXACTLY how i've played it. This took about 1h to implement, including the input object. <- try this without fixed rate logics :P

Let me also mention that at such low update freq, I free up processing for logic exponentially, resulting in having dozens of thousands of active objects with complex aggregated component maps and quad-trees.

I think i have a perfect game for such low freq update loop, and it runs silk smooth with or without vsync, very responsive, and replays are basically free byproduct. I wouldn't recommend 10 fps for most games though, 30-60 however is enough for any type of project.

Cheers,
Dima


dmaz(Posted 2009) [#52]
I'm running my last game on 60fps completely relying on the vblank and fixed logic.


as Gabriel pointed to
So what happens if I have my vblank disabled in my driver settings?


I test my stuff on IBM/Lenovo computers at work... they have integrated video which is fast enough but both the opengl and directx drivers have vblank disabled without any way in settings to enable them(that I was able to find). that forced me to choose a timing method.


Grey Alien(Posted 2009) [#53]
@Taskmaster: yes well perceived, that could be an issue but I have various controls in place to stop that like time clamps etc. which will result in a minimum framerate if need be. Also I am very careful to optimise my code so that the game logic is never very slow at all even on old PCs. If my game logic ever became too CPU intensive then I could drop the logic from 200 to 100 or consider if I really needed all that logic. It hasn't happened yet for the kind of games I write. The closest I get is when there are tons of particle effects going on and thus lots of lists to process, but all that happens on slow PCs is a few frames may drop yet the timing still stays accurate. To be honest I think the framerate drop is often due to the rendering phase anyway, not the logic. For the logic to take too long it would have to take >5ms which is really a lot for game logic, I mean what the hell would you be doing to have the CPU consume 5ms just for some game logic? It would no doubt be quite a complex game :-)


Taron(Posted 2009) [#54]
Yup, yup, it's very true with the possibly disabled vblank. Especially OpenGL, so I noticed, on mobile cards can have no proper vblank available. That's why I, at some point, wanted to have the high res timer in order to stay in charge myself in regards to refresh timing. I guess we have one spoiling factor emerging and that is the more and more common use of LCD monitors at 60Hz.

In reality I don't have any experience, yet, with a greater variety of systems.

As for "testing numbers", I'm referring to the examination of dynamics routines and the likes, if you develop them yourself, like I do. It's a little more accessible if you can limit the factors during testing.

On top of that, tweening does- what has been mentioned several times- permit skipping over specific locations, which in case of dynamics can be twice as wild as they depend on what happened before. SOOOOO routines then need to be tailored to expect such irregularities, which makes them more complicated and therefore also potentially a bit heavier on the processing side. This kicks in the most in things like chains or springs, inheriting behavior.

In an ideal world, we wouldn't have to deal with such unknown things like timing differences and triggers between machines, that's for sure. In many ways I had hoped to be able to create a framework that could be in charge of fundamental base timings and present a rigit timing environment. (one of the rare cases where "rigit" sounds like a good thing to me!)

I apologize for my unqualified and incomplete contribution in the previous post, which is at it is because I still have rather feelings toward topics like this than actual experience, but I said that already. Consider it my confused mind probing for feedback.


Gabriel(Posted 2009) [#55]
As for "testing numbers", I'm referring to the examination of dynamics routines and the likes, if you develop them yourself, like I do. It's a little more accessible if you can limit the factors during testing.

Ah, I see what you mean. That's why I like fixed rate timing. It means there is no such thing as a bug which only happens occasionally, or only happens on some machines ( excluding hardware-specific bugs like driver issues, obviously ) because every piece of logic is running identically on every single machine. If you run with a delta time of any kind, you always have that one in a million bug which only occurs when the delta is very very small or something like that.

On top of that, tweening does- what has been mentioned several times- permit skipping over specific locations

No, it doesn't do that. I don't know why people have the impression that you tween between the current position and some kind of imagined future position you guessed, but it doesn't work like that. You're only ever tweening backwards. I completely understand you getting that impression though as it's a myth which has been repeated a number of times.

I apologize for my unqualified and incomplete contribution in the previous post

Don't apologize for probing for more information or for having an opinion which hasn't necessarily been backed up by 100's of hours of testing. No one's opinion is any more or less important than anyone else's. It's only through a healthy discourse that we ever learn anything new anyway.

In an ideal world, we wouldn't have to deal with such unknown things like timing differences and triggers between machines, that's for sure.

Amen. Almost makes you want to develop for a console where every single machine is identical to every other machine, doesn't it? Well, except that Sony and Microsoft keep revising their damn machines with slightly different ram and cpu's,etc so that they're *not* all identical any more. But generally speaking, a fixed development platform would be appealing.


Taron(Posted 2009) [#56]
If I only didn't dislike gadgets, I'd see the iphone as an interesting candidate, but soon enough they'll have the same special power versions of it as the consoles, I bet...pfff :P

I'll have a closer look at that tweening again. Somehow I guess I just rested on the idea that it's about figuring out a delta for each cycle that evens out the future step length to take.

Thanks a lot, Gabriel! Wonderful post!


Grey Alien(Posted 2009) [#57]
you always have that one in a million bug which only occurs when the delta is very very small or something like that
This is a very good point as I've experienced it.


dmaz(Posted 2009) [#58]
On top of that, tweening does- what has been mentioned several times- permit skipping over specific locations


it's not tweening that permits the "skipping"... it's the logic rate. Grey runs his logic at a very high rate as he said. that permits a finer resolution in your collision detection. with tweening we can do exactly the same thing.


Grey Alien(Posted 2009) [#59]
Low speed logic (e.g. 10-20fps) could certainly make a fast moving bullet pass through a wall if you are just using tweening for the graphics, so you'd need some special path tracing code to resolve that. Also low speed logic could result in a feeling of input lag I guess (I've heard this mentioned before by people like Mike Boeh Source: http://www.indiegamer.com/archives/t-738.html ) although I've never tested it myself. Dmaz has it right which is why I like a fast logic rate.

Somewhere along the line, as Gabriel points out, I got confused that you may end up drawing something inside another object by tweening an object between it's current position and it's projected position instead of between it's last position and current position. This was because I assumed the lag was undesirable and to be avoided and when I read the fix your time step article source: http://gafferongames.wordpress.com/game-physics/fix-your-timestep/ , I interpreted it as suggesting that, but it doesn't do that. Although it's probably possible to do. Basically you know that say half a logic iteration (physics step) has accumulated but you are not processing it yet, however you could decide to render it by tweening between the current position and the projected position based on objects' dx and dy and other changing states. Probably not worth it though just to remove the lag.

Probably render tweening is easy but it would require a big rethink for me because I'm so used to doing my tweening equivalent using fractional delta values as part of my logic iterations. It's pretty easy, stuff like x:+Speed*Delta or Counter:+Delta or ParticleAlpha:-AlphaSpeed*Delta etc. In fact can someone show me how you'd do the same via tweening please?

Also I read someone post about how if say you made a ball go off one side of the screen and enter on the other that the tweening may show it at an incorrect position until the next frame is reached. The explanation made sense to me and I was thinking it could apply to all things where you reverse an object's state somehow. Like say you made something change direction, so that in logic iteration 1 it's heading right and after logic iteration 2 it's heading left (imagine something bouncing off something). If your render tweening doesn't know about the change, just the two different positions, it'll render halfway between the two positions instead of taking into account the whole path including the change and rendering at the appropriate point on that path. For example:

object starts at x=0 in logic iteration 1 and bounces off a wall at x=100 and is at x=50 in logic iteration 2 but the render tweening state is at 50%, it'll tween halway between 0 and 50 = 25 instead of realising that the whole path is actually 150 pixel long and rendering at x=75 instead.

Hope that makes sense. Same thing for reversing alphas, and what about things following a special curved path? If the logic is too slow then the render tweening would render the object on a straight line between two points instead of at its true curved position. Or am I totally wrong here and you have special render code for each object that doesn't pick a straight line to interpolate between two coords but takes into account all other factors so it can accurately interpolate. But then surely it would be repeating part of the logic code? (or maybe the logic doesn't even work out the x and y it just moves a counter on and the rendering works out the position, but then how would you handle collisions?)

As you can see I'm pretty confused about this so if anyone is experienced with it, please post some examples, explanations. Thanks! :-)


Muttley(Posted 2009) [#60]
I think you're getting a little confused Grey. :)

Each logic iteration updates the objects previous position with it's current position before moving it, so to take your example:

Logic 1: oldX = 0, newX = 100
Logic 2: oldX = 100, newX = 50

So at 50% tweening state it would render at X=75.

There are issues if you wrap around the screen because you're confusing the algorithm by effectively manually setting the position a large increment away from where it was. which you would need to catch those instances and update oldX as well:

if newX > 640
   newX:-640
   oldX = newX
endif

if newX < 0
   newX:+640
   oldX = newX
endif


So that specific step wouldn't be smoothed, but seeing as it's leaping across the screen that frame it's probably not that big a deal.

TBH, your method is just as valid. You're just doing the tweening in the logic loop rather than during the rendering. The only thing that you may want to be aware of is that if you're running your logic at 250Hz and using Delta then you have a lot of extra multiplication calculations going on for every object moved, rather than much cheaper increments/decrements, where if you leave the tweening for the render stage where it's only performing the calculation once per object per display frame.

Of course, if you've never seen an issue with this there's no reason to change the way you're doing things. There's nothing worse for a developer to waste time on than premature optimisation. ;)

Muttley


Grey Alien(Posted 2009) [#61]
@Muttley: What I am saying is that a the end of Logic 1 newx=0, then during logic2 it works out that the object got to x=100, bounced and is now at x=50. So we have a newx=0 and a newx=50. This is for an object moving at 150 pixels per logic iteration. I'm saying that the issue is similar to the wrapping issue in that a manual change has been made to the object. Make sense now? I use lots of stuff like this that I'm not sure tweening can handle.

extra multiplication calculations going on for every object moved, rather than much cheaper increments/decrements
Agreed. I'm using floats for coords and counters and changing them by a float speed * delta doesn't seem that slow, at least the amount I'm using it (i.e. several hundred a logic frame, not thousands).


Taron(Posted 2009) [#62]
Aside from all that...in regards to collisions, I've done wacky things such as calculating the actual location of the where the collision should've been after one was detected. I've used a subdividing concept in which I moved the respective object back half a step and test again, then if it hasn't been half of half forward...and so forth... goes pretty quick.

Just thought I'd mention it...

I found a beautiful timing rountine that I'll disect a little more. I wrote a small one early on that was curious, but had the usual hickups when windowed. But this other very elaborate code acts very smoothly right now. Still have to test it on the laptop. But so far it acts consistenly on openGL and directX. I forgot who it was...he translated a blitz3d routine...argh...might have been one of you?! Particles spraying from top center, lousy framerate adjustment and a bit of awkward coding (probably blitz3d style translation laziness, haha... I fixed that!). TRL type!
Anyway, seems beautiful. Correct me if I'm wrong, please!


TaskMaster(Posted 2009) [#63]
Grey, it doesn't matter what system you use, you are always going to have to overcome problems of that nature. Especially if things are moving 150 pixels per logic cycle. That is crazy fast unless your logic is crazy slow.


Muttley(Posted 2009) [#64]
@Muttley: What I am saying is that a the end of Logic 1 newx=0, then during logic2 it works out that the object got to x=100, bounced and is now at x=50. So we have a newx=0 and a newx=50. This is for an object moving at 150 pixels per logic iteration. I'm saying that the issue is similar to the wrapping issue in that a manual change has been made to the object. Make sense now? I use lots of stuff like this that I'm not sure tweening can handle.


Those instances would need to be handled the same way as if you were wrapping round the screen. No way around that.


Philip7(Posted 2009) [#65]
@Taron: Yes, that would be DMAZ code who insists that he only translated Mark Sibly's code from Blitz3d. A yeah, also, that code, you found it almost at the top of this thread 3 months ago :)

I use it too, it works really great.


Muttley(Posted 2009) [#66]
Hehe. That method is just a fancier way of doing Fixed Timestep and Render Tweening. :)


jkrankie(Posted 2009) [#67]
@Taron, let's have a look at this code then :•)

Cheers
Charlie


tonyg(Posted 2009) [#68]
Am I being gullible or did you miss the fact it's in Dmaz's post from 3 months ago?


Grey Alien(Posted 2009) [#69]
Especially if things are moving 150 pixels per logic cycle. That is crazy fast unless your logic is crazy slow.
That was just some example numbers to make it easy. It could be 15 pixels per second.

Anyway so I've found out that Render Tweening needs special cases hard-coded (as I suspected) which sounds like a pain to me. So I'll stick to logic tweening instead :-) But each to their own, as long as you don't rely on just VSync.


Taron(Posted 2009) [#70]
HAHAHA LOL...yes, it's right up there! DMAZ did the porting! Tssss...how bizarre...

So, yeah, the second codebox in this thread has the code!


Gabriel(Posted 2009) [#71]
@Muttley: What I am saying is that a the end of Logic 1 newx=0, then during logic2 it works out that the object got to x=100, bounced and is now at x=50. So we have a newx=0 and a newx=50. This is for an object moving at 150 pixels per logic iteration. I'm saying that the issue is similar to the wrapping issue in that a manual change has been made to the object. Make sense now? I use lots of stuff like this that I'm not sure tweening can handle.

This is completely unrelated to tweening. I don't know how many different ways I can write the same thing, but tweening is a visual effect, it has no bearing on logic. The whole point of it is to ensure that rendering and logic are entirely separate. You can still run the logic at 200 update per second if you want to. The difference is that you don't *need* to run the logic at 200 updates per second to make things smooth, meaning that you can get the same smoothness on a much slower machine or with much more complex logic.


Anyway so I've found out that Render Tweening needs special cases hard-coded (as I suspected) which sounds like a pain to me.

No, it doesn't need anything hardcoded. So long as you know the difference between moving something and repostioning something, so does a fixed logic timing system with tweening.


HrdNutz(Posted 2009) [#72]
Of course there are a few catches, as with any system, and you have to understand the architecture to really make use of it. Knowing things ahead of time usually makes it much easier down the road. Like converting a game with no timing code, or framerate capped, to delta timing could be a pain, but knowing how to use delta in advance, streamlines the design approach.

Same could be said about fixed interval loops, their main and major benefit is reproducibility. All of a sudden people could have a 'fixed' delta time which would never return nonsense, no matter the situation or platform, delta never changes and every tick is precise. Hmm, heres where it got interesting, bugs can be recreated exactly, behaviors did exactly the same thing every time in the same tick - suddenly there's equilibrium all over the place.

Next thing was to separate rendering from the logic, how else can you achieve super high frame rates? There are a few options here; run logic same speed as vsync, but this breaks without vsync since actual fps can be much higher, and at what frequency to run logic then? Another option is to run logic at much higher rates, then you are at least guaranteed smooth result. Third option would be to run logic at any frequency, but in the case when fps is higher, interpolate be(tween) all the values and render that until the next update.

Benefit of low frequency interval loop with interpolation at render time:
- even with high frequency loops, if fps is higher, you are drawing same frame many times. You can keep trying to raise the frequency, but then you exponentially bottle-neck your processing. Lowering frequency appears less smooth and undesirable.
- low frequency loops are obviously less straining on all resource types, and if some type of interpolation is used, stuff can be infinitely smoother than anything other than pure delta time or no timing code at all. Less strain on CPU than anything else, as smooth as it can possibly be, and totally reproducible.

people found a comfort zone between 30-60 Hertz update loops. In my game I use 10Hz, no joke, and its working. Obviously different games may require variable frequency, but i havent seen anything that cant be done in 60.

this example is as simple as could be made: http://www.blitzbasic.com/codearcs/codearcs.php?code=2039

cheers,
Dima


plash(Posted 2009) [#73]
I finally fully understand dmaz's code.

Module incoming.


Grey Alien(Posted 2009) [#74]
This is completely unrelated to tweening. I don't know how many different ways I can write the same thing, but tweening is a visual effect, it has no bearing on logic. The whole point of it is to ensure that rendering and logic are entirely separate. You can still run the logic at 200 update per second if you want to. The difference is that you don't *need* to run the logic at 200 updates per second to make things smooth, meaning that you can get the same smoothness on a much slower machine or with much more complex logic.
I know that tweening is a visual effect and I know that you can run the logic fast or slow with tweening, I 100% understand that. Did you read my post properly? Because I am saying if you are running a slow logic and are using visual tweening and you encounter a scenario like I mentioned (or the object passing off one side of the screen scenario) then it seems like the visual tweening will render the object at the incorrect position temporarily. Other people seem to be saying that this is true also. Are you saying that it is not true then?

No, it doesn't need anything hardcoded. So long as you know the difference between moving something and repostioning something, so does a fixed logic timing system with tweening.
Can you elaborate more please as this is not clear especially in the light of what I posted above. If what you are saying is true, then great, but I don't understand it yet and need to see an explanation of how visual tweening can handle it.


Grey Alien(Posted 2009) [#75]
@Gabriel: OK here's some code to prove my point. I've used dmaz's code (great OOP code btw) as a base.

It shows a ball bouncing off each side of the screen and uses a low logic rate (so you can see how weird it is, but even with a faster rate the "movement bug" still exists (it's just less noticeable) until the logic rate goes above the screen refresh rate).

Notice how unnatural the movement of the ball is at the screen edges. Take a look at the Output window. You'll see that when I reverse the direction of the ball the render tweening tries to render between the last x coord and the current x coord like this:

620.000000 logic
460.000000 logic altered
520.00000000000000 tweened from 520.000000 and 460.000000


So it will render over a total distance of 80 pixels travelling left. BUT WAIT! Our ball should have moved 100 pixels in total by travelling 20 pixels right before bouncing at the screen edge and then travelling 80 pixels left. Of course the render tweening DOES NOT KNOW THIS without some special HARDCODED tweak to the standard render tweening code for that particular object. You'd also have to make other hardcoded tweaks for any other objects that change path in the logic section. Please correct me if I'm wrong or have missed something (like a totally different way to handle the path changing or render tweening that makes this scenario work).



The above visual bug would never occur with fixed rate logic or delta time because the logic changes the path and the rendering just draws it where it is now (i.e. the correct location)


Philip7(Posted 2009) [#76]
@Grey Alien

I'm interested in seeing the visual distortion you're discribing. I'll check out your example tonight.

About the overshooting of objects. What Gabriel is trying to say (correct me if i'm wrong) is that there is a big difference between moving an object pixels*speed in any direction and re-placing it.
Moving it means you have to collision detect at every pixel between the starting point and the +pixels*speed.
The only way you can overshoot an object is if your not moving your object but stepping it and the collision-object would be in between steps. The dirty workaround would be to make you're logic so fast that you can reduce the step taken by the object to a smaller amount of pixels. Reducing the stepsize then reduces the chance that an collisonable object gets between steps.

But what i'm wondering is, can you detect collision without graphical representation? I admit i haven't done a lot of gameprogramming so maybe this a stupid question but: can i detect a collision without it already beeing drawn on the screen? So does the collision function 'grab' a screen and check for overlap in graphical represented objects or can i:

currectx, currenty -> Collision detect every x,y between -> targetx, targety: if no collision currectx=targetx, currenty=targety ?


Muttley(Posted 2009) [#77]
@Grey Alien

That's hadly a real world example though, is it?

I mean if someone's writing a game with objects moving at 500px a second, but only running their logic at 5fps, then they deserve everything they get. ;)

There's no chance of it ever being smooth, or even playable. You're talking about an input lag of up to 200ms.

Up the logic rate to 50fps and the xvel to 10 pixels and it's perfectly smooth even though the object is moving at exactly the same speed. IMHO 30fps is the absolute minimum you should aim for in a game with lots of fast moving stuff (mostly static puzzle games are another matter of course). At 30fps with an xvel value of 16.6 (roughly 500px a second) it's also perfectly smooth.


TaskMaster(Posted 2009) [#78]
I agree with Muttley on this one.

Grey, I bet you could post the best version of the code you use, and I could come up with something that makes it fail. If you try to cause failure, you will probably succeed.


HrdNutz(Posted 2009) [#79]
Using Grey's example above, even without tweening, if you adjust a position like that after overlapping collision, the object moves a lesser distance for that update (just imagine object moving at 500 pixels per second, being 1 pixel away from collsion, and it overlaps the collision boundary by 499 pixels in next single update, you adjust the object, and it end up moving only 1 pixel for that update). Reason you don't notice that object moving slower in that last tick is usually because the update frequency is high enough not to notice, and you don't penetrate by such high distances. If you want an accurate collision response, with variable velocity, at extremely low frequencies, it's a bit extra work no mater if you're tweening or not. With tweening you just have to sometime adjust old values again to correct some situations (like object leaving screen from one side and entering from another).


HrdNutz(Posted 2009) [#80]
To illustrate what i was talking about above, here's my modified sample. UPDATE_FREQUENCY is set to 1, this is as low as it gets, I am clipping the circle to the edges so it does not defeat it's boundary. You can notice why the tweened circle slows down at the end, because the real circle also slows down. Try changing frequency to 10, 30, and 60Hz, the last tick becomes un-noticeable.



Grey Alien(Posted 2009) [#81]
That's hadly a real world example though, is it?
Well some people are running logic at 10FPS and may well have fast moving objects. What I was doing was demonstrating that fixed rate tweening fails to render correctly in that scenario (and similar scenarios) unless you add in some special code to deal with it. Even if you speed up the logic and slow down the object so that it's less noticeable to the player, the error still exists, and I don't like inconsistencies like that...When it comes to visuals I'm a perfectionist and this hopefully shows in my games, I don't like "it's good enough" or "no one will notice" because *I* notice ;-)

Grey, I bet you could post the best version of the code you use, and I could come up with something that makes it fail. If you try to cause failure, you will probably succeed.
I'm not trying to "dis" render tweening, let's get that straight. Simply whenever I code anything I think about the possible ways it may fail and test them out. That's just good coding practice (or good QA at least). The code I use for logic and rendering will never draw things in the wrong place, but sure it can be made to fail other ways as already discussed like making the logic loop take >5ms for example.


Grey Alien(Posted 2009) [#82]
But what i'm wondering is, can you detect collision without graphical representation
For sure you can (and probably should). You can either use formulas in your logic, or tight collision loops where you move everything 1 pixel at a time and testing for collision, or draw to a collision layer in your logic. None of which is ever rendered.


Grey Alien(Posted 2009) [#83]
Using Grey's example above, even without tweening, if you adjust a position like that after overlapping collision, the object moves a lesser distance for that update (just imagine object moving at 500 pixels per second, being 1 pixel away from collsion, and it overlaps the collision boundary by 499 pixels in next single update, you adjust the object, and it end up moving only 1 pixel for that update). Reason you don't notice that object moving slower in that last tick is usually because the update frequency is high enough not to notice, and you don't penetrate by such high distances. If you want an accurate collision response, with variable velocity, at extremely low frequencies, it's a bit extra work no mater if you're tweening or not. With tweening you just have to sometime adjust old values again to correct some situations (like object leaving screen from one side and entering from another).
My code sample isn't showing an overlapping collision, it's showing a bounce, thus it has still moved 100 pixels (just split between two directions). How could you deal with that in tweening? The tweening would need to know also about the bouncing (i.e the altered path of the object) in order to calculate the correct placement for the object.


Grey Alien(Posted 2009) [#84]
@HrdNutz: So you are clipping the circle (clamping it's coords when it hits the edge) and I was bouncing it off to make sure it travelled the same distance each frame i.e. not clipping. Your code clearly shows the real and tweened circle slowing down due to "throwing away" some speed as a result of clipping it. In my code the real circle never changes speed (although you can't see it but you can tell from the print statements) and ideally nor should the tweened version, but it does. So your code is not showing the same thing as mine.


Muttley(Posted 2009) [#85]

Well some people are running logic at 10FPS and may well have fast moving objects.


Then they're doing it wrong. ;)

What I was doing was demonstrating that fixed rate tweening fails to render correctly in that scenario (and similar scenarios) unless you add in some special code to deal with it. Even if you speed up the logic and slow down the object so that it's less noticeable to the player, the error still exists, and I don't like inconsistencies like that...When it comes to visuals I'm a perfectionist and this hopefully shows in my games, I don't like "it's good enough" or "no one will notice" because *I* notice ;-)


Yeah, but as I pointed out, your demonstration is pretty much irrelevant.

Nobody in their right mind (especially someone after visual perfection) will be moving objects at up to 500px a second at a logic update rate of 10fps. It's just daft, and of course it will break.


Grey Alien(Posted 2009) [#86]
So you think that even though the graphical error exists, because it can't be noticed at higher speeds, most programmers will ignore it and leave the tweening code alone (i.e. standard, no special cases)? OK fair enough. My point was really that "hey there's a potential issue (for slow logic) here that may need special code with render tweening" which I guess I've proved. Programmers can choose to ignore it or do something about it in their own code if they too are bothered by it.


HrdNutz(Posted 2009) [#87]
you have to have special cases, sorry I didn't realize you were trying to bounce the object. Either way the simulation is wrong, because in this example, the ball doesn't even touch it's obstacle, kinda ricochets in the other direction, and interpolation isn't aware of that. In any case it's unrealistic, because objects should either penetrate an obstacle, or deform itself to a pancake if penetration is not possible, but in this case the object doesn't even touch the obstacle.

quick hack. Obviously at low frequency the effect is extreme, but try 60Hz, also try increasing ball speed from 150 pps to 500 pps, and check it out at 60Hz. Im sure there are better ways to deal with this, but the collision response is inaccurate to begin with.





TaskMaster(Posted 2009) [#88]
Yes, there are special cases. But depending on what you are doing, there will always be special cases. No system is perfect and can accommodate everything.

If there is a possibility of a ball striking a wall and bouncing quite far away from the wall in one logic pass, then you should be running logic quicker.

Personally, I like to show the instant the ball hit the wall to the user so he knows it happened. So, I always try to render the point of impact, even if it isn't absolutely precise as far as physics or reality goes.

As a player, I would rather see:

ball near wall
ball hit wall
ball away from wall again

rather than:
ball near wall
ball away from wall


TaskMaster(Posted 2009) [#89]
I don't really think we are discussing tweening versus not tweening at this point. Because if you are going to run logic faster than render, you do not need to tween. You won't tween.

I think this discussion is really whether logic should be faster than render.

I do not see any reason to run logic faster than render. If you are doing it just so you do not have to check for objects passing through objects without colliding, then that is fine, but if you really want to avoid that happening, you really should check for it. No matter how fast you run your logic, there is the possibility of one object passing through another unless you check for it.

So, I would say, the only real way to do it, is to run a logic rate the same as the render speed, and check for the possibility of objects passing through objects.

But, since we do not know what the render rate will be, unless we control it, we can't do that either.

So, then you can do two things. Run a high logic rate hoping that the render rate does not surpass it. Or, run tweening in case render rate is faster than logic.


HrdNutz(Posted 2009) [#90]
Im not sure you can ever reliably run logic faster than render, because if vsync is missing there's nothing stopping it. Can easily achieve fps greater than 5 thousand on a modern hardware with nothing drawing, I average over 900 fps in my game, that's already faster than most update loops. You can't depend on logic being faster than fps 100% of the time. And if logic is not as fast as fps, then you end up drawing same frame more than once. That's another benefit for interpolation, it infinitely gets smoother with greater fps (as infinite as computer precision).


Grey Alien(Posted 2009) [#91]
In any case it's unrealistic, because objects should either penetrate an obstacle, or deform itself to a pancake if penetration is not possible, but in this case the object doesn't even touch the obstacle.

Agreed, but most games are unrealistic unless they are physics sims. In my bouncing code I was emulating what would happen in a typical brick buster. You don't want the ball to look like it has lost speed or got hung up for a second so you make sure it always moves a constant amount of pixels each logic frame just change the direction.

So even your tweaked code is not rendering it in the correct position because the tweening cannot cope with the bounced unless you added in some special code to the tweening section. Of course it's less obvious at a faster logic rate. So basically every object could inherit from a base class with default tweening code and you'd override it for objects that perform special movements (or just don't bother :-))

rather than:
ball near wall
ball away from wall


Yeah I'd probably do

ball near wall
sound effect played and particle effect left at collision point on wall
ball away from wall

This way the ball never looses speed. Think about if the ball is going 100 pixels per second and it is 1 pixel from the wall before the collision. If you stuck it to the wall for a frame it would have lost 99% of it's speed! That's too much not to look weird, especially considering that at other times it may be 90 pixels from the wall and thus only lose 10% of it's speed - you'd have inconsistency in the visual effect of every bounce...

No matter how fast you run your logic, there is the possibility of one object passing through another unless you check for it.
Not if you make sure your objects never move faster than 1 pixel per logic iteration (so in my case 200pixels per second as I run my logic at 200Hz).

Im not sure you can ever reliably run logic faster than render, because if vsync is missing there's nothing stopping it. Can easily achieve fps greater than 5 thousand on a modern hardware with nothing drawing, I average over 900 fps in my game, that's already faster than most update loops. You can't depend on logic being faster than fps 100% of the time.
Agreed, I'm not depending on it as maybe TaskMaster thought. I'm just setting it high for smooth collisions, responsiveness and to suit my style of coding. I often test the game with VSync off to check how optimised it is and it works and looks exactly the same (except with vertical tearing) because the logic is controlling the game speed and movement and collisions etc.


dmaz(Posted 2009) [#92]
I forgot who it was...he translated a blitz3d routine...argh...might have been one of you?! Particles spraying from top center, lousy framerate adjustment and a bit of awkward coding (probably blitz3d style translation laziness, haha... I fixed that!). TRL type!


that hurt my feelings! :P

I didn't translate it from some b3d source... I built the code above based on Marks tweening routine but it's my own type and example.... "awkward coding" "laziness" !!? what do you mean :) seriously?

that code is AWESOME!

actually seriously Taron, what do you think is wrong with it?


MGE(Posted 2009) [#93]
I've done some tests with a tweening engine and an engine using GA's timing. To be honest, when running on modern hardware and running at full vsync, the results are visually identical.

The only time tweening wins out is when you have some serious cpu stutter or when the frame rate suffers. And even that was taken care of when I applied my FRS (frame rate stablizer) to GA's timing code. :)

So I'll take the ease of the fixed logic code in GA's timing. No need to do anything out of the logic loop. All movement, collision, etc, can be done in the UpdateLogic() routine. The Render() routine simply draws objects at their current positions.

That's about as easy as it gets me thinks. :)


dmaz(Posted 2009) [#94]
So you think that even though the graphical error exists, because it can't be noticed at higher speeds, most programmers will ignore it and leave the tweening code alone (i.e. standard, no special cases)? OK fair enough. My point was really that "hey there's a potential issue (for slow logic) here that may need special code with render tweening" which I guess I've proved. Programmers can choose to ignore it or do something about it in their own code if they too are bothered by it.

that error occurs with delta too..but you're right, the higher your logic the better. but we are often looking for ways to increase our performance yet you are doing everything 3x more often. if you have no performance issues running at that high a rate, then great. but doing everything 3 times per render (60hz lcd) seems excessive... you don't render at 200 do ya?


dmaz(Posted 2009) [#95]
The only time tweening wins out is when you have some serious cpu stutter or when the frame rate suffers. And even that was taken care of when I applied my FRS (frame rate stablizer) to GA's timing code. :)

So I'll take the ease of the fixed logic code in GA's timing. No need to do anything out of the logic loop. All movement, collision, etc, can be done in the UpdateLogic() routine. The Render() routine simply draws objects at their current positions.


can you share an example or do you want to keep it private?


TaskMaster(Posted 2009) [#96]
Im not sure you can ever reliably run logic faster than render, because if vsync is missing there's nothing stopping it. Can easily achieve fps greater than 5 thousand on a modern hardware with nothing drawing, I average over 900 fps in my game, that's already faster than most update loops. You can't depend on logic being faster than fps 100% of the time. And if logic is not as fast as fps, then you end up drawing same frame more than once. That's another benefit for interpolation, it infinitely gets smoother with greater fps (as infinite as computer precision).


Sure you can. You may be rendering, but unless your monitor runs refresh of 900Hz, then the user is not seeing those frames. The user is only going to see screens that happen during a refresh. So again, you are doing logic faster than render.

This way the ball never looses speed. Think about if the ball is going 100 pixels per second and it is 1 pixel from the wall before the collision. If you stuck it to the wall for a frame it would have lost 99% of it's speed! That's too much not to look weird, especially considering that at other times it may be 90 pixels from the wall and thus only lose 10% of it's speed - you'd have inconsistency in the visual effect of every bounce...


Sure, but you also have an unplayable game. If the ball is moving more than about 3 pixels per render, your game is running very poorly and hard to play. So, examples like this make no sense, as the game would be an unplayable piece of crap if this were occurring. So, a stutter of 1 or 2 pixels to show the user the collision is ok in my book.

Not if you make sure your objects never move faster than 1 pixel per logic iteration (so in my case 200pixels per second as I run my logic at 200Hz).


This isn't exactly true. An object moving 200 pixels per second in one direction could pass through an object moving 200 pixels per second in the other direction. Your max speed is actually 100 pixels per second per object.

So I'll take the ease of the fixed logic code in GA's timing. No need to do anything out of the logic loop. All movement, collision, etc, can be done in the UpdateLogic() routine. The Render() routine simply draws objects at their current positions.


But that is how tweening is done as well. Logic in a logic loop, drawing in the drawing loop. Nothing different. Never put game logic in the render loop. In tweening there is just some code that draws the interpolated frames. But no actual game logic. It is like 4 or 5 lines of code.

but we are often looking for ways to increase our performance yet you are doing everything 3x more often


Exactly. In a perfect world, you would be able to run exactly one logic frame per render frame with a fixed logic rate. But since we cannot guarantee the render speed, we have to come to some compromise.


Grey Alien(Posted 2009) [#97]
In a perfect world, you would be able to run exactly one logic frame per render frame with a fixed logic rate
100% agreed. Like on the Amiga.


Taron(Posted 2009) [#98]
actually seriously Taron, what do you think is wrong with it?



Oh, just some code ethics and a few inconsistencies in style.
like:
If time+1001<MilliSecs() Then
	        framerate=counter
	           counter=0
	        time=MilliSecs()
	        EndIf

which reads a little cleaner this way:
If time+1001<MilliSecs()
	framerate=counter
	counter=0
	time=MilliSecs()
EndIf


I think there were a few more things, but I'm currently on a different continent, far away from my machine and on typing on a horrible laptop keyboard, so I'm not too motivated to revisit the code in detail, haha... or worse... write stuff!

here is and example with my timing code (slightly modified mark sibly blitz3d code).

And that's what threw me off... thought it meant you've translated it...

But you have every reason to cheer, because I think your routine rocks!


dmaz(Posted 2009) [#99]
whoops I didn't even notice that.... those 2 functions were just basically copied from other places and I must of messed up the formatting so you are right! I guess that was me being lazy.