Jump to content

View more

Image of the Day

WIP title screen for #DeathOfAPartisan #screenshotsaturday #gamedev https://t.co/qJNhfZCvd4
IOTD | Top Screenshots

The latest, straight to your Inbox.

Subscribe to GameDev.net Direct to receive the latest updates and exclusive content.

Sign up now

Timestep/game loop explanations needed

4: Adsense

Old topic!

Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

  • You cannot reply to this topic
1 reply to this topic

#1 Predator034   Members   


Posted 05 February 2013 - 04:42 PM

Hi there, I need some help with my game's timestep. And yes, I've read over the infamous and all-too reposted gaffer article: gafferongames.com/game-physics/fix-your-timestep/



Basically my current game loop code is broken and passes a deltatime through each update(elapsedTime) method. Then movements are multiplied based on that value, of course.


My game does need to be networked, but I'm hoping that such a thing doesn't change much, (essentially I'll just have the clients act as dumb input terminals and the server will tell everyone the state, it's only for a small number of players so it should be fine and as such will be authoritative).


The parts I do not understand about *this* solution, is how the State struct fits into all of this. Why is it only 1 dimensional? Do I add y (it's a 2d game) as well in a same similar manner, along with vy to make this usable for 2d?



Why is it interpolating the rendering itself and not collision and such?


If I have a world->update() call which updates all the entities and checks collision on them..what do I pass to them and how do I use this in a similar manner as I was doing?


I don't see how just interpolating the rendering would result in something usable?


Where do I place the input collection code and the update (collision/physics etc.) code, as well as networking. Especially since I have a handleEvents() { while (SDL_PollEvent(&event)) {.. }.. } Can I just place all of these in one area? Where, exactly, in the main loop?


I've scoured the internet and unfortunately have yet to find a *real* example that uses a fixed time step



  I'm posting the code below so that it's easy to talk about as I need to understand it, and a lot of it I do not, and so people can hopefully walk me through the parts I'm confused on.


Thanks, really hoping someone here can help me understand and use this code. Game loops seem to be an area where from a distance they seem obvious and simple/straight forward, but of course, that is not the case at all.


struct State
    float x;
    float v;

struct Derivative
    float dx;
    float dv;

State interpolate(const State &previous, const State &current, float alpha)
    State state;
    state.x = current.x*alpha + previous.x*(1-alpha);
    state.v = current.v*alpha + previous.v*(1-alpha);
    return state;

float acceleration(const State &state, float t)
    const float k = 10;
    const float b = 1;
    return - k*state.x - b*state.v;

Derivative evaluate(const State &initial, float t)
    Derivative output;
    output.dx = initial.v;
    output.dv = acceleration(initial, t);
    return output;

Derivative evaluate(const State &initial, float t, float dt, const Derivative &d)
    State state;
    state.x = initial.x + d.dx*dt;
    state.v = initial.v + d.dv*dt;
    Derivative output;
    output.dx = state.v;
    output.dv = acceleration(state, t+dt);
    return output;

void integrate(State &state, float t, float dt)
    Derivative a = evaluate(state, t);
    Derivative b = evaluate(state, t, dt*0.5f, a);
    Derivative c = evaluate(state, t, dt*0.5f, b);
    Derivative d = evaluate(state, t, dt, c);
    const float dxdt = 1.0f/6.0f * (a.dx + 2.0f*(b.dx + c.dx) + d.dx);
    const float dvdt = 1.0f/6.0f * (a.dv + 2.0f*(b.dv + c.dv) + d.dv);
    state.x = state.x + dxdt*dt;
    state.v = state.v + dvdt*dt;

int main()
    const int width = 640;
    const int height = 480;
    if (!openDisplay("Timestep", width, height))
        return 1;

    gluPerspective(45.0, 4.0/3.0, 1, 1000);

    gluLookAt(0,0,150, 0,0,0, 0,1,0);
    glClearColor(0.3f, 0.3f, 0.3f, 1);

    State current;
    current.x = 100;
    current.v = 0;
    State previous = current;

    float t = 0.0f;
    float dt = 0.1f;
    float currentTime = 0.0f;
    float accumulator = 0.0f;
    while (!quit) 
        const float newTime = time();
        float deltaTime = newTime - currentTime;
        currentTime = newTime;
        if (deltaTime>0.25f)
            deltaTime = 0.25f;
        accumulator += deltaTime;
        while (accumulator>=dt)
            accumulator -= dt;
            previous = current;
            integrate(current, t, dt);
            t += dt;
        State state = interpolate(previous, current, accumulator/dt);
        glVertex3f(state.x, 0, 0);
    return 0;


Edited by Predator034, 05 February 2013 - 04:43 PM.

#2 ultramailman   Prime Members   


Posted 05 February 2013 - 07:58 PM

The example uses one dimension in state, but you can add as many dimensions as you need.

Old topic!

Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.