Skip to content

Commit

Permalink
perf: stabilize frame rate when maxFps set
Browse files Browse the repository at this point in the history
Allows a small variation in the minDt to avoid always overshooting due to floating point inaccuracies.
  • Loading branch information
adil192 committed Sep 14, 2024
1 parent 8adac1f commit 94e6bb5
Showing 1 changed file with 19 additions and 6 deletions.
25 changes: 19 additions & 6 deletions lib/flame/ricochlime_game.dart
Original file line number Diff line number Diff line change
Expand Up @@ -320,23 +320,36 @@ class RicochlimeGame extends Forge2DGame
/// this is used to sum up the dt values
/// and only update the game when the sum is greater than 1/30.
double groupedUpdateDt = 0;
static const maxDt = 0.5;

@override
// ignore: must_call_super (super.update is called in [updateNow])
void update(double dt) {
const maxDt = 0.5;
if (dt > maxDt) {
onResume(dt);
groupedUpdateDt = 0;
// physics engine can't handle such a big dt, so just skip this frame
return;
}

groupedUpdateDt += dt;
final minDt = 1 / Prefs.maxFps.value;
if (groupedUpdateDt < minDt) return;
if (Prefs.maxFps.value <= 0) {
// unlimited fps, don't group updates
updateNow(dt, timeDilation.value);
return;
}

dt = min(groupedUpdateDt * timeDilation.value, maxDt);
groupedUpdateDt = 0;
final targetDt = 1 / Prefs.maxFps.value;

groupedUpdateDt += dt;
// *0.9 so e.g. 16ms is treated like 16.6666...ms
if (groupedUpdateDt < targetDt * 0.9) return;
updateNow(groupedUpdateDt, timeDilation.value);
// may go below 0 to compensate for rounding errors
groupedUpdateDt -= targetDt;
}

void updateNow(double dt, double timeDilation) {
dt = min(dt * timeDilation, maxDt);
ticker.tick(dt);
super.update(dt);
}
Expand Down

0 comments on commit 94e6bb5

Please sign in to comment.