# How can I implement framerate-independant updates?

Edit: I fixed the problem by making jumpvelocity the one that is modified and added onto, and yvelocity just equal jumpvelocity * t. This is what I have right now:

``````if (GUI->Space && grounded){
jumpvelocity = -185.f * 2  / gravity;
grounded = false;

}

if(!grounded ){
if(jumpvelocity < terminaly){
jumpvelocity += 185.f * t * 4  / gravity;
yvelocity = jumpvelocity * t;
}
else{
jumpvelocity = terminaly;
yvelocity = jumpvelocity * t / gravity;
}
}
else{
yvelocity = 0.f;
jumpvelocity = 0.f;
}
``````

Thanks for the help.

I am trying to get my gravity to work. The code I have so far is

``````if (jumpvelocity < 0){
yvelocity = jumpvelocity * t *2/gravity;
jumpvelocity += 185.f*t * 2 / gravity;
}

else if(!grounded ){
if(yvelocity < terminaly)
yvelocity += t / gravity;
else
yvelocity = terminaly;
}
``````

Gravity scales upwards, the higher making falling and jumping slower. It's default value is 1. Jumpvelocity is set to 185 when the player wishes to jump. My problem is that you fall slower at a slower framerate, but you jump at the same speed as if it was a higher framerate. How would I make it frame independent? T is delta time.

-
Can you show the code where Velocity is used to modify position? – Jordaan Mylonas Oct 18 '11 at 5:42
So, re your comment... what's the problem? It works exactly the same way for x and y. – Arcane Engineer Oct 18 '11 at 17:54
I'm using SFML so it's just you.Move(xvelocty, yvelocity). – user975989 Oct 18 '11 at 19:43
Your updated code still has absolutely all the problems I pointed out. You are not averaging `jumpvelocity` with its previous value when updating `yvelocity`, giving you an accuracy error that will get worse at lower framerate. What you call `yvelocity` should actually be `ymovement` since it's a velocity multiplied by time. You are updating `jumpvelocity` when the character no longer touches the ground, which has no physical meaning. Your check for `terminaly` is done before updating, causing `jumpvelocity` to be greater than `terminaly` and worsens at lower framerates. – sam hocevar Oct 19 '11 at 11:27

On each main loop iteration:

1. Check your system timer and store as `currentTime` (eg. SDL_GetTicks())
2. `timeDelta = currentTime - lastTime`
3. Convert `timeDelta` to seconds (usually it's in ms or ns), store as `timeDeltaSeconds`
4. `For each entity in entities: entity.position = velocityInUnitsPerSecond * timeDeltaSeconds`
5. `lastTime = currentTime` (could also be done before step 1 instead of here)

...You will need to adjust your current numbers to be in units per second, i.e. so that they would make sense at 1FPS. For example, if you expected your character's horizontal velocity to be 2 pixels per tenth of a second, then you now need to set it as 20 pixels per second. That way, the above will work out correctly.

For some applications, it is better to fix your timestep to a given amount. In this case, `timestep != timeDelta`. The latter is the amount of system time that has actually passed; the former is a quantised amount you want to consume from your time accumulator each time you apply logic updates in your game. This assists integration when you are using iterative solvers like those found in the well-known physics engines, because timesteps must be equal when doing the calculus. In this case, because you are not simply using up all of the time you have remaining on each tick, you will have fractions of time left over, and you need to accumulate these for use in later ticks. For more about this, read Fix Your Timestep by Glenn Fiedler.

-
+1 For Gaffer on Games article. – user_123abc Oct 18 '11 at 16:21
Op here, sorry I'm not sure how to respond to an answer, but I already have a timestep set into place which is 1/60th of a second or lower depending on the value returned. My xvelocity works well, and is frame independent (200.f * t), but my yvelocity is not. – user975989 Oct 18 '11 at 17:29
You do not want `velocityInUnitsPerSecond` but the average velocity during the elapsed timeframe. If velocity is constant, then your code is correct. If velocity varies linearly, as is the case with gravity, then that value is `0.5 * (OldVelocity + NewVelocity)`. Otherwise, you may need to integrate over a smaller timestep in order to avoid accuracy issues. – sam hocevar Oct 18 '11 at 19:57

It does not seem that `jumpvelocity` is needed at all. Jumping means instantly setting velocity to a given value: once the feet no longer touch the ground, the only thing that can change velocity is gravity (and air resistance, that you implement using terminal velocity).

Another remark: floating point divisions are extremely slow. I suggest you store `1.0f / gravity` instead of `gravity`.

Finally, there is a possibility that for one frame `yvelocity` can be larger than `terminaly`.

My suggestion:

``````if (GUI->Space && grounded) {
yvelocity = 185.f;
grounded = false;
} else if (!grounded ) {
yvelocity += t * inv_gravity;
if (yvelocity > terminaly)
yvelocity = terminaly;
}
``````

And remember that the following is not accurate:

``````ypos += t * yvelocity;
``````

You need to do:

``````ypos += t * 0.5f * (old_yvelocity + yvelocity);
``````
-