2
\$\begingroup\$

I'm trying to figure out if I'm approaching my simple fixed-timestep implementation correctly, following examples such as: Gaffer (without RK4), and DeWitters

Currently, I have a game object which contains position and velocity data members, with position calculated by

 position = position + (velocity * dt)

However, unless the velocity is set to a value of two decimal places, the update makes the position change in an instant (e.g. Velocity = 0.05 works, but this does not seem logical; to me Velocity should be >0?; even a value of 0.5 makes the update appear instant). Therefore, I have come to the conclusion that I have implemented by game loop incorrectly.

Note, I'm using SDL and C++, however the following is all Psuedocode:

bool quit = false;
World world;

Uint32 frameTime = SDL_GetTicks();
double accumulator = 0.0;
const double dt = 1.0 / 60.0;
int fCount = 0;
while(!quit){
    fCount = 0;
    double newTime = SDL_GetTicks();
    double nextFrameTime = newTime - frameTime;

    if(nextFrameTime > 0.25)
        nextFrameTime = 0.25;

    frameTime = nextFrameTime;  //Line of error, should be frameTime = newTime
    accumulator += nextFrameTime;

    while(accumulator >= dt){
        world.Update(dt);  //A simple counter revealed Update being called 15-16 times during this loop
        accumulator -= dt;
        fCount++;
    }
    //fCount is equal to 15 when dt = 1.0/ 60.0, fCount = 8/9 when dt = 1.0/30.0
    double interpol = accumulator / dt;
    world.Render(interpol);
}

If there isn't any apparent issue with this code then perhaps I have messed up my position/physics calculations based on Update(dt).

Any help is appreciated

\$\endgroup\$

1 Answer 1

3
\$\begingroup\$

I assume GetTicks() is standard SDL. In which case when I look at the documentation is says "Get the number of milliseconds since the SDL library initialization." However all your calculations seems to be in seconds. So if you treat the output from GetTicks() as being seconds you are gonna effectively be running 1000 times faster. Or you would if it weren't for this line if(nextFrameTime > 0.25).

So you either have to change all your other calculations to be in milliseconds, e.g. dt = 1000.0 / 60.0;, or convert the output from GetTicks() to seconds by dividing it by 1000. That way all numbers related to time will be in the same unit and can be directly compared, added and subtracted easily.

Also this line frameTime = nextFrameTime; should be changed to this frameTime = newTime;. frameTime should store the previous frame's start time so you can calculate the elapsed time for the frame from that.

\$\endgroup\$
6
  • \$\begingroup\$ Tried the second way of GetTicks() / 1000, however it did not seem to fix the case though your explanation definitely makes sense so that had to be causing some issue down the line. \$\endgroup\$
    – sl133
    Dec 20, 2015 at 21:13
  • \$\begingroup\$ @sl133 Just remember that GetTicks() will return a number of type Uint32. This number divided by 1000, another int, will always produce an int. So you'll never get the fractional part. newTime will always be a whole number of seconds, something you don't want. So you want to promote the number to double before dividing. There is at least two ways to do that, either GetTicks() / 1000.0 or (double) GetTicks() / 1000. If either side is a double the entire operation is promoted to a double. \$\endgroup\$
    – Christer
    Dec 20, 2015 at 21:52
  • \$\begingroup\$ I straight up just changed it from a Uint32 into a double, dividing by 1000.0 however updates are still either too fast or my velocity is being somehow calculated too fast (didn't think it was this but Ill have to dive deeper into what I'm doing to just double check) \$\endgroup\$
    – sl133
    Dec 20, 2015 at 22:01
  • \$\begingroup\$ @sl133 Well if you are still having problems after all of this you could try adding your new code to you question. However even though your velocity might still be wrong, I feel confident this should solve your update method being called 15-16 times every frame. \$\endgroup\$
    – Christer
    Dec 20, 2015 at 22:12
  • \$\begingroup\$ Using a simple counter (see above) to count the number of times Update is being called still reveals 15 Updates() during that loop. It is supposed to be running as many UPS as possible while rending at a solid framerate, my PC is most likely dictating this 15 counter via its own performance? \$\endgroup\$
    – sl133
    Dec 20, 2015 at 22:18

You must log in to answer this question.

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