Game Version: 1.16.5
Platform: Windows
Modded: No
SP/MP: Singleplayer
Description
Using the MaxFPS slider at higher settings than 60 (without Vsync since this disables it) locks FPS to ~60.
How to reproduce
Have a Windows PC without HPET enabled
Set MaxFPS above 60
Observe as FPS doesn't actually go higher than 60
Expected behavior
FPS is capped to the MaxFPS setting instead of 60
Screenshots
Before:
After:
Fix
I recently got the game and upon starting a new world and exploring, I noticed my FPS wasn't super smooth. After checking the settings I saw my FPS was capped to 60 even though I had configured it at a max of 100.
After a bit of digging I found out that the game's rendering loop uses Thread.Sleep(num) to limit FPS. On my system however, the minimum amount of time Thread.Sleep sleeps for is ~15-16ms thus restricting the FPS limiter to a max limit of ~60 FPS.
Since using native calls to modify the timer on the OS level seemed dirty and impractical to me, I tried looking for a different solution and here's what I came up with:
double num = (double)ClientSettings.MaxFPS / 1.6;
if (ClientSettings.VsyncMode != 1 && num > 10.0 && num < 150.0)
{
Stopwatch stopwatch = new Stopwatch();
stopwatch.Start();
while (stopwatch.Elapsed.TotalMilliseconds < 1000.0 / num - this.frameStopWatch.Elapsed.TotalMilliseconds)
{
Thread.Sleep(0);
}
}
Since Thread.Sleep(0) is used, this will still yield if other work is available, if not it will loop thus consuming CPU cycles and being a 'busy wait'. Thus this uses slightly more CPU cycles than using just Thread.Sleep, but now I can enjoy a much smoother (and configurable) experience.
PS: It might be beneficial to switch the Thread.Sleep(0) with Thread.SpinWait(some amount of iterations), but I haven't been able to identify issues with Thread.Sleep(0) in my (limited) testing.
PS2: For users on machines with lower specs I was thinking it might be possible to implement a switch to the old Thread.Sleep method dynamically (if max FPS is set to < 65 or if only 2 cores are detected) so the game uses less CPU resources.
Game Version: 1.16.5 Platform: Windows Modded: No SP/MP: Singleplayer
Description
Using the MaxFPS slider at higher settings than 60 (without Vsync since this disables it) locks FPS to ~60.
How to reproduce
Expected behavior
FPS is capped to the MaxFPS setting instead of 60
Screenshots
Before: After:
Fix
I recently got the game and upon starting a new world and exploring, I noticed my FPS wasn't super smooth. After checking the settings I saw my FPS was capped to 60 even though I had configured it at a max of 100. After a bit of digging I found out that the game's rendering loop uses Thread.Sleep(num) to limit FPS. On my system however, the minimum amount of time Thread.Sleep sleeps for is ~15-16ms thus restricting the FPS limiter to a max limit of ~60 FPS. Since using native calls to modify the timer on the OS level seemed dirty and impractical to me, I tried looking for a different solution and here's what I came up with:
Since Thread.Sleep(0) is used, this will still yield if other work is available, if not it will loop thus consuming CPU cycles and being a 'busy wait'. Thus this uses slightly more CPU cycles than using just Thread.Sleep, but now I can enjoy a much smoother (and configurable) experience.