For my game (custom engine) I had a way to stop the game clock from advancing, while the input and draw loop kept running. It would also put the game into the "pause" input state during which only the resume button would be active.
One of the things that impressed me in Quake (the first one) was the demo recording system. The system was deterministic enough that it could record your inputs/the game state and just play them back to get a gameplay video. Especially given that Quake had state of the art graphics at the time, and video playback on computers otherwise was a low-res, resource intensive affair at the time, it was way cool.
It always surprised me how few games had that feature - though a few important ones, like StarCraft, did - and it only became rarer over the years.
I find the notion odd that this is even a problem to be solved.
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 strangest pause bug I know is in Mario Sunshine: pausing will misalign the collision logic (which runs 4 times per frame) and the main game loop. So certain specific physics interactions will behave differently depending on how many times the game has been paused modulo 4.
When I present TLA+ [0], I am referencing game pauses (pause buffer / item duplication Legend of Zelda exploit, Dark Souls menuing to cancel animations) and deliberate crashes as mechanics to exploit games, as those are still valid actions that can be modeled, and not doing that allows such exploits to happen.
A system is only correct relative to the transition system you wrote down. If the real system admits extra transitions that you care about (pause, crash, re-entry, partial commits), and you didn't model them, then you proved correctness of the wrong system.
Do you have any of these presentations available publicly? I'm always amused by the glitch names people come up with (force quit wrong warps, skirtless parry-walks...) and it'd be fun to see them in a TLA+ context.
The console cert ones are interesting but all the others are just Unity/Gamemaker/Unreal not allowing the developers to write normal code? The nonzero timestep thing is very strange
When I first played the NES the pause feature impressed me even more than did the graphics. Apparently Atari already had the feature on the 5200 console, but even as late as 1988 it felt like magic to hit a button, go and eat dinner, and an hour later resume my game with another press of the button.
Early versions of Unreal Engine had these animated procedural textures that would produce sparks, fire effects, etc. The odd part is that when you paused the game, the animated textures would still animate. Presumably, the game would pause its physics engine or set the timestep to 0, but the texture updater didn't pause. I suspect it was part of the core render loop and each new iteration of the texture was some sort of filtered version of the previous frame's texture. Arguably a very early version of GPU physics.
Modern games can have the same issue. Even taking a capture of the exact graphics commands and repeating them, you'll sometimes see animated physics effects like smoke and raindrops. They're doing the work on the GPU where it's not necessarily tied to any traditional physics timestep.
> when it was time to ship, we’d read the [Technical Requirements Checklists] and have to go back and add a special pause for when you unplug the controller
article confirms my early theory I formed when reading the title about why would pause be complicated
I only know pausing games is funky because the highest my playstation fans ever go is pausing some games. Quite weird pausing is not just a feature of the game engine or runtime, especially as the menu and settings system seem to be totally separate in most cases anyways.
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.
I was suspicious of those random game developers getting quoted, and this is the pinned post of the one giving this cute silly story about slowing down game speed time:
"Announcing TORMENT HEXUS, a match-3 roguelike about putting technofascist CEOs on the wrong side of skyscraper windows!
[...]
And remember: they SHOULD be afraid of us.
#indiedev #indiegame"
While the game is paused, if a player were to click on the "level up" buttons for their skills, each click actually advanced the game by 1 frame - so it was possible for people to die etc. during a pause screen.
I would expect pausing to bring a game’s CPU/GPU usage down to near-zero, which won’t happen if the game keeps redundantly rendering the exact same frame. A game engine can optimize this by special casing time scale zero to simply render a single textured quad under the pause menu (which is probably what one of the commenters in TFA referred to).
One of the things I was thinking about with regards to pause and or save games, is the need to control all aspects of real time logic, with possibly stopping/resuming, and saving it to disk is how our current ways of doing async is incredibly lacking.
Unity has introduced the idea of coroutines (which were essentially yield based generators), and people started using them, and immediately encountered problems with pausing/saves.
Internally these coroutines compile down to state machines with opaque internals which are not necessarily consistent across compilers/code changes, and its very difficult to accomodate needs like pausing when using them.
From what I've seen, the usual answer is that people go back to hand-written state machines, and go through the pain of essentially goto programming to fix these issues.
From a lot of game jam games with custom engines, I have a pretty standard approach: I set the game clock to zero timestep, and push a pause gamestate onto the gamestate stack, where top gamestate gets all input. The trick is that you need many clocks, clocks for the gameplay/game animations, HUD animations, menu animations.
This is silly reporting with a couple of interesting stories. Forget about the technical ways of doing it. Doing it at all changes the game experience.
Pausing a game has a massive impact on the game experience. It lets you break the fourth wall experientially. Not wrong, but it changes the dynamic of the game.
Same as saving at any time does. As losing your loot or your life permanently does. Not wrong, but a hard choice that appeals to some players and not to others.
I used to pause pacman on my Atari 800 so I could run to church and sing in the choir or be an altar boy. Then I ran home and unpaused to continue. Sometimes in summer the computer over-heated and I lost everything while I was at church.
> Same as saving at any time does. As losing your loot or your life permanently does. Not wrong, but a hard choice that appeals to some players and not to others.
I am recently working on a "realtime with pause" style grand strategy game using my own engine (think Europa Universalis, Crusader King, Hearts of Iron).
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’d love to hear about the 2020 release of Microsoft Flight Simulator, which had an “active pause” feature that they hyped as a big innovation for that release. You could pause and switch camera angles and see what was going on, then quickly resume. Pretty much the whole game was still interact-able, but with your plane’s position paused. It was supposed to be a nice user-friendly way to pause while you checked gauges or fiddled with cockpit settings or whatever.
It never worked. You’d pause, and the plane was frozen in place yes, but the instrument cluster would still animate and show your altitude/speed changing as if you never paused. But you couldn’t control anything until unpaused. So you’d resume, and your momentum would suddenly leap to where the accumulated deltas ended up. So if you active-paused at full throttle, you’d unpause and start going way too fast… if you active paused while stalling, you’d unpause and your speed would be near zero… you’d even consume fuel while paused.
It’s like they literally just froze the plane’s position and left every other aspect of the physics engine untouched, never tested it, shipped it, and even did a bunch of marketing at how great the feature was. When it was so obviously broken.
I came back to the game after a year or so of updates, and not a thing had improved, it was every bit as broken as when they shipped it.
The 2024 release seems to have largely fixed it though from what I can see. It’s just nuts they had such a clearly broken feature for that long.
46 comments
[ 2.6 ms ] story [ 56.3 ms ] threadThe best approach would be using something like if(game_is_paused) return; in the game loops.
It always surprised me how few games had that feature - though a few important ones, like StarCraft, did - and it only became rarer over the years.
Like torch flames and trees swaying in the wind.
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.
A system is only correct relative to the transition system you wrote down. If the real system admits extra transitions that you care about (pause, crash, re-entry, partial commits), and you didn't model them, then you proved correctness of the wrong system.
[0] https://lamport.azurewebsites.net/video/videos.html
Modern games can have the same issue. Even taking a capture of the exact graphics commands and repeating them, you'll sometimes see animated physics effects like smoke and raindrops. They're doing the work on the GPU where it's not necessarily tied to any traditional physics timestep.
article confirms my early theory I formed when reading the title about why would pause be complicated
switch(game_state):
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."Announcing TORMENT HEXUS, a match-3 roguelike about putting technofascist CEOs on the wrong side of skyscraper windows!
[...]
And remember: they SHOULD be afraid of us. #indiedev #indiegame"
Weird times.
While the game is paused, if a player were to click on the "level up" buttons for their skills, each click actually advanced the game by 1 frame - so it was possible for people to die etc. during a pause screen.
Unity has introduced the idea of coroutines (which were essentially yield based generators), and people started using them, and immediately encountered problems with pausing/saves.
Internally these coroutines compile down to state machines with opaque internals which are not necessarily consistent across compilers/code changes, and its very difficult to accomodate needs like pausing when using them.
From what I've seen, the usual answer is that people go back to hand-written state machines, and go through the pain of essentially goto programming to fix these issues.
Pausing a game has a massive impact on the game experience. It lets you break the fourth wall experientially. Not wrong, but it changes the dynamic of the game.
Same as saving at any time does. As losing your loot or your life permanently does. Not wrong, but a hard choice that appeals to some players and not to others.
I used to pause pacman on my Atari 800 so I could run to church and sing in the choir or be an altar boy. Then I ran home and unpaused to continue. Sometimes in summer the computer over-heated and I lost everything while I was at church.
Lessons learnt? None, I think :)
That choice should be left for the player.
You could use a knob to slow down any game to a stop. You could also press a button to go to a console that let you change memory.
It would even figure out which bit of memory kept the number of lives of you deliberately lost a life and it could see what decremented.
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.
It never worked. You’d pause, and the plane was frozen in place yes, but the instrument cluster would still animate and show your altitude/speed changing as if you never paused. But you couldn’t control anything until unpaused. So you’d resume, and your momentum would suddenly leap to where the accumulated deltas ended up. So if you active-paused at full throttle, you’d unpause and start going way too fast… if you active paused while stalling, you’d unpause and your speed would be near zero… you’d even consume fuel while paused.
It’s like they literally just froze the plane’s position and left every other aspect of the physics engine untouched, never tested it, shipped it, and even did a bunch of marketing at how great the feature was. When it was so obviously broken.
I came back to the game after a year or so of updates, and not a thing had improved, it was every bit as broken as when they shipped it.
The 2024 release seems to have largely fixed it though from what I can see. It’s just nuts they had such a clearly broken feature for that long.