avatar

Timestep

At some point every game designer will find that their game is behaving differently on multiple machines. Usually, this has to do with performance and at how many frames per second each computer can run your game.

Let’s say you have a character that moves 5 pixels to the right whenever you hit the right-key. At 60 frames per second you will cover 300 pixels in one second. But another computer can only run your game at 30 FPS, and thus your character will only travel 150 pixels in one second.

One way to solve this would be to force the framerate to the desired number. However this will not fix the problem for those who can’t reach that framerate. We want a more universal solution: Timestep. The basic idea of timestep is that every speed and timing is not per frame but per second. Frames per second are not constant, seconds per second is.

Example

A small example on how timestep affects your movements. Try setting the frames to 60 and 30 with and without timestep and watch the different times.

[kml_flashembed publishmethod=“static“ fversion=“10.0.0″ movie=“http://www.klonk-games.de/wp-content/uploads/2012/07/timestep.swf“ width=“400″ height=“150″ targetclass=“flashmovie“ play=“true“ loop=“false“ quality=“high“]

Get Adobe Flash player

[/kml_flashembed]

Timestep can be turned on/off, FPS can be changed with the +/- and the square starts moving once you hit the play-button. It should always travel the distance in 1000ms. Without timestep, it will only do so at 60 FPS, with timestep there will be small variations in the timing, but bear in mind, 20ms are 0.02 seconds.

Implementation

For this example, I’ll use Actionscript 3, but the principle can be used for every language. Unity3D, for example, has a preset timestep variable called Time.deltaTime.

To create a timestep variable, we have to calculate the time between the current and the last frame. Since this is a very short timespan, we’ll use milliseconds. Actionscript 3 has a handy function that returns the time the program has been running in milliseconds, called getTimer(). So when the program has run for 7 seconds, it will return 7500.

Now we need to calculate the difference between two frames. So at every frame we save how long the program has been running and subtract that number in the next frame from how long it has been running then. At 60 FPS this will usually be around 16ms. All we need to do now is make this a factor for seconds. We do that by dividing it by 1000.

Code   
  1. var timestep:Number = (getTimer() - lastFrame) / 1000;
  2. lastFrame = getTimer();

This would be inside your ENTER_FRAME event (or whatever you are using for every frame).

The variable timestep can now be used to multiply your speeds. In the above example, we want to move 300 pixels per second.
300 * 0.0166 = 4.98 pixel per frame
0.0166 seconds are the average for 60 FPS. The amount to move would be 4.98 pixels in order to travel 300 pixels in one second at the current framerate. 4.98 * 60 = 298.8, close enough, since the multiplier was only an average.
300 *  0.033 = 9.9 pixel per frame
0.033 seconds are the average for 30 FPS.  9.9 * 30 = 297, again close enough.

Of course the framerate often varies while running, but since we recalculate the timestep every frame, we get an accurate multiplier.

This entry was posted in Code, Devblog and tagged , . Bookmark the permalink.