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’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.
Like a lot of issues in gamedev, pausing the game is a surprisingly difficult problem to solve. It's especially difficult to provide a one size fits all solution which would obviously be desirable for the popular modern engines that try to be a general solution.
I see a lot of comments here saying something along the lines of "isn't it just a state in the state machine?" which isn't wrong, but is an extremely simplistic way of thinking about it. In, say, 1983, you could get away with something like that:
- pause the game: write "PAUSED" to the tilemap
- paused main loop: check input to unpause
- unpause the game: erase the "PAUSED" / restore the previous tiles
But at that time you could already see the same sort of issues as today. Something somewhat common in Famicom/NES games is the sprites disappearing when the game is paused. Perhaps deliberate/desirable in some cases (e.g. Tetris) but a lot of the time, probably just a result of the 'is paused' conditional branch in the main loop skipping the sprite building code[0].
There's an extremely large problem space and ultimately, each game has its own way to define what "paused" actually means.
You might be interested in the features Godot provides[1] for this. Particularly, the thing that makes it interesting is the 'process mode' that each node in the scene tree has. This gives the developer quite a lot of control over what pausing actually means for a given game. It's not a complete solution, but a useful tool to help solve the various problems.
[0] Simplified description of course. Also, the sprite building code often ended up distributed throughout the various gameplay logic routines, which you don't want to run in the paused state.
[1] https://docs.godotengine.org/en/stable/tutorials/scripting/p...
[ed] Just adding that Tetris is only an example of a game where you might want that behaviour, not a comment about how any of the Tetris games were actually made.
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.
Seems like a solved problem for consoles, at least. On the Nintendo switch you can "pause" any game regardless of if the devs implemented it by pressing the home button which suspends the entire game at the OS level
I quite like when games keep playing some visual-only animations when paused.
Like torch flames and trees swaying in the wind.
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.
Lessons learnt? None, I think :)
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.
Suddenly I realize why so many games didn't have a real pause feature, but a view maps feature that did the same.
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.
There used to be a funny bug in Dota 2:
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.
So the simple case is using some sort of state variable:
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.If your game uses more than 1% CPU and 1% GPU when paused you're doing something wrong.
A damn blurred screenshot should not make the GPU consume hundreds of Watts.
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.
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.
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.
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.
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.
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.
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).
More people should play Lobotomy Inc. Coolest pause mechanism I've ever seen.
> 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
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
Can we just link to the twitter thread the article copies content from?
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"
Weird times.
This reminds me of the Action Replay device you could get for the Amiga 500 in the ‘90s.
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.
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.
Not sure if slowing down time is the right approach.
The best approach would be using something like if(game_is_paused) return; in the game loops.
[flagged]
How difficult can it be when Cloud providers are able to do live migration of VM from one bare metal server to another?
One of the fun features that I developed for Warcraft (the RTS) was to fade the screen to grayscale when the game is paused.
Since the game uses a 256 color palette, it was only necessary to update a few bytes of data (3x256) instead of redrawing the whole screen, so the effect was quick.
I also used this trick when the game stalled due to missing network packets from other players. Initially the game would still be responsive when no messages were received so that you could still interact and send commands. After a few seconds the game would go into paused state with grayscale screen to signify the player that things were stuck. Then several seconds after that a dialog box would show allowing a player to quit the game.
This was much less disruptive than displaying a dialog box immediately on network stall.