Posted by speckx 3 days ago
switch(game_state):
case(paused):
<the paused logic goes here>
case(gameplay)
<updating entities and regular gameplay goes here>
You still have to be careful about how you implement "gameplay", though. For example if at any point you read the 'system clock' to do time-based stuff like animations or physics, then when you unpause you suddenly will have a couple minutes of advance in a place where you expect fractions of a second. float accum = 0;
while (running) {
poll_input();
poll_network();
accum += delta_time;
while (accum >= tick_time) {
accum -= tick_time;
update_ui(tick_time);
update_anims(tick_time);
if (!paused) {
update_entities(tick_time);
}
}
render();
}It's a simulation; why should clock time be involved to begin with? The only things that should care about clock time are those that exist outside the sim, e.g audio
But I’m not 100% that’s even true; in the context of replay, I imagine it’d be more appropriately part of the sim for it to scrub properly.
In the context of networked games with client-side prediction, I think it’d probably be key frames tied to logical time and intermediate frames tied to wallclock
It suggests a level of control way below what I would ordinarily consider required for game development.
I have made maybe around 50 games, and I think the level of control of time has only ever gone up. Starting at move one step when I say, to move a non-integer amount when I say, to (when network stuff comes into play) return to time X and then move forward y amount.
The trick is to separate the logic simulation from other game loops (rendering, UI, input, sound, etc). So when a player pauses the game, everything else still more or less works. And the logic simulation should be able to take user "command" while being paused.
Most commands should mutate the game state and reflect in the UI immediately. A few commands that have to wait until the next tick should at least acknowledge the action result.
i did the thing you're "not supposed to do" and attached everything to a world clock so everything ran at like 60fps in terms of events, so it was a real-time "turn based" system
Typically any of the common modern engines with a "time scale" variable like that are not at all optimising anything in that way. It's likely that the physics engine won't be stepped with a zero delta time, which will reduce the time spent on physics, but that's more of a byproduct of how physics engines work[0] than an optimisation.
You would have to go out of your way to capture the scene and display it "under the pause menu" in that way. Not saying nobody does that, just that it's not something the engine is giving you for free nor is it related to the time scale variable.
Further, doing that won't necessarily reduce resource usage. For example, if there isn't some sleep time inserted in the main loop when in a menu, or v-sync[1] to limit the framerate, the result of the simplified scene (just the menu and the quad with the captured scene) is an extremely high framerate, which may or may not cook the hardware more than the in-game load.
[0] Typical rigidbody physics engines are only (what I'll call) predictably stable with a constant delta time (same dt every tick). And a common way to manage this is with a time accumulator main loop, that only steps physics for whole units of dt.
[1] And v-sync isn't a silver bullet. consider refresh rates, different hardware, different drivers, driver overrides.
acerola on YouTube has an excellent 23 minute frame rendering analysis video about what goes into drawing just the "pause menu" in Persona 3 Reload:
A damn blurred screenshot should not make the GPU consume hundreds of Watts.
The rendering loop continues to run. The GUI is immediate mode and is still rendered. In some games visual effects continue to be rendered. If it’s a networked game the network code will continue to run.
Given this the game needs to slow down and lock its frame rate while paused and in menus otherwise it will run at full speed and burn a lot of CPU & GPU time. Though I would say this is not usually an issue because it gets fixed pretty quickly during development.
Now more work can be done by the developers to make the paused state this efficient, but it is all a matter of priorities, and in all cases the developers would rather spend their time making the gameplay better and fixing crash bugs. If the player wants their game to run more efficiently then they should reduce the processing demands by limiting the frame rate and lowering quality settings.
> unless the developers got time to implement something custom
As I said: the point nevertheless ought to stand.
Taken from this comment: https://news.ycombinator.com/item?id=47825155
Obviously not every game is doing that level of styling, but often a lot of stuff might still be happening when a game is "paused" for various reasons e.g. aesthetics, or handling input for pause menus, which usually offer you the ability to change all the games settings, e.g. video resolution, volume levels, etc. and also provide you with audio/visual feedback when you make choices, which requires keeping the audio engine running as well as rendering to the screen @ 60 fps.
article confirms my early theory I formed when reading the title about why would pause be complicated