1
\$\begingroup\$

ns is 1000000000 / amountOfTicks;

    long now = System.nanoTime();
    delta += (now - lastTime) / ns;
    lastTime = now;

    if (delta >= 1) { 
        tick(glad);
        updates++;
        delta--;
        fps_counter = 0;
    }

    if (delta >= fps_counter / FramesPerTick) { // render
        fps_counter++;
        frames++;
        render(glad);
    }

    if (System.currentTimeMillis() - timer > 1000) {
        timer += 1000;
        frame.setTitle("Ticks: " + updates + " Fps: " + frames);
        updates = 0;
        frames = 0;
    }

So if i have 20 ticks and 3 FramesPerTick i get 60fps it checks whenever delta is bigger than 1/3, 2/3 and 3/3, so every tick has 3 frames

Everything is jittery, movement, mouse look. Animation gets more and more jittery the lower the FPS, i dont understand why.

Also when i take the render(glad) method out of the if, it goes up to 400 fps and runs very smoothly.

EDIT: If i put Thread.sleep(13) instead of if (delta>=fpscounter/FramesPerTick){} i get around 60 fps and smooth animations.

\$\endgroup\$
2
  • \$\begingroup\$ Sounds like you've got vertical synchronization enabled and at the same time try to control your rendered framerate yourself. What happens if you set the condition of the render if() to true? \$\endgroup\$
    – Mario
    Jul 20, 2014 at 19:49
  • \$\begingroup\$ @Mario if its true then ill use the full potential of the CPU producing 400-500 fps. \$\endgroup\$
    – Stef
    Jul 20, 2014 at 22:57

1 Answer 1

3
\$\begingroup\$

Ah! I missed the obvious reason for the odd behavior while first looking at your code (I think). Essentially, there are three potential problems here:

First: Missing Updates

Each and every iteration you'll update your game logic only once (or not at all). In a similar way, you draw your screen (or skip drawing).

However, this causes one problem:

  • Let's assume you'd like to update the game 100 times per second (makes it easier to explain/compare).
  • This means there are 10 ms between updates.
  • As long as each and every iteration is faster than 10 ms, you won't notice any problem.
  • Now assume there's some stuttering for a moment (don't know, let's say you connected some device or whatever).
  • This iteration, 25 ms have passed. This means that you'd have to do two updates before rendering again, i.e. update(); update(); render();.
  • Due to your design, you won't do this. Instead you'll get update(); render(); update(); render();.
  • This might cause visual/noticeable stuttering (especially if we're talking about more than just two updates!) since the game now obviously lags a bit (till you've cleared your update backlog; assuming you're able to do so).
  • This also means you're essentially connecting your logic updates to the framerate. If you can't render at the intentional framerate, your game logic will slow down as well.

Second: Race Conditions

This is something you can't really avoid if you'd like to do fixed timesteps:

  • Let's assume you're rendering 60 times per second and updating 30 times per second.
  • Theoretically, this should trigger one call to update() for every second call to render().
  • However, this is essentially just an average number.
  • It's possible, that between two frames you miss your update since you're like 5 ns too fast.
  • Rather than calling update(); render(); render(); update(); render(); render(); you'd at once call update(), render(); render(); render(); update(); render();. Overall you're still at 60/30 fps, but your timing is still off a bit (especially if you've got vertical sync enabled).
  • This can cause minor inconsistencies that might become noticeable, especially when things on screen are moving quite fast.
  • Fix Your Timestep! elaborates a bit more and also provides a solution to this.

Third: Rounding/Precision Issues

While I can't say this for sure, you might be running into precision issues with your variables.

If delta is some floating point variable (due to the / ns step?), you might run into rounding issues here.

Also System.nanoTime() doesn't necessarily return a very precise time value - it's implementation dependent. It could be in nanoseconds, but it could as well just return whole milliseconds or even less (could also depend on the system's energy saving settings):

This method provides nanosecond precision, but not necessarily nanosecond resolution (that is, how frequently the value changes) - no guarantees are made except that the resolution is at least as good as that of currentTimeMillis().

Depending on your actual number of frames/updates this might be neglectable though. (And there isn't really anything you can do about this, other than trying to pick sane numbers/scaling that will work for you.)

\$\endgroup\$
1
  • \$\begingroup\$ First of all thank you for your comprehensive answer, you explained things very good. 1) I dont think rendering would be too slow because i get 400 FPS means 2,5ms for a frame. 2) On the other hand (if i understood corectly) i think this is the problem since i get free time after the frames and instead of calling Render() again i wait for Update(). This explains when i use Thread.sleep(13) working smoothly. \$\endgroup\$
    – Stef
    Jul 21, 2014 at 23:29

You must log in to answer this question.

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