I do remember the jank encountered in previous attempts, but I think it might be possible to avoid that. Dt seems to vary a bit per frame. At 60fps it should be 0.0166 but I've seen it lower to around 0.0163 in my tests as an example. My idea is we can skip frames if dt is less than some target framerate, but instead of checking if dt<1/30, we let it be approximate with say dt<0.3. I coded up a complete test to check my idea and on my 60hz screen I was able to get this. Super janky with dt<1/30, but smooth with an approximate value for 1/30 like dt<0.03.
It gives the high and low dt, the average dt of the last 128 drawn frames, and a little graph of the dt times for the drawn frames.
And here's the relevant animation loop. The only remarkable part is the frame skip.
let prevTime=0;
function gameLoop(newTime)
{
requestAnimationFrame(gameLoop);
newTime/=1000;
let dt = Math.min(0.05, newTime-prevTime); //20fps min to account for tabbing away
if (dt<0.3) // skip frame if dt isn't at least approximately 1/30.
return;
prevTime=newTime;
tick(dt);
draw();
}
requestAnimationFrame(gameLoop);
It should work the same when cpu/gpu load causes frames to be skipped. The only thing that would need testing is how it would behave with other screens with higher refresh rates. Anyways, just an idea.
Edit:
0.3 is fairly arbitrary as a lower value than 1/30. dt<1/maxFPS-1/480 may work better, at least should work for refresh rates up to 240.
dt<1/30-1/480
Thank you! So I'm not going to complicate myself with this, I'm going to use the dt to make it work well regardless of the frames, just like many people use 60hz on their phones to save battery, I also think this is just a trick and doesn't really limit the fps, (correct me if I'm wrong) anyway thank you very much for taking the time to try this