Difference between revisions of "Unstable replays"

From Stunts Wiki
 
(8 intermediate revisions by the same user not shown)
Line 31: Line 31:
 
* Fast playing an unstable replay from ''either'' the beginning or 0:00.05, depending on where the divergence point is, will lead to the fast-forward timeline.
 
* Fast playing an unstable replay from ''either'' the beginning or 0:00.05, depending on where the divergence point is, will lead to the fast-forward timeline.
  
* Loading the replay from the Options menu and fast-forwarding the tape from the beginning to the end lead to the same result: the final state of the fast-forward timeline.
+
* Either loading the replay from the Options menu or fast-forwarding the tape from the beginning to the end lead to the same result: the final state of the fast-forward timeline.
  
 
* Loading from Options and rewinding will keep you in the fast-forward timeline. (Fast-forwarding is okay as long as you don't stop at the divergence point, nor play through it.)
 
* Loading from Options and rewinding will keep you in the fast-forward timeline. (Fast-forwarding is okay as long as you don't stop at the divergence point, nor play through it.)
Line 39: Line 39:
 
* To find the exact frame of the divergence point, load from Options (or fast-forward to the end), rewind to a candidate frame, and play from there. If you stay on the fast-forward timeline by doing so, the divergence is further back. If you switch to the divergent timeline, either you stopped exactly at the divergence point (and redoing it on the next frame will lead to the fast-forward timeline) or the divergence is further ahead.
 
* To find the exact frame of the divergence point, load from Options (or fast-forward to the end), rewind to a candidate frame, and play from there. If you stay on the fast-forward timeline by doing so, the divergence is further back. If you switch to the divergent timeline, either you stopped exactly at the divergence point (and redoing it on the next frame will lead to the fast-forward timeline) or the divergence is further ahead.
  
* Watching both the fast-forward and the divergent timeline in the manner described above will usually be enough give you an upper boundary for where the divergence point can be (it must be before the timelines become visibly different). If somehow that isn't helpful, you can systematically find the 30-seconds window the divergence must be in by playing from the beginning, pausing at ~29.95, ~59.95, etc., and rewinding a single frame at each stop until you see a timeline change.
+
* Watching both the fast-forward and the divergent timeline in the manner described above will usually be enough to give you an upper boundary for where the divergence point can be (it must be before the timelines become visibly different). If somehow that isn't helpful, you can systematically find the 30-seconds window the divergence must be in by playing from the beginning, pausing at ~29.95, ~59.95, etc., and rewinding a single frame at each stop until you see a timeline change.
  
* If you see an unexpected crash while playing an unstable replay, and rewinding doesn't instantly switches timelines, chances are the divergence point is on the other side of a 30-seconds checkpoint. (A straightforward example C232DUP.RPL: divergence point at 27.95, crashes on the divergent timeline at 33.05. C232OVE.RPL is similar, but more confusing still because the fast-forward timeline isn't the successful one.)
+
* If you see an unexpected crash while playing an unstable replay, and rewinding doesn't instantly switch timelines, chances are the divergence point is on the other side of a 30-second checkpoint. (A straightforward example C232DUP.RPL: divergence point at 27.95, crashes on the divergent timeline at 33.05. C232OVE.RPL is similar, but more confusing still because the fast-forward timeline isn't the successful one.)
  
 
== How rewinding works ==
 
== How rewinding works ==
Line 51: Line 51:
 
[[image:Rewinding-past-a-checkpoint.gif|320px|float|center|thumb|Demonstration of the increase in frame loading times when rewinding a replay past a 30-second checkpoint (replay: C260DUP.RPL).]]
 
[[image:Rewinding-past-a-checkpoint.gif|320px|float|center|thumb|Demonstration of the increase in frame loading times when rewinding a replay past a 30-second checkpoint (replay: C260DUP.RPL).]]
  
That's a nifty optimisation if replays always play in consistent ways. If they don't, though, things get interesting. For instance, if you are on a divergent timeline, and the divergence point lies behind a checkpoint, there will be a visible discontinuity when you rewind past the checkpoint. Depending on how far away checkpoint and divergence are, the discontinuity can be very obvious, as in Usrin's ZCTP03 replay around 2:00 (divergence at 1:38.95)...
+
That's a nifty optimisation if replays always play in consistent ways. If they don't, though, things get interesting. For instance, if you are on a divergent timeline, and the divergence point lies behind a checkpoint, there will be a visible discontinuity when you rewind past the checkpoint. Depending on how far away checkpoint and divergence are, the discontinuity can be very obvious, as in [[Usrin]]'s ZCTP03 replay around 2:00 (divergence at 1:38.95)...
  
 
[[image:p03zusr-discontinuity.gif|320px|float|center|thumb|Obvious discontinuity observed while rewinding an unstable replay (p03zusr.rpl).]]
 
[[image:p03zusr-discontinuity.gif|320px|float|center|thumb|Obvious discontinuity observed while rewinding an unstable replay (p03zusr.rpl).]]
  
... or incredibly subtle, as in Overdijf's ZCT232 replay around 0:30 (divergence at 28.05):
+
... or incredibly subtle, as in [[Overdrijf]]'s ZCT232 replay around 0:30 (divergence at 28.05):
  
[[image:C232OVE-discontinuity.gif|320px|float|center|thumb|Obvious discontinuity observed while rewinding an unstable replay (p03zusr.rpl).]]
+
[[image:C232OVE-discontinuity.gif|320px|float|center|thumb|Subtle discontinuity observed while rewinding an unstable replay (C232OVE.RPL).]]
  
 
== Why rewinding fixes replays (sometimes) ==
 
== Why rewinding fixes replays (sometimes) ==
  
{{sectstub}}
+
To keep things simple, for now let's just consider replays with a single divergence point. Suppose that you're on a divergent timeline. Since rewinding amounts to fast-forwarding from the nearest checkpoint, any rewinding within the 30-second window between checkpoints which contains the divergence point switches to the fast-forward timeline. That being so, if said window lies behind a checkpoint, you see discontinuities like the ones above upon crossing it, and rewinding without crossing it will preserve the divergence. However, if you're already into the window, any use of the rewind button will instantly snap you back into fast-forward timeline. For instance, here is what would happen in an attempt to fix this wayward jump in the divergent timeline of [[Duplode]]'s ZCT099 replay (divergence at 42.00):
  
WIP
+
[[image:099zdup-leaving-a-divergent-timeline.gif|320px|float|center|thumb|Snapping out of a divergence, started before the latest checkpoint, by rewinding a single frame (replay: 099zdup.rpl).]]
 +
 
 +
This explains why most unstable RH replays complete the lap successfully in the fast-forward timeline. What typically happens is that the racer enters a divergent timeline while driving and then, a few seconds later but before reaching a checkpoint, rewinds slightly to fix something. At this point, the replay switches to the fast-forward timeline (a change that might be barely noticeable, depending on how close the divergence point is), and the racer completes the lap on it. For the same reason, replays driven like that are easily played to the end: once the spectator notices something amiss, like an unexpected crash, any rewinding will put the replay back into the fast-forward timeline, which will be successful.
 +
 
 +
Instability usually gets harder to handle, though, if the divergence point is just before a checkpoint. The most familiar example is Overdijf's replay at ZCT232. Here is a demo of its successful divergent timeline:
 +
 
 +
[[image:C232OVE-successful-timeline.gif|320px|float|center|thumb|The successful divergent timeline in Overdrijf's ZCT232 lap (replay: C232OVE.RPL).]]
 +
 
 +
In this case, the most likely sequence of events is that Overdrijf entered the divergent timeline at 28.05, completed the jump over the bridge on the first attempt and found no need to rewind past the 30.00 checkpoint for the rest of his racing session, until the lap was done. That being so, the lap was completed on the divergent timeline. To watch that timeline, though, you need to play the lap from 28.05 or earlier and hope for the best.
 +
 
 +
Two corollaries are worth mentioning here:
 +
 
 +
Firstly, attempting to "fix" an unstable replay with a successful fast-forward timeline can make things worse if the successful timeline becomes a divergent one which is hard to reproduce. This is likely what happened to [[Frieshansen]]'s laps on ZCT251 (C251FRE.RPL, 1-17-45.RPL and 1-17-50.RPL).
 +
 
 +
Secondly, any [[NoRH]] unstable replay must be completed on the divergent timeline. Since NoRH unstable replays are very unlikely to arise in practice, given how instability is associated with powerslides, a set piece had to be prepared to demonstrate this. The resulting replay is SLIDER.RPL. Its track has a moat surrounding the middle of the map. In the divergent timeline, which is the one driven NoRH, the car sinks from inside the moat at 2:09.15, whereas in the fast-forward timeline it sinks from outside the moat at 1:56.95. The divergence point comes very early at 30.50, and for a long time after that the differences between the timelines are barely noticeable by the naked eye. Below are two example screenshots at 1:20.00:
 +
 
 +
<gallery caption="SLIDER.RPL" heights=200px mode=packed>
 +
File:SLIDER-divergent-1-20-00.png|Divergent timeline, 1:20.00.
 +
File:SLIDER-fast-forward-1-20-00.png|Fast-forward timeline, 1:20.00.
 +
</gallery>
 +
 
 +
SLIDER.RPL also demonstrates that divergences can happen as you drive a lap or watch a replay without anything being done with the replay controls, to the point that unstable NoRH replays are possible. Broadly speaking, the replay controls provide a way to switch timelines, not to create them.
 +
 
 +
=== The alternative divergent timeline ===
 +
 
 +
The "broadly speaking" qualifier was added to the paragraph just above due to a kind of divergent timeline which is unlikely to arise except by toying with the replay controls. It was discovered by [[Argammon]], with the defining example being the parked-by-the-beach ending of [[Friker]]'s deleted ZCT260 replay (FRI15695.RPL). If you advance the tape to the divergence point (in this case, 1:46.00) and play to the end, you will get a divergent timeline. However, fast-forwarding a single frame ahead from the divergence point and playing from there can result in a slightly different divergence. With Friker's replay, the margins are thin enough that such a subtle change leads to a finish completely different from what happens in the two main timelines.
 +
 
 +
== Fast play (aka double speed) ==
 +
 
 +
What about fast play — is it a viable way of watching unstable replays, as has been suggested in the past? By and large it is, though using it has its own subtleties.
 +
 
 +
In all examples that have been analysed thus far, fast play follows either the fast-forward timeline or the (main) divergent one, depending on the point of the tape at which fast play is started. Assuming a staring point earlier than the divergence, we have:
 +
 
 +
*If the timestamps of the starting point and divergence point end with the same digit, it will follow the divergent timeline.
 +
* Otherwise, it will follow the fast-forward timeline.
 +
 
 +
For instance, fast-playing FRI15695.RPL from the beginning (0:00.00) leads to the (crashing) divergent timeline, as the divergence point is 1:46.00, while starting from 0:00.05 leads to the (successful) fast-forward timeline.
 +
 
 +
Fast play works by stepping through each frame of the simulation normally, as it must be, but only rendering graphics for every other frame (note how the timestamps in the replay bar advance by 0.10 s while using fast play). That we seemingly get different results from fast play depending on whether graphics get rendered at the divergence point is one more piece of evidence suggesting that divergences fundamentally have to do with graphics rendering in the game loop.
  
 
[[Category:Game]]
 
[[Category:Game]]

Latest revision as of 16:38, 11 September 2024

An unstable replay is a replay which can produce different outcomes depending on how it is played back, as if the replay tape could split into diverging timelines at some specific frame. Unstable replays are a rare occurrence, but not vanishingly so, and typically are RH racing laps with aggressive powergear slides.

Whether a divergence will appear in a replay, and what it will look like if it does, depends on a large number of factors, including but not limited to: the chosen camera, in-game graphics settings, the number of cycles in DOSBox and the system (be it an emulator or real hardware, as the effect has also been observed in native DOS systems) used to run the game. Since, in contrast, reproducing a replay with only the bare game state loop (be it by fast-forwarding the tape or by using the repldump tool) gives consistent outcomes across systems, instability is believed to somehow arise from the graphics layer. Since live gameplay can't help but involve graphics, the exposure of drivers to instability can be limited only so far.

While unstable replays are by and large just one more amusing curio of Stunts, the conflicting outcomes can lead to confusion when validating laps in a race, specially given how the system dependence of the effect can make it hard to reproduce. That being so, this article aims at clarifying what to expect upon facing an unstable replay and how to effectively navigate in it, which should help avoiding, or getting out of, messy situations in competitions.

Definitions

Note: Replays mentioned in what follows can be downloaded from Southern Cross.

To avoid mixing up things, let's begin by defining some key terms that we'll use in the discussion below. To begin with, for the replay controls, we'll mostly use the names in the game manual: skip to the start, stop, play, fast play and, in the bottom row, rewind and fast forward. (Note that fast play is often referred to as "double speed".)

Illustration of the replay control names mentioned above

Next, some key notions about instability:

Fast-forward timeline
The events in a replay as seen by fast-forwarding it from the beginning, loading it from the Options menu, or reproducing it with repldump. The fast-forward timeline is the same across systems and settings, and so is a sensible choice of a default validation method for potentially unstable replays. (Note the relevant replay control is fast forward, and not fast play/"double speed".)
Divergent timeline
A sequence of events in a replay different from the one in the fast-forward timeline. A divergent timeline might be seen by playing the replay (that is, watching with the play button), or through some other use of the replay controls. Whether it will actually be seen can depend on the computer running the game, the DOSBox cycles setting, camera choice, graphics settings, and so forth.
Divergence point
A point in the replay at which two or more timelines diverge. Divergence points are typically vertex points in a powergear slide, in which the car stops for a moment before shooting into a different direction (note the converse is presumably not true: there are many powergear slides which, as far as we know, don't lead to divergences). By convention, divergence points will be quoted using the last frame before the timelines split (for instance, FRI15695.RPL has a divergence point at 1:46.00).
Unstable replay
A replay known to have a divergence point and multiple timelines when reproduced in some way on at least one system. (Given the way factors external to the game affect the observations, "known to be unstable" is arguably more accurate than "unstable", but let's try to keep the language straightforward.)

Navigating unstable replays

Before getting into the minutiae of how divergences play out, it's worth anticipating the conclusions a bit in order to give some practical advice on how to work around divergence points and switch timelines:

  • Playing an unstable replay from the beginning, or from any point before the divergence, will lead to a divergent timeline. What this timeline will look might depend on a host of factors, most notably your system and the chosen camera.
  • Fast playing an unstable replay from either the beginning or 0:00.05, depending on where the divergence point is, will lead to the fast-forward timeline.
  • Either loading the replay from the Options menu or fast-forwarding the tape from the beginning to the end lead to the same result: the final state of the fast-forward timeline.
  • Loading from Options and rewinding will keep you in the fast-forward timeline. (Fast-forwarding is okay as long as you don't stop at the divergence point, nor play through it.)
  • The divergence point will most likely be at the vertex of some powerslide, when the car changes direction suddenly.
  • To find the exact frame of the divergence point, load from Options (or fast-forward to the end), rewind to a candidate frame, and play from there. If you stay on the fast-forward timeline by doing so, the divergence is further back. If you switch to the divergent timeline, either you stopped exactly at the divergence point (and redoing it on the next frame will lead to the fast-forward timeline) or the divergence is further ahead.
  • Watching both the fast-forward and the divergent timeline in the manner described above will usually be enough to give you an upper boundary for where the divergence point can be (it must be before the timelines become visibly different). If somehow that isn't helpful, you can systematically find the 30-seconds window the divergence must be in by playing from the beginning, pausing at ~29.95, ~59.95, etc., and rewinding a single frame at each stop until you see a timeline change.
  • If you see an unexpected crash while playing an unstable replay, and rewinding doesn't instantly switch timelines, chances are the divergence point is on the other side of a 30-second checkpoint. (A straightforward example C232DUP.RPL: divergence point at 27.95, crashes on the divergent timeline at 33.05. C232OVE.RPL is similar, but more confusing still because the fast-forward timeline isn't the successful one.)

How rewinding works

One of the puzzling aspects of unstable replays is the way in which some divergences are so easily fixed to be barely noticeable, while others are recalcitrant enough to be nightmare fuel. Such variation arises from a replay mechanic that is an integral part of RH racing: rewinding.

The first thing to note is that the game does not rewind a replay by moving backwards in time. Rather, it fast-forwards the tape from the beginning to the point you want to reach. That is why rewinding is so slow on the 1990 Broderbund (Stunts 1.0) version of the game (and gets slower the further ahead the tape is). To improve on that, later versions store checkpoints of the game state every thirty seconds, so that there is no need to fast-forward from the beginning, but only from the latest checkpoint. For a demonstration, rewind frame by frame across a xx:00 or xx:30 timestamp. You'll notice the game takes noticeably longer to update once you go behind the checkpoint:

Demonstration of the increase in frame loading times when rewinding a replay past a 30-second checkpoint (replay: C260DUP.RPL).

That's a nifty optimisation if replays always play in consistent ways. If they don't, though, things get interesting. For instance, if you are on a divergent timeline, and the divergence point lies behind a checkpoint, there will be a visible discontinuity when you rewind past the checkpoint. Depending on how far away checkpoint and divergence are, the discontinuity can be very obvious, as in Usrin's ZCTP03 replay around 2:00 (divergence at 1:38.95)...

Obvious discontinuity observed while rewinding an unstable replay (p03zusr.rpl).

... or incredibly subtle, as in Overdrijf's ZCT232 replay around 0:30 (divergence at 28.05):

Subtle discontinuity observed while rewinding an unstable replay (C232OVE.RPL).

Why rewinding fixes replays (sometimes)

To keep things simple, for now let's just consider replays with a single divergence point. Suppose that you're on a divergent timeline. Since rewinding amounts to fast-forwarding from the nearest checkpoint, any rewinding within the 30-second window between checkpoints which contains the divergence point switches to the fast-forward timeline. That being so, if said window lies behind a checkpoint, you see discontinuities like the ones above upon crossing it, and rewinding without crossing it will preserve the divergence. However, if you're already into the window, any use of the rewind button will instantly snap you back into fast-forward timeline. For instance, here is what would happen in an attempt to fix this wayward jump in the divergent timeline of Duplode's ZCT099 replay (divergence at 42.00):

Snapping out of a divergence, started before the latest checkpoint, by rewinding a single frame (replay: 099zdup.rpl).

This explains why most unstable RH replays complete the lap successfully in the fast-forward timeline. What typically happens is that the racer enters a divergent timeline while driving and then, a few seconds later but before reaching a checkpoint, rewinds slightly to fix something. At this point, the replay switches to the fast-forward timeline (a change that might be barely noticeable, depending on how close the divergence point is), and the racer completes the lap on it. For the same reason, replays driven like that are easily played to the end: once the spectator notices something amiss, like an unexpected crash, any rewinding will put the replay back into the fast-forward timeline, which will be successful.

Instability usually gets harder to handle, though, if the divergence point is just before a checkpoint. The most familiar example is Overdijf's replay at ZCT232. Here is a demo of its successful divergent timeline:

The successful divergent timeline in Overdrijf's ZCT232 lap (replay: C232OVE.RPL).

In this case, the most likely sequence of events is that Overdrijf entered the divergent timeline at 28.05, completed the jump over the bridge on the first attempt and found no need to rewind past the 30.00 checkpoint for the rest of his racing session, until the lap was done. That being so, the lap was completed on the divergent timeline. To watch that timeline, though, you need to play the lap from 28.05 or earlier and hope for the best.

Two corollaries are worth mentioning here:

Firstly, attempting to "fix" an unstable replay with a successful fast-forward timeline can make things worse if the successful timeline becomes a divergent one which is hard to reproduce. This is likely what happened to Frieshansen's laps on ZCT251 (C251FRE.RPL, 1-17-45.RPL and 1-17-50.RPL).

Secondly, any NoRH unstable replay must be completed on the divergent timeline. Since NoRH unstable replays are very unlikely to arise in practice, given how instability is associated with powerslides, a set piece had to be prepared to demonstrate this. The resulting replay is SLIDER.RPL. Its track has a moat surrounding the middle of the map. In the divergent timeline, which is the one driven NoRH, the car sinks from inside the moat at 2:09.15, whereas in the fast-forward timeline it sinks from outside the moat at 1:56.95. The divergence point comes very early at 30.50, and for a long time after that the differences between the timelines are barely noticeable by the naked eye. Below are two example screenshots at 1:20.00:

SLIDER.RPL also demonstrates that divergences can happen as you drive a lap or watch a replay without anything being done with the replay controls, to the point that unstable NoRH replays are possible. Broadly speaking, the replay controls provide a way to switch timelines, not to create them.

The alternative divergent timeline

The "broadly speaking" qualifier was added to the paragraph just above due to a kind of divergent timeline which is unlikely to arise except by toying with the replay controls. It was discovered by Argammon, with the defining example being the parked-by-the-beach ending of Friker's deleted ZCT260 replay (FRI15695.RPL). If you advance the tape to the divergence point (in this case, 1:46.00) and play to the end, you will get a divergent timeline. However, fast-forwarding a single frame ahead from the divergence point and playing from there can result in a slightly different divergence. With Friker's replay, the margins are thin enough that such a subtle change leads to a finish completely different from what happens in the two main timelines.

Fast play (aka double speed)

What about fast play — is it a viable way of watching unstable replays, as has been suggested in the past? By and large it is, though using it has its own subtleties.

In all examples that have been analysed thus far, fast play follows either the fast-forward timeline or the (main) divergent one, depending on the point of the tape at which fast play is started. Assuming a staring point earlier than the divergence, we have:

  • If the timestamps of the starting point and divergence point end with the same digit, it will follow the divergent timeline.
  • Otherwise, it will follow the fast-forward timeline.

For instance, fast-playing FRI15695.RPL from the beginning (0:00.00) leads to the (crashing) divergent timeline, as the divergence point is 1:46.00, while starting from 0:00.05 leads to the (successful) fast-forward timeline.

Fast play works by stepping through each frame of the simulation normally, as it must be, but only rendering graphics for every other frame (note how the timestamps in the replay bar advance by 0.10 s while using fast play). That we seemingly get different results from fast play depending on whether graphics get rendered at the divergence point is one more piece of evidence suggesting that divergences fundamentally have to do with graphics rendering in the game loop.