Shawn Hargreaves Blog
Phrase: "the black pit of despair"
Definition: When fixed timestep catch up logic fails to keep up with the target time.
Usage: "Yesterday the framerate was bad, but today it got so much worse that we fell into the black pit of despair."
Fixed timestep game logic works by calling Update more than once in a row if it has fallen behind the target time. This does a great job of recovering from occasional frames that for some reason took longer than usual. It also works ok to recover from situations where the Draw operation is consistently taking too long, so the game has to reduce framerate and skip drawing every other frame, yet still wants to run Update at full frequency to avoid falling behind wall clock time.
But fixed timestep falls over if Update alone takes longer than the target time, even without Draw being called:
In simplistic implementations this causes the game to hang, calling Update over and over again without ever reaching Draw. Smarter fixed timestep logic will detect this situation and give up, breaking out of the loop so that Draw does eventually get called, albeit at a terribly low framerate.
The pit of despair creates a discontinuity in the relationship between overall framerate and the duration of each Update call. As you increase the time spent per Update, framerate gradually goes down, until you fall into the pit, at which point framerate plummets to zero and the game cannot continue in any reasonable way.
Hmm. I usually use this to refer to the problem with variable time steps! Variable-step processing can scale strangely as the timestep increases, e.g. the early-out logic for collisions starts finding exponentially more possibles as the timestep increases (whereas by definition fixed timestep always scales linearly). So your framerate glitches due to a particle effect close to the camera, the game logic sees a timestep 10x as long and takes 50x as long to process it. The particle system goes away, but now the more expensive game logic tanks the framerate. Which causes the game logic to behave even worse, and so into the pit of despair.
You can obviously clamp the max inter-rendered-frame timestep, as for the fixed timestep case. But with true variable-rate updates what can happen is you just get clamped there forever because of the feedback effect, and never escape. I think the right thing is to clamp how long the variable rate can be run for, and instead run it multiple times. So... a bit like a fixed timestep really :-)
In such cases as yours, there are only two options:
1) Prevent positive feedback by calling the logic multiple times instead of once with a 10x higher timestep.
2) Make a breakout clause. Measure the time(or iterations or recursions) your logic spends, if it reaches a maximum, deactivate the logic for a few cycles, to make the error recoverable.
I noticed, when playing XNA in windowed mode, dragging it around rises cycle times to several 100ms. I wouldn't want my code to freeze(drop into the black pit of despair) in such cases.
Besides we call it either 'Teufelskreis', or 'Darkness of Despair'(you can guess where that comes from...)
This term was discussed on GDAlgorithms 10 years ago, under the name "time step death/doom spiral." I think we've all felt it. The least bad solution is to slow down game time, which leads to disconnects if you are networked...
I've never agreed with the way XNA handles bad frame rates, since Update() is usually the cause for slowdown, and XNA assumes it's the Draw().
I prefer the 'slowdown syndrome' where the game itself slows down with the frame rate (think Super Mario Bros. when there's too many enemies on-screen). I do this like so: I make sure Update() is not called until Draw() is for the last frame, so you see every frame, no matter what.
This handles all cases of craziness, from bad code slowing the game down, to situations you never expected, to bad OS stuff going on in the background (a game download completion knocks off 60 frames), etc. I can make a boss explode with so much stuff that I bring the Xbox to its knees, and the slowdown syndrome emulator will make it appear as though I wanted this to happen, since the game will slow down as well, without any hint of frame skips. Score Rush will slow down in crazy difficulty levels with many players, and the slight slow down is welcome, just as it was during Task Force Harrier in the arcades. Sometimes the game design can incorporate this in, and desire it.
I realize this makes the game time and real time out of sync, so this would be bad for online play, and I wonder if this is the reason it was decided that XNA is implemented the way it is?
@Jason - just discarding time when the game cannot keep up is obviously trivial to implement (basically doesn't require you to do anything special at all) but I personally find it a horrible solution. Many games used to do that (especially simple 2D ones on fixed hardware platforms where they didn't really have any other alternative) but it's not a widely used design these days and I don't think you will find many game devs who consider this a good practice any more.