Most of my demos have the standard do nothing fixed timestep, if the framerate slows, the game slows to potentially slow motion.
I’m implementing a variable timestep, as with any time attack based game (like a fastest lap on a racing game etc) it’s essential to allow a user running at say 30fps to potentially achieve the same lap time or faster as a user running at the target 60fps.
It seems incredibly easy, simply muliply your acceleration or velocity by the timestep, and bob’s your uncle.
However it’s not that simple, especially when factoring in gravity and friction.
Proof that it isn’t that trivial, is even Carmack himself didn’t correctly implement a variable timestep in Quake 3, as apparently you have significantly different jumping capabilities according to the framerate in Quake 3.
To preface, I don’t need pinpoint accuracy as I’m not building physics simulations, I just need the system to be accurate enough that a car is going to accelerate and slow down at the same rate whether it’s 30fps or 60fps (or to put it another way, the car needs to accelerate twice as fast per frame and slow down twice as much per frame as it does at 60fps).
I’m currently applying all the forces to a velocity vector - acceleration, gravity, and friction.
This gets multiplied by the timestep, which becomes the displacement to add to the object’s position.
I did try the more correct method of averaging the timestep per frame like this, position += (newVelocity + velocity)/2 * ts;
However I can’t get it working correctly with the collision response, so I’m sticking with just multiplying the velocity by the timestep.
It sort of works fine. whether at 15fps or 60fps the user can move through the world at the same speed, well the user reaches the same top speed, travelling the same distance per second.
However, acceleration is not at the same speed, and this is due to friction/damping, which is my main question.
Do any of you have experience of applying damping to a vehicle with a variable timestep?
Using a basic static friction variable like 0.95 (ie vel *= 0.95) results in far LESS friction at lower framerates, as the top speed is the same, but the simulation is basically sped up at higher rates. So the higher the framerate, the faster you speed up/slow down.
I developed a Verlet physics engine with angled constraints in AS2, and for the friction I just did frictionValue ^ timeStep, which seemed to work fine at the time, producing more or less the same results at 60/30 frames a second.
To save a Math.pow() call, this can be translated to fric = 1-(frictionValue * ts); where a frictionValue of 3 translates to a 0.95 multiplication at 60fps.
Using this friction value as a damping force however, restricts the displacement per frame to be the same regardless of the timestep. Which obviously results in moving at half the speed at 30fps and twice the speed at 120fps (actually the displacement is slightly less than half at 30fps, and slightly more than double at 120fps, but close enough).
What this basic variable timestep friction does however is slow the car down at the same rate, regardless of framerate, if no other forces are being applied. So if you’re travelling at a certain velocity per second, it’ll bring the vehicle to a halt in say, 5 seconds for example, regardless of framerate.
This is fine, but what I want is a damping force to be applied to the velocity vector whilst accelerating serving as a method of limiting acceleration and the overall top speed, and I have no experience of this beyond that basic hacky friction.
I tried multiplying acceleration by the timestep twice, in conjunction with the above friction method, and this comes close to the desired effect, but you lose power the lower the framerate. At 60fps the max velocity is 16, at 30fps it’s 30, and at 15fps it’s 50. When obviously it should be 16/32/64.
So for those with experience of physics with a variable timestep - how can I apply say drag and surface friction (or an approximation of both) with a variable timestep?
Excuse the ramblyness of the post
Cheers,
RumbleSushi.