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.
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.
Outside of VR, Unity offers a nice "AudioListener.pause" to pause all audio, but if you have any sound effects in your pause menu like when a user changes a setting, those no longer work, further requiring more hacky fun (or just set it to true, and ignore user-complaints about no audio on menus when paused).
On top of that, you have things like Animators for characters, which also have to be paused manually by setting speed to 0 (TimeScale = 0 doesn't seem to do it). Some particle systems also don't seem to be affected by TimeScale. If you have a networked game then you also have to (obviously) send the pause command to clients. If you have things in motion, pausing/restarting the physics engine might cause weird issues with (at least angular) velocity so you might have to save/restore those on any moving objects.
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.
[0] https://github.com/rameshvarun/marble-mouse/blob/8b25684a815...
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.
Like torch flames and trees swaying in the wind.
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 :)
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.
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.
Like, you're still just churning away at the main game loop while literally nothing else is happening except for you waiting for me to unpause it?
Because THAT would be an actual achievement. Hell, I can suspend any process from the Unixy side of things by sending a SIGSTOP signal, for a far more perfect "pause".
If I was a game dev, I would not settle for "looks like paused, but still burning down the environment and heating up my home as a side effect"
I hate when games are into multiplayer modes even when played in single-player campaign (e.g.: Generation Zero) and thus cannot be paused.
Another thing that I hate in this regard are unpausable cutscenes. I remember when I was playing The Witcher 3, that at last there was some cutscene advancing some plot point, and right into the middle of it The Wife™ would barge in telling me something important that would require my attention... but I cannot pause that scene so I had to miss it while I listened to her. Why, oh why, devs hate pausing cutscenes so much??
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.
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 really need to start blogging my notebook
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.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
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.
A damn blurred screenshot should not make the GPU consume hundreds of Watts.
article confirms my early theory I formed when reading the title about why would pause be complicated
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.
"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.
The best approach would be using something like if(game_is_paused) return; in the game loops.