From b8969cde39c1866a621eba9f9d97bc3af7d7408c Mon Sep 17 00:00:00 2001 From: CuriouslyCurious Date: Mon, 15 Dec 2025 17:54:36 +0100 Subject: [PATCH] Add sleep to game loop This should ensure that the program does not hog up an entire CPU core just to get the current time. --- client/src/main/java/rt4/GameShell.java | 11 ++++++++++- client/src/main/java/rt4/ThreadUtils.java | 5 +++++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/client/src/main/java/rt4/GameShell.java b/client/src/main/java/rt4/GameShell.java index 80a799d..a28f006 100644 --- a/client/src/main/java/rt4/GameShell.java +++ b/client/src/main/java/rt4/GameShell.java @@ -613,6 +613,7 @@ public abstract class GameShell extends Applet implements Runnable, FocusListene long lastUpdateTime = 0; long lastDrawTime = 0; + long nextUpdate = 0; while (killTime == 0L) { if (GameShell.killTime > MonotonicClock.currentTimeMillis()) { break; @@ -621,6 +622,14 @@ public abstract class GameShell extends Applet implements Runnable, FocusListene long currentTime = System.nanoTime(); updateDelta = currentTime - lastUpdateTime; + renderDelta = currentTime - lastDrawTime; + + nextUpdate = Math.min(FIXED_UPDATE_RATE_NS - updateDelta, VARIABLE_RENDER_RATE_NS - renderDelta); + // Convert from ns to ms + nextUpdate /= 1_000_000; + ThreadUtils.sleep(nextUpdate); + + // Game update if (updateDelta >= FIXED_UPDATE_RATE_NS) { logicCycles = timer.count(minimumDelay, (int) FIXED_UPDATE_RATE); for (int cycle = 0; cycle < logicCycles; ++cycle) { @@ -630,7 +639,7 @@ public abstract class GameShell extends Applet implements Runnable, FocusListene flush(signLink, canvas); } - renderDelta = currentTime - lastDrawTime; + // Render update if (renderDelta >= VARIABLE_RENDER_RATE_NS) { this.mainInputLoop(); this.mainRedrawWrapper(); diff --git a/client/src/main/java/rt4/ThreadUtils.java b/client/src/main/java/rt4/ThreadUtils.java index ae4c3cf..3fe9905 100644 --- a/client/src/main/java/rt4/ThreadUtils.java +++ b/client/src/main/java/rt4/ThreadUtils.java @@ -5,6 +5,11 @@ import org.openrs2.deob.annotation.OriginalMember; import org.openrs2.deob.annotation.Pc; public class ThreadUtils { + /** + * Sleeps the current thread for a set amount of milliseconds. + * + * @param arg0. Time in milliseconds to sleep for. + */ @OriginalMember(owner = "client!sk", name = "a", descriptor = "(JI)V") public static void sleep(@OriginalArg(0) long arg0) { if (arg0 <= 0L) {