# Framerate independent friction

This topic is 2269 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

I noticed that my game runs a bit differently when running at 60 FPS on my PC and 30 FPS on my phone, and I traced it down to the friction code. I'm applying friction like this:

newVelocity = oldVelocity - oldVelocity * friction * elapsedTime

The results are not consistent between 60 Hz and 30 Hz. But then I thought about how continuous compound interest is calculated, and I came up with this:

newVelocity = oldVelocity * exp(-friction * elapsedTime)

It works perfectly, at least on paper. Has anyone else ever used an approach like this? Or is there a better way to do it?

Edit: I should mention that the game is using a fixed time step. At 30 Hz it's 1/30 seconds and at 60 Hz it's 1/60. Edited by BradDaBug

##### Share on other sites
I think the better way to do it is to use a fixed time step for physics, independent of how fast the screen updates.

http://gafferongames.com/game-physics/fix-your-timestep/

##### Share on other sites
Personally I think fixed timestep physics is good, but some accomodation for varying time delta is nice because schedulers are never 100% precise.

##### Share on other sites

Personally I think fixed timestep physics is good, but some accomodation for varying time delta is nice because schedulers are never 100% precise.

what do schedulers have to do with a fixed timestep ?

If you use a fixed timestep you won't use elapsed time in the physics calculations.

updatePhysics(elapsedTime);

you do:

while (elapsedTime>timeStepSize) {
updatePhysics(timeStepSize);
elapsedTime-=timeStepSize;
}
where timeStepSize is constant so the physics calculations will be deterministics as you always give it the same delta to work with and instead call the physics update routine multiple times per frame if needed (or not at all if your framerate is higher than the physics update rate) Edited by SimonForsman

##### Share on other sites

It works perfectly, at least on paper. Has anyone else ever used an approach like this? Or is there a better way to do it?

It's the correct way of doing it... You are essentially multiplying with (1-friction) every time step so over multiple time steps the "correction" is (1-friction)^n and not [s]n*(1-friction)[/s] (1-n*friction) as you would get with the first version when increasing the timestep n times.

Edit: n*(1-friction) would be totally off Edited by japro

##### Share on other sites

what do schedulers have to do with a fixed timestep ?

Say for example your physics engine runs at 50Hz, so 0.02s between executing physics. Due to the nature of a multitasking OS it won't be precisely 0.02s every time. One time it might be 0.018, another time 0.023. The difference may not be visible... or it may. Depending upon the nature of the physics and the speed of the objects involved. Also ignoring varying delta would be bad if there was a requirement for repeatability, such as in MMO games.

Using some game platforms the timing variation may be minimal, but some systems that I've tinkered with can have variations of up to 20%.

##### Share on other sites

[quote name='SimonForsman' timestamp='1335678100' post='4935764']
what do schedulers have to do with a fixed timestep ?

Say for example your physics engine runs at 50Hz, so 0.02s between executing physics. Due to the nature of a multitasking OS it won't be precisely 0.02s every time. One time it might be 0.018, another time 0.023. The difference may not be visible... or it may. Depending upon the nature of the physics and the speed of the objects involved. Also ignoring varying delta would be bad if there was a requirement for repeatability, such as in MMO games.

Using some game platforms the timing variation may be minimal, but some systems that I've tinkered with can have variations of up to 20%.
[/quote]

When you use a fixed timestep the delta is constant, you don't pass the actual elapsed time to the physics subsystem. (if you run the physics at 50hz with a fixed timestep you always pass 0.02 as the delta, if the elapsed time is 0.023 you still pass 0.02 as the delta and carry the 0.003 you have left (so the next update triggers after an additional 0.017s have passed), Therefore the scheduler has no impact on the simulation. (You can even run the simulation without measuring the actual elapsed time if the result doesn't have to be displayed in realtime (if you're making a movie for example))

If you need to compensate for a variable delta then you're not using a fixed timestep, you're using a variable timestep. Edited by SimonForsman

##### Share on other sites

Say for example your physics engine runs at 50Hz, so 0.02s between executing physics. Due to the nature of a multitasking OS it won't be precisely 0.02s every time. One time it might be 0.018, another time 0.023. The difference may not be visible... or it may. Depending upon the nature of the physics and the speed of the objects involved. Also ignoring varying delta would be bad if there was a requirement for repeatability, such as in MMO games.

Using some game platforms the timing variation may be minimal, but some systems that I've tinkered with can have variations of up to 20%.

Pseudo-code for which the scheduler doesn't matter:
 float timestep = 1.0f / 30.0f; // 30 updates per second Clock clock; clock.start(); while (runMainLoop) { if (clock.time() >= timestep) { clock.reset(); updateGame(timestep); // use the *fixed* timestep } renderGame(); } 

##### Share on other sites
@Cornstalks: Very true. I wonder whether it might appear inconsistent or stuttery to a player when physics performed is constant but the real-time that it occurs in is not constant, but I really have no proof either way.

##### Share on other sites

@Cornstalks: Very true. I wonder whether it might appear inconsistent or stuttery to a player when physics performed is constant but the real-time that it occurs in is not constant, but I really have no proof either way.

True. In a well done game, the rendering is often interpolated. So you don't just naively call renderGame(), but you give it the system time as well and it interpolates the rendering between the current system time and the game time.

1. 1
2. 2
Rutin
22
3. 3
4. 4
JoeJ
16
5. 5

• 14
• 29
• 13
• 11
• 11
• ### Forum Statistics

• Total Topics
631775
• Total Posts
3002284
×