# C2 games and 120hz monitors (*dt problem?)

Discussion and feedback on Construct 2

### » Sat Jan 24, 2015 1:28 pm

@Ashley / @Aphrodite,

The use of a = lerp(a, b, z * dt) to compensate for variations in delta time is correct. I've just crunched an example to illustrate this in LibreOffice Calc. The lines in the image equate the results from using lerp with dt for fps values of 60, 72, 120 and 144. As you can see, the end result after 1 second at each frame rate is the same (well, the same within a value of approx 0.002).

The x axis is number of frames, so the right hand side of each drawn line equates to 1 second of time, the y axis is the result of the lerp using cell value for B3, for example =B2 + (1 - B2) / \$B\$1 where B1 contains the fps value. I am not a LibreOffice guru and couldn't figure how to stretch the x axis for each line so they would overlap....
You do not have the required permissions to view the files attached to this post.
A big fan of JavaScript.
B
76
S
20
G
85
Posts: 2,351
Reputation: 52,196

### » Sat Jan 24, 2015 1:34 pm

Thanks for that chart, Colludium, Was getting confusing with the diverging statements. dt is still our safe haven for consistent results it seems.
B
19
S
6
G
7
Posts: 1,101
Reputation: 6,146

### » Sat Jan 24, 2015 1:38 pm

@Somebody - it has been an emotional 30 minutes! I went from total confidence in using dt to a horrific realization that I had to go through my game and edit my lerps all the way back to where I started.
A big fan of JavaScript.
B
76
S
20
G
85
Posts: 2,351
Reputation: 52,196

### » Sat Jan 24, 2015 1:38 pm

Aphrodite wrote:they don't give the same results on the same occuring times

What do you mean by that? What did you test and what results did you get?

I am gradually remembering that A = lerp(A, B, 1 - x ^ dt) was in fact a correct form. I think the maths was something like:

Instead of considering how far you've gone, think about how far you have left to go. So if you want to jump 10% of the way there, that's the same as saying there's 90% of the way left to go after the jump, which is the same as multiplying the distance remaining by 0.9. Let's call that 'm'.

So if you make multiple jumps, that's the same as multiplying the remaining distance by m multiple times, which is m^n.

Remember that multiplying powers adds the power, i.e. m^a * m^b = m^(a+b). If we raise m to the power dt, then whatever number of multiplications happen over one second (i.e. the number of frames) always add up to 1. E.g.:

At 4 FPS, dt will be 0.25, so the distance remaining is m^0.25 * m^0.25 * m^0.25 * m^0.25 = m^1.
At 10 FPS, dt will be 0.1, so the distance remaining is m^0.1 * m^0.1 * m^0.1 * ... (10 times) = m^1.

Both times, despite there being a different number of frames (multiplications), the distance remaining was reduced by the same factor m after one second.

Therefore a formula like A = lerp(A, B, 1 - 0.5^dt) means "cover half the remaining distance every 1 second regardless of the framerate".

Without doing the actual maths to prove it, I think @Colludium has shown A = lerp(A, B, n * dt) is also correct. But I think the raise-to-power way is more predictable - the example I gave demonstrates how you can easily set it to cover half the distance every 1 second, but with just using n * dt, how do you choose n such that it covers half the distance every 1 second?
Scirra Founder
B
408
S
242
G
92
Posts: 24,888
Reputation: 198,582

### » Sat Jan 24, 2015 2:20 pm

@Colludium my calculs shows that when z becomes larger, the error becomes more important, and with values really high, it can become quite big, which value of z did you tried? (as I am curious to see, on my side, there is a value limit where the result becomes completely unstable, and can go far in variations with time), like if z is equal to fps, you have the direct value of b, stable as it is lerp (a,b,1), but ifyou have z being twice the value of fps, you have the recurring unstability, where you over around b but never come near to it (the difference a-b is always the same absolute value), and over that, well...

(I cannot use C2 until the next week so I could be wrong)

@Ashley I did not said lerp(a,b, 1-x^dt) was a bad idea (I did not calculate it), but that lerp(a, b, x times dt) was, as the product x*dt can go potentially over 1 with the fps variations (for x being 60 you can have issues as soon as the fps goes under 60) and even without that issue, the evolution is prone to errors with that calcul as with an higher x, the errors are higher too for the same time value, and I still have trouble with why this is even used at all too.

Actually, the way it goes reminds me of my studies, basically:

SP being b, PV being a, temps being the time, the blue one is when x*dt is between 1 and 2, the red one when x*dt is under 1 (which should tick something in your head, what if the framerate drastically go down for one frame or two due to something that may happen)

PS: this graph is not related to lerp, just the allure is the exact same (the maths behind a P regulation being similar to a a=lerp(a, b, x*dt) )

in short, due to how C2 works, you will be safe as long as x is under 10 for a timescale of 1.

EDIT: well actually... why I am even talking about this, I am going far off topic, we will see what were the issues of the people that have trouble.
Game design is all about decomposing the core of your game so it becomes simple instructions.
B
54
S
22
G
18
Posts: 2,123
Reputation: 17,150

### » Sat Jan 24, 2015 3:05 pm

I don't know how to compensate the variation of Dt, but I know how to compensate that high level math discussion : http://bit.ly/1B44qVT
B
74
S
21
G
12
Posts: 314
Reputation: 12,175

### » Sat Jan 24, 2015 3:41 pm

I'm pretty sure the dt in C2 is based on the assumption that whatever the framerate, it'll sum to a value of 1 after a second. I don't see why it should go crazy at 120 fps unless you've double counted dt somewhere, or just plain used it wrong
B
79
S
13
G
8
Posts: 1,977
Reputation: 9,947

### » Sat Jan 24, 2015 3:44 pm

QuaziGNRLnose wrote:You have to change the timescale depending on target vsync i believe.

dt adapts itself to the fps value and as far as I saw on my own, that applies even when the V-sync changes (if the refresh rate was under 10 hz, you would have to, but that is not the case).

which is normal, as there is no way in C2 to check the refresh rate and the a multiplatform engine should at least support different refresh rate by itself.
Game design is all about decomposing the core of your game so it becomes simple instructions.
B
54
S
22
G
18
Posts: 2,123
Reputation: 17,150

### » Sat Jan 24, 2015 4:41 pm

Thanks a billion for all your answers. This is really kind of you all to take the time to have a look at this.
Like Kamizoto, you got me lost pretty fast, but I understand the most important:

- the game goes crazy only because I used *dt in events where I shouldn't, and I couldn't notice it before because 30-60 fps is a low variation compared to 60-120 tick per second.
- You can't code a game if you suck at mathematics, even with C2. I have to learn what I skipped at school as I was making fun of the geeks. Payback time, I guess!

I don't know if it makes sense, but here's a sincere feedback from a regular C2 user who sucks at math.
The dt guide is very well written, and when you read it, you think(*dt) you understand it. I've read it, I don't know, maybe 50 or 60 times.
But when you have to write tons of events, it would be so nice to have charts you can quickly reference to. Here on the forum, or even better inside C2.
Something like this:

lerp to an angle, use this:
lerp to a position, use this:
lerp to speed, use this:
lerip to scale, use this:
lerp to variable value, use this:
every tick events: don't use if this and this. Use if this and this.
every X second: don't use.

I must sound super lazy to most of you, and I definitely understand this, but for average users it would be a freaking life saver.
B
19
S
6
G
1
Posts: 307
Reputation: 2,500

### » Sat Jan 24, 2015 4:48 pm

DT is calculated by the C2 runtime every game tick by simply doing something like this: dt = time_now - last_tick_time

Construct users do not have to worry about factoring in the v-sync rate in their calculations. As I mentioned earlier, the underlying Construct 2 engine uses something called "requestAnimationFrame" which asks the browser to run the next game tick according to the refresh rate of the local display to smooth out animation.

Regardless of how often the game tick is run (whether its running 60 ticks or 120 ticks every second), dt will adjust accordingly.
B
31
S
7
G
8
Posts: 232
Reputation: 6,284

PreviousNext