Yet another stuttering problem

Hi community!

Little help needed.

I have a problem with stuttering, manly because I’m using fixed time step or a least trying :)!
I think that the problem for the stuttering is because I’m missing frames when inside the while cycle, how should I fixed the code so that when I render my assets they will keep up and do not “jump” movement steps?

Wheres the little peace of code I’m using :



    private float fixedTimestepAccumulator = 0f;
    private final float MAX_ACCUMULATED_TIME = 1.0f;
    private final float TIMESTEP = 1/60f;

    @Override
    public void render(float deltaTime) {
        Gdx.gl.glClearColor(172f / 255f, 229f / 254f, 254f / 255f, 1f);
        Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
        
        levelController.handleInputGame(deltaTime);
        
        fixedTimestepAccumulator += deltaTime;
        if (fixedTimestepAccumulator > MAX_ACCUMULATED_TIME)
            fixedTimestepAccumulator = MAX_ACCUMULATED_TIME;
        while (fixedTimestepAccumulator >= TIMESTEP) {
            levelController.update(deltaTime);
            fixedTimestepAccumulator -= TIMESTEP;
        }
        
        levelRenderer.render();
        fpsLogger.log();
    }

Thank you all!

This problem is fairly common, especially in multiplayer games where the tickrate is much slower than the framerate (take Team Fortress 2, for instance where the default tickrate is 20, and the normal framerate 30-60).

The solution to this is interpolating your visual position between frames. When you update your positions, you can update the actual ones, but interpolate a “visual” position which only exists for where the sprite should be drawn.

If your tickrate is 20 ticks per second, and you’re assuming the framerate will be at around 60, you’ll have to interpolate between the old and the new position in thirds (because there are 3 frames until the next update is executed).

unrelated issue



    private float fixedTimestepAccumulator = 0f;
    private final float MAX_ACCUMULATED_TIME = 1.0f;
    private final float TIMESTEP = 1/60f;

    @Override
    public void render(float deltaTime) {
        Gdx.gl.glClearColor(172f / 255f, 229f / 254f, 254f / 255f, 1f);
        Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
        
        levelController.handleInputGame(deltaTime);
        
        fixedTimestepAccumulator += deltaTime;
        if (fixedTimestepAccumulator > MAX_ACCUMULATED_TIME)
            fixedTimestepAccumulator = MAX_ACCUMULATED_TIME;
        while (fixedTimestepAccumulator >= TIMESTEP) {
-           levelController.update(deltaTime);
+           levelController.update(TIMESTEP);
            fixedTimestepAccumulator -= TIMESTEP;
        }
        
        levelRenderer.render();
        fpsLogger.log();
    }

Thanks, already try it, but same result!
Although not sure on who to implement what chrislo27 sugested, I think that’s the right path…

Thanks, I understand your explanation, going to try to implement it… Huh

Thanks a lot.

i spot two things.

how do you compute the delta time ? if you’re not averaging it may stutter.

the loop [icode]while(fixedTimestepAccumulator >= TIMESTEP)[/icode] computes [icode]fixedTimestepAccumulator < 0.0[/icode] which needs special care. interpolating back to previous state by abs(fraction spilled) / TIMESTEP i guess.

o/

Hi,

Yes it’s true it computes if fixedTimestepAccumulator < 0.0 , but with that code it’s impossible for fixedTimestepAccumulator to be less than 0, right?

yes, you get the idea. fixedTimestepAccumulator will not become < 0.0 but rather [icode]< TIMESTEP[/icode] and then exit the loop. thats still the fraction which needs special care. after the while loop, something like : [icode]interpolate( lastControllerState, levelController.update(TIMESTEP), fixedTimestepAccumulator / TIMESTEP)[/icode]

in your render loop you carry the fraction to the next frame which is a good idea. you should have a stable simulation going on. it is causing a bit of visual stuttering since the levelController time is not synchronised with renderer/frame time.