1
\$\begingroup\$

I want to be able to change the game speed, to speed up or slow down all animations and gameplay. Ideally, this could also be set to a negative number to make everything go backwards.

I tried this:

I made everything dependent on a time variable, updated every frame from the OS time:

void calledEveryFrame()
{
    time = System.accurateTime();
}

Then I tried just scaling that time.

lastTime = time;
long now = System.accurateTime();
double diff = now - lastTime;       
time = (lastTime + diff * speed);

That obviously doesn't work, because you can't just multiply the speed times the difference because it is not called exactly regularly.

How do I do this correctly?

\$\endgroup\$

2 Answers 2

1
\$\begingroup\$

Some points:

  1. You should make all your movements time-dependent, more specifically depending on the timeSinceLastFrame. That way, your game will run equally fast on all computers in the sense that the possible movement distances are aligned (not in the sense that you get the same FPS, because that of course depends on the hardware specs).

    So, your movements would look something like this:

    newPosition = oldPosition * direction * speed * timeSinceLastFrame;

    To now slow down the whole application, you can just decrease timeSinceLastFrame by a certain factor, resulting in slower movements of your objects.

    // At startup
    long lastTime = 0;
    long now = 0;
    long timesinceLastFrame = 0;
    
    // Each game loop run
    now = System.accurateTime(); // get new time
    timeSinceLastFrame = now - lastTime; // calculated time passed since the last frame, e. g. in milliseconds      
    timeSinceLastFrame *= 0.5; // to get the game to half speed
    lastTime = now; // update the value for the next loop run
    
  2. Backtracing in a game is difficult, because in order to do so, you need to store all user input to be able to un-do that in the correct reverse order. And this also only works if the rest of your application is completely deterministic which it is not when being based on variable (= un-deterministic since dependent on something as uncontrollable as the overall system performance at any given point in time) timestamps.

A good general overview about the discussion: fixed timestamp vs. variable timestamp (variable not in your sense that you can slow down or speed up the game, but in the sense that the time between frames is not constant), can be found in this GameDev.SE thread. Another important source is this blog entry by Glen Fielder.

\$\endgroup\$
5
  • \$\begingroup\$ thanks, but actually i have heard that you should not use the timeSinceLastFrame, because of numerical errors which will add up. instead one should always use the timeSinceStart. \$\endgroup\$
    – clamp
    Commented Sep 2, 2014 at 8:53
  • \$\begingroup\$ Do you have any source for that? One thing I am aware of is that "clamping" your deltas/timeSinceLastFrame in some bounds can sometimes be advised as explained here. \$\endgroup\$ Commented Sep 2, 2014 at 8:58
  • 1
    \$\begingroup\$ @clamp are you sure it is not the other way around? The timeSinceStart adds up. timeSinceLastFrame does not. \$\endgroup\$
    – wondra
    Commented Sep 2, 2014 at 10:28
  • \$\begingroup\$ @Phillip, determinism is lost among other things when the simulation is infected with stuff like how long it takes the hardware to process something. This is how you do it properly: gafferongames.com/game-physics/fix-your-timestep \$\endgroup\$
    – Steven Lu
    Commented Sep 2, 2014 at 14:42
  • \$\begingroup\$ @StevenLu: True. I updated my answer to make that point clear. Glen Fielder's blog post was already linked indirectly via the mention of the timestamp GameDev.SE thread, but I now also added it explicitly. \$\endgroup\$ Commented Sep 2, 2014 at 14:50
0
\$\begingroup\$

In most rendering applications this is called Delta time, or the time since the last frame update. For example, in most of my applicaitons I have a master loop that looks like this:

while(running){
    updateDelta();
    update(delta);
    render(delta);
}

with the functions:

void updateDelta() {
    long currentTime = (Sys.getTime() * 1000 / Sys.getTimerResolution());
    delta = (int) (currentTime - LAST_FRAME);
    LAST_FRAME = (Sys.getTime() * 1000 / Sys.getTimerResolution());
}

void update(float delta){
    ...
}

void render(float delta){
    ...
}

If you start of with this format, your application will:

  • Always run at the same speed independent of system performance

  • Be able to change the update speed(delta).

\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .