Feature: allow changing the game-speed other than 1x and warp-speed #8693
#8766 already implements part of this PR that has to do with changing the internals to use
Motivation / Problem
With #8680 (on which this PR depends) and #7744, fast-forward can easily hit 9999x simulation speeds. This makes fast-forward completely impracticable in most use-cases, as holding down the button for 1 second gives you an extra month of gametime. You miss a decade if you blink, basically.
This PR tries to mitigate that issue by introducing a "Game Speed" window. Incidentally, it also allows the game to run slower.
Initially I tried a dropdown to allow selecting the game-speed (or called fast-forward speed in that branch). It felt really bad to work with. The menu is not really designed for these kind of interactions, but mostly, once you are fast-forwarding, there was no real way to telling at what speed.
So I took another approach most other games I know do: make a window where you can select the game speed. And the last commit in this PR does exactly that (the rest are identical to #8680).
This draft-PR I made purely so others can already see the work, and to allow me to make a Preview to get opinions from others.
Checklist for review
Some things are not automated, and forgotten often. This list is a reminder for the reviewers.
The text was updated successfully, but these errors were encountered:
Adding to _realtime_ticks in a random place is a bit of a hack, and by using modern C++, we can avoid this hack.
On all OSes we tested the std::chrono::steady_clock is of a high enough resolution to do millisecond measurements, which is all we need. By accident, this fixes a Win32 driver bug, where we would never hit our targets, as the resolution of the clock was too low to do accurate millisecond measurements with (it was ~16ms resolution instead).
During fast-forward, the game was drawing as fast as it could. This means that the fast-forward was limited also by how fast we could draw, something that people in general don't expect. To give an extreme case, if you are fully zoomed out on a busy map, fast-forward would be mostly limited because of the time it takes to draw the screen. By decoupling the draw-tick and game-tick, we can keep the pace of the draw-tick the same while speeding up the game-tick. To use the extreme case as example again, if you are fully zoomed out now, the screen only redraws 33.33 times per second, fast-forwarding or not. This means fast-forward is much more likely to go at the same speed, no matter what you are looking at.
Before, every next frame was calculated from the current time. If for some reason the current frame was drifting a bit, the next would too, and the next more, etc etc. This meant we rarely hit the targets we would like, like 33.33fps. Instead, allow video-drivers to drift slightly, and schedule the next frame based on the time the last should have happened. Only if the drift gets too much, that deadlines are missed for longer period of times, schedule the next frame based on the current time. This makes the FPS a lot smoother, as sleeps aren't as exact as you might think.
Sleep for 1ms (which is always (a lot) more than 1ms) is just randomly guessing and hoping you hit your deadline, give or take. But given we can calculate when our next frame is happening, we can just sleep for that exact amount. As these values are often a bit larger, it is also more likely the OS can schedule us back in close to our requested target. This means it is more likely we hit our deadlines, which makes the FPS a lot more stable.
Most modern games run on 60 fps, and for good reason. This gives a much smoother experiences. As some people have monitors that can do 144Hz or even 240Hz, allow people to configure the refresh rate. Of course, the higher you set the value, the more time the game spends on drawing pixels instead of simulating the game, which has an effect on simulation speed. The simulation will still always run at 33.33 fps, and is not influences by this setting.
… that shouldn't be closed yet The higher your refresh-rate, the more likely this is. Mostly you notice this when creating a new game or when abandoning a game. This is a bit of a hack to keep the old behaviour, as before this patch the game was already freezing your mouse while it was changing game-mode, and it does this too after this patch. Just now it freezes too a few frames earlier, to prevent not drawing windows people still expect to see.
Absolutely! I had it planned, just hadn't made it into the PR yet .. but it is now in the TODO list, so we will not forget :D
After pressing "FF" once, I cannot raise it anymore :)
Suggestion option 1:
Suggestion option 2:
I keep looking at this, thinking: I think this would be a really good idea.
On the other hand, I also have this huge issue of me thinking: I really do not want to spend time on this :P I cannot get myself motivated to build a custom widget with a slider to show the current setting, but also what the game is currently able to do. And that you can slide it easily, and that is works smooth etc .. I have it all in my head. I just ... cannot get myself to do it.
So for now I am going to close this Pull Request. If anyone else wants to pick it up, please do. I might find the energy to do it myself some day .. just not soon.