This is how I handle the game loop:

while (running) {
    diff = duration_cast<milliseconds>(end - start).count();
    start = clock::now();

    dt = diff / (16.0);

    handleInput(); // get input
    update(dt); // game logic
    render(); // render game

    SDL_GL_SwapWindow(window); // swap frame buffer

    end = clock::now();

It is intended to be a fixed timestep game locked to 60FPS (it's a re-made emulation of an SNES game) however it runs on 144 timestep on my 144hz screen, making it far too fast. Vsync can't solve this, so what can?

Question author Accumulator | Source



Here is a quick example of how game loop can be implemented:

int32_t tickInteval = 1000/FPS; // frequency in Hz to period in ms
uint32_t lastUpdateTime = 0;
int32_t deltaTime = 0;
while (running) { // running condition
    uint32_t currentTime = SDL_GetTicks();
    deltaTime = currentTime - lastUpdateTime;

    int32_t timeToSleep = tickInteval - deltaTime;
    if(timeToSleep > 0)
        SDL_Delay(timeToSleep); // energy saving

    update(deltaTime); // game logic
    lastUpdateTime = currentTime;

I would recommend to look close on this topic.

One might be concerned with uint32_t overflow. And yes it will overflow. After almost two months of uninterrupted run of the game (49.7 days to be precise). What will happen then? currentTime will be a very small positive integer, lastUpdateTime will be a very large positive integer. But the subtraction of two will not overflow no matter what. Moreover if the difference does not fit into int32_t it will be wrapped around modulo of UINT_MAX + 1 resulting in a small positive integer that will be the exact number of ticks these two values different (with regard to unsigned overflow of one).

Answer author Teivaz

Ask about this question here!