games: fix timing drift with cumulative nextTick, 30fps render, 90 pps base

Root cause of unstable speed: nextTick was reset to 'now + speed' each step,
accumulating timing drift. Now uses 'nextTick += speed' with a floor (if
nextTick < now, reset to now) to prevent drift and catch-up spirals.

- Both games: 30 fps render cap (FRAME_MS = 33 ms), nextTick updated
  cumulatively to eliminate drift.
- Snake: base speed 90 px/sec (~100 ms per step at cell=9), turn queue
  unchanged, edge wrap unchanged.
- Tetris: gravity step uses cumulative nextTick, controls unchanged.
This commit is contained in:
Luxferre
2026-10-24 09:44:24 +03:00
parent 1d1c4524de
commit 52ac64e9b3
6 changed files with 8 additions and 5 deletions
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+5 -3
View File
@@ -228,7 +228,8 @@ static void step() {
update_speed();
place_food();
}
nextTick = now_ms() + speed;
if (nextTick < now_ms()) nextTick = now_ms();
nextTick += speed;
}
static void draw_text(int x, int y, int scale, unsigned long col, const char* s) {
@@ -407,7 +408,7 @@ int main() {
render();
int xfd = ConnectionNumber(dpy);
const unsigned long FRAME_MS = 1000 / 60; // 60 fps rendering
const unsigned long FRAME_MS = 1000 / 30; // 30 fps rendering
unsigned long frameStart = now_ms();
while (running) {
@@ -425,7 +426,8 @@ int main() {
// Game logic step at its own rate
if (now >= nextTick) {
if (state == PLAYING) step();
nextTick = now + (state == PLAYING ? speed : 80);
if (nextTick < now) nextTick = now;
nextTick += (state == PLAYING ? speed : 80);
}
// Render every frame
+3 -2
View File
@@ -520,7 +520,7 @@ int main() {
render();
int xfd = ConnectionNumber(dpy);
const unsigned long FRAME_MS = 1000 / 60; // 60 fps rendering
const unsigned long FRAME_MS = 1000 / 30; // 30 fps rendering
unsigned long frameStart = now_ms();
while (running) {
@@ -538,7 +538,8 @@ int main() {
// Game logic step at its own rate
if (now >= nextTick) {
if (state == PLAYING) step();
nextTick = now + (state == PLAYING ? speed : 80);
if (nextTick < now) nextTick = now;
nextTick += (state == PLAYING ? speed : 80);
}
// Render every frame