I've been trying to create a deterministic, fixed gameloop.
The game loop should run TICK_RATE # of physics updates per second, and then render as quickly as possible (didn't do interpolation yet).
The issue I'm currently having is that the # of physics updates per second isn't constant. I want it to be the same as TICK_RATE, but it constantly changes by 1.
E.g. the tick-rate varies from 60-61 if TICKRATE = 60.
I thought this issue might be due to rounding issues, but manually calculating the delta time with System.nanoTime() and storing everything as a double gives me the same problem. If the physics simulation constantly varies by 1 frame per second, it's not longer deterministic, which I think would be hard to replicate (for networking and replays for example).
Any ideas on how to fix this so the number of physics updates per second is constant?
import com.badlogic.gdx.ApplicationAdapter
import com.badlogic.gdx.Gdx
private const val TICK_RATE = 60 //Number of updates per second
private const val TIME_STEP = 1f / TICK_RATE //Seconds per tick
private const val MAX_FRAME_SKIP = (TICK_RATE * .2).toInt() //If fps drops below 20% of tickrate, slow down game to
//avoid spiral of death
class FixedTimestep : ApplicationAdapter() {
private var accumulator = 0f
//variables for ticks per second tracking
private var tps = 0
private var previousNanoTime = System.nanoTime()
override fun render() {
var frameSkipCount = 0
val delta = Gdx.graphics.rawDeltaTime
accumulator += delta
while (accumulator > TIME_STEP && frameSkipCount < MAX_FRAME_SKIP) {
accumulator -= TIME_STEP
//do physics step
//display tps to console every second
tps++
val currentNanoTime = System.nanoTime()
if (currentNanoTime - previousNanoTime >= 1000000000L) {
println(tps)
tps = 0
previousNanoTime = currentNanoTime
}
}
//render
}
}
accumulator >= TIME_STEP
instead ofaccumulator > TIME_STEP
? \$\endgroup\$