Determinism & replay

Replay scope

replay-scope-2

Tests included

This contract defines the behavior of recorded reruns: a racing ghost, a daily seed, or a shared solution.

This contract decides what your racing ghost has to match, whether the game can still play it after an update, and what happens at the first difference.

Use in your package

The first button opens the authoring tool with this contract added and its questions unanswered. You can also download the zip file and add the contract later.

What is in the zip file

The zip file holds the contract and its acceptance tests. In the authoring tool, choose Add contract and pick this zip file. If you edit your package outside the authoring tool, unpack the zip file in your package folder. The files of the zip file go into contracts/. Fill in the answers there.

Questions

3 questions.

  1. What does this replay need to run again?
  2. What happens to a recorded replay after the game updates?
  3. What happens at the first difference between the replay and the record?

Try the answers

Pick answers to see which rules and tests apply. Nothing is saved here. In the zip file and in the authoring tool, the questions have no answers yet.

What does this replay need to run again?

Choices for What does this replay need to run again?
The replay needs only the seed. A roguelike daily run rebuilds the day's dungeon before new play begins.

The record carries the seed but no input log; each claim's comparison reference is carried or recomputed from the record. Playback consumes the seed, accepts live inputs, and applies each claim's live-input answer.

The replay needs the seed and the recorded inputs. A racing ghost follows the recorded steering on the same generated track.

The record carries the seed and one ordered input log; each claim's comparison reference is carried or recomputed from the record. Playback consumes the seed and log from the declared starting point; changing either creates a different record instance.

The replay needs recorded inputs and one fixed start. A puzzle solution begins from the shared board and repeats the saved moves.

The record carries one fixed-start identity and one ordered input log; each claim's comparison reference is carried or recomputed from the record. Seed identity is not a separate requirement.

Why this is asked

A daily seed recreates a challenge. A racing ghost also needs the driver's recorded inputs.

What happens to a recorded replay after the game updates?

Choices for What happens to a recorded replay after the game updates?
The replay works only in the version that recorded it. A patched racing game labels an older ghost as incompatible.

When the recorded and running version ids differ, refuse the replay before consuming its seed, start, or inputs. Equal version ids do not override failed content, mod, or settings checks.

The game converts the replay before playing it. A puzzle update maps an old move list onto the revised board rules.

When the version ids differ, a cited migration rule derives a new record for the running version while preserving the source record. Playback consumes only a successful migrated record and identifies both versions and the migration used.

The game tries the old replay and states what may differ. An RTS update names changed unit balance before the observer replay starts.

When the version ids differ, the running version consumes the original record after presenting the cited known changes between the versions. Actual differences still follow the divergence-response answer.

Why this is asked

A patch can change rules, content, or timing. The replay needs a clear version promise before playback starts.

What happens at the first difference between the replay and the record?

Choices for What happens at the first difference between the replay and the record?
Stop the replay and report the first difference. A puzzle solution stops on the first move that produces the wrong board.

Do not consume the next recorded input. Report the failed claim, comparison point, expected result, observed result, versions, and platforms, then end playback as diverged.

Keep playing and mark the replay as diverged. An RTS observer can watch the rest after a unit first appears in the wrong place.

Report the first difference, mark playback as diverged, and continue from playback's own state. Later comparisons are informational; they do not replace the first report or resynchronize playback to the reference.

Keep playing without showing the difference. A racing ghost can finish the lap after its position differs from the record by more than the allowed gap.

Mark the difference inside the replay controller, send no report to the player, to the ordinary log, or to telemetry, and continue from playback's own state. Later comparisons are informational and playback remains diverged.

Why this is asked

A replay can stop, continue with a warning, or continue without showing the difference.

Numbers and rules1 number, 1 rule

Numbers

Each setting takes a number, or a reference to a decided number in your tuning. It cannot reference an open number. Stay inside any range shown.

Allowed position gap

allowed-position-gap

The greatest allowed distance between recorded and replayed positions, in the position unit named by every position claim in this adoption.

Range
0 to 1000000
Written as
a number or a reference

Applies when some reproduction claims row has matching standard Allowed position gap.

Rules

  • A replay that the game tries after an update must show its first difference. Choose stop-and-report or continue-and-flag, or choose same-version-only.

    Forbidden when After an update is Best effort with declared divergence and Divergence response is Continue silently.

Lists2 lists

Some settings are lists of rows.

A reference points to a number or a rule in your design. For a number, use the address of a decided number in your tuning, not an open one. For a rule, use its file and heading, such as 02-mechanics.md#recovery. The reference must match exactly one heading in that file. No > DELEGATED: or > PERSONALIZATION: tag may cover any part of the section under that heading. Each field's description says what it needs.

Replay record

replay-record

Give the rules that record and play back this kind of replay. One adoption has exactly one row.

An empty list means: An empty replay-record list is never a behavior choice: this adoption requires exactly one row, and a reviewer rejects a file without it.

Each row is: id, recording-declared-in, input-clock-declared-in, fixed-start-declared-in, migration-declared-in, cross-version-divergence-declared-in, difference-report-declared-in.

Every field
FieldKindWhen it appearsMeaning
id string Required A short name for this kind of replay in your game's words, such as ghost-lap or observer-match. Each finished record of this kind has its own identity. The rules for recording define that identity.
recording-declared-in reference Required Where your game's rules name the start and the end of recording. The same rules set the recording version, the platform, the content-set identity, the settings, the mod identity, and the record's own identity. They name the seed or the fixed start, and the input log when one is used. They say whether each claim's comparison reference is captured at recording or recomputed from the record at playback.
input-clock-declared-in reference Present when Replay record is Seed and input log or Input log from fixed start. Where your game's rules say how recorded inputs are ordered, and which clock, step, or turn is used to play them back.
fixed-start-declared-in reference Present when Replay record is Input log from fixed start. Where your game's rules say how the game identifies the fixed starting state and verifies it before the first input.
migration-declared-in reference Present when After an update is Migrate then replay. Where your game's rules state the deterministic rule that derives the record for the running version. The source record stays unchanged.
cross-version-divergence-declared-in reference Present when After an update is Best effort with declared divergence. Where your game's rules state the known changes that may alter this replay in the running version. The game shows this statement to the player.
difference-report-declared-in reference Required Where your game's rules describe the incompatibility or difference report. Before playback, the report presents a refusal because of the version, the content, the mods, the settings, the start, or the migration. When the selected response is visible, the report presents the first failed claim and the comparison details.

Reproduction claims

reproduction-claims

List one row for each result this replay promises to compare. Rows may share one conditions section when the same conditions apply. A shared section must cover every row that points to it.

An empty list means: This adoption makes no replay promise without at least one result to compare, and a reviewer rejects the empty list.

Each row is: id, artifact, platform-reach, shifts-with-live-input, live-input-dependence-declared-in, matching-standard, reproduces, excludes, conditions, comparison-points.

Every field
FieldKindWhen it appearsMeaning
id string Required A short name for this comparison claim in your game's words, such as car-path or match-state.
artifact string Required The game's plain name for the result that playback compares.
platform-reach choice: recorded-platform-only, every-supported-platform Required Whether this claim is compared only on the recording platform or on every supported platform.
shifts-with-live-input choice: seed-fixes-this-claim, live-input-may-shift-this-claim Present when Replay record is Seed only. Can the player's input during playback change a result that this replay promises? Say whether the seed alone decides this result, or whether live input may change it.
live-input-dependence-declared-in reference Present when row shifts with live input is Live input may shift this claim. Where your game's rules name every fact about the player's earlier live input that may change this result. Live input that the rules do not list does not change the result.
matching-standard choice: bit-exact-state, outcome-equivalent, allowed-position-gap Required What this claim compares: every named state byte, every named outcome field, or position in the named space using the adoption's allowed gap.
reproduces reference Required Where your game's rules name every state byte, outcome field, or position that must match.
excludes reference Required Where your game's rules name what this claim excludes from what it promises to match. This section is separate from the section that names what must match. When nothing is excluded, the section says so.
conditions reference Required Where your game's rules say when the promise holds. The conditions include the content-set identity, the settings, the mods, and every other condition for compatibility or comparison. Content identity is a condition, not a version.
comparison-points reference Required Where your game's rules say when a reference is captured or recomputed and when playback compares it, such as at every simulation checkpoint, at the finish line, or at the solved board.

For builders

Exact wording for builders and 48 pack tests

Exact wording for builders

This text decides the order of the steps for what is recorded, when capture or recomputation happens, what playback consumes, and how differences are detected and handled. The questions and rows supply choices and cited game rules. They do not change the order.

A replay-record row names a replay kind. Each immutable replay record of that kind carries its own stable instance identity under recording-declared-in. It also carries the recording version, platform, content-set identity, settings and mod identity; the chosen seed or fixed start; the ordered input log when selected; and every claim's comparison reference. A reference is either captured at recording or deterministically recomputed from the sealed record at lifecycle step 11. A migrated record is a derived record with its own identity and a link to the unchanged source.

A comparison point is a cited checkpoint at which playback reads a result and obtains the corresponding captured or recomputed reference. A difference is the first eligible comparison that fails that claim's matching standard. The terminal playback result is diverged, rejected, or complete; before a terminal result, playback is in progress. When the game refuses a record or a replay, the result is rejected.

### Record

1. Read the one replay-record row and every reproduction claim. From recording-declared-in, set the recording version, platform, content-set identity, settings, and mod identity before the record begins. They do not change during the recording.

2. Establish the start. A seed-only or seed-and-input record captures the seed before any claimed seeded result is generated. A fixed-start record captures an identity that the cited state rule can verify before playback.

3. Begin input capture at the cited start. A seed-only record captures no inputs. Either input-log record captures each mapped game action with its complete order and cited clock, step, or turn.

4. At every claim's comparison point, either capture the reference required by that claim's matching standard or capture all sealed source data that the cited rule requires to recompute the reference at step 11.

5. End capture at the cited boundary. Seal the record's own instance identity and contents. A later edit creates a different record instance of the same replay kind.

### Select a playable version and claims

6. Before consuming the seed, start, or inputs, read the version, platform, content-set identity, settings, and mod identity carried under recording-declared-in, then read every cited compatibility condition. If a record-wide identity — content, settings, mods, or the fixed start — no longer holds, refuse the record and use the incompatibility report. A failed condition cited by one claim alone exempts only that claim, per steps 7 and 12. Content identity is a condition, not a version; a level-content patch can therefore invalidate a record even when the version id is unchanged.

7. Determine platform reach claim by claim. A claim limited to the recording platform is not compared on another running platform. A claim covering every supported platform is not compared on an unsupported running platform. A claim that is excluded in one of these two ways does not diverge. The other claims continue.

8. Only when the recorded version differs from the running version, apply the selected update policy. same-version-only refuses the record with the incompatibility report. migrate-then-replay runs the cited migration once; success creates a derived record naming source version, target version, and migration rule, and when the migration fails, the game refuses the record. best-effort-with-declared-divergence presents the cited known changes and keeps the source record unchanged. Migration must map the recorded input clock to an existing running-version clock; playback under best-effort-with-declared-divergence refuses the record if the cited clock no longer exists.

### Replay and compare

9. Recreate the start. Supply the recorded seed when present. Verify or restore the fixed starting state when present. Refuse the replay if either required item cannot be established.

10. For an input-log record, consume inputs in their recorded order at their cited clock, step, or turn. For a seed-only record, accept live inputs. A seed-fixes-this-claim result cannot change when those inputs vary. A live-input-may-shift-this-claim result may read only the live-input facts named by its live-input-dependence-declared-in citation.

11. Obtain each claim's comparison reference. Read a reference captured in the record, or deterministically recompute it from the sealed record using the method cited by recording-declared-in and that claim's comparison-points. This is the recomputation step used by a puzzle share whose solved-board reference is derived from its fixed board and move log.

12. At each comparison point, first read the claim's cited conditions. If they are not met, do not compare that claim and do not mark a divergence. The live-input-dependence-declared-in citation of a live-input-may-shift-this-claim result works the same way: a result that differs only as that citation permits is not compared against the recorded reference and does not diverge; where the citation's method recomputes a reference for the actual inputs, step 11's recomputation applies. Otherwise compare with the reference using the row's matching standard. Bit-exact state compares every declared byte. Outcome matching compares every declared outcome field. Position matching measures distance in the cited space and passes when it is no greater than allowed-position-gap. excludes subtracts from reproduces; excluded state is never compared.

This contract makes no promise about changes outside the cited conditions. Such a change does not fail this contract.

### Handle the first difference

13. On the first failed eligible comparison, set the playback result to diverged and retain the claim id, comparison point, expected result, observed result, versions, platforms, and last consumed input when present.

14. Under stop-and-report, present the difference, consume no later input, and end playback. Under continue-and-flag, present the difference, keep a visible diverged mark, and continue. Under continue-silently, emit no outward report and continue. Either continuing route advances from playback's own state. Later comparisons are informational and never resynchronize playback to the recorded reference.

15. If no eligible comparison fails and the record reaches its cited end, set the result to complete. Completion means every comparison actually made matched. It makes no promise about excluded claims, unmet conditions, or excluded state.

Every event offered at the same replay moment enters this lifecycle in the total order supplied by Event resolution. This contract preserves that order but does not choose it.

Verification pack

sha256:bf1143945366c1a44f1715fbfb5ca22c389ccc27b091ac8bc7bbfac64be3593c

The format calls an adoption that has its matching pack Checked. The tests are included, but this does not mean that a game has passed them. An adoption without the pack is Promised. The builder must still build the chosen behavior.

48 pack tests

Placeholders are filled from the adoption's answers, numbers, rows, and test inputs.

Row.id sealed records carry the complete replay identity

sealed-record-carries-replay-identity

scenarioper replay-record row

Applies for every adoption

Each sealed Row.id record has its own instance identity and carries, as named at Row.recording declared in, the replay identity fields and Bind record shape, together with every claim's captured reference or sealed recomputation source. A reference never comes from live play. The test names the address and restates nothing from it.

Given

a sealed record of replay kind Row.id and its manifest at Row.recording declared in

When
  • the record is inspected before playback
Then
  • the record carries its own stable instance identity, recording version, platform, content-set identity, settings and mod identity, Bind record shape, and every reproduction claim's comparison reference or sealed source data for deterministic recomputation
  • each comparison reference is captured during recording or deterministically recomputed from the sealed record, never obtained from live play
Diagnostics
  • Instance-record-manifest
  • Instance-reference-source
a migrated record has its own identity and keeps its source

migrated-record-keeps-source-identity

scenarioper replay-record row

Applies when After an update is Migrate then replay.

A successful migration under Row.migration declared in creates one derived record with its own identity, the two versions, the migration rule, and a link to the unchanged source. The test names the address and restates nothing from it.

Given

a sealed source record of replay kind Row.id and a different running version

When
  • the deterministic migration at Row.migration declared in succeeds
Then
  • one derived record is created with its own stable instance identity and a link to the unchanged source record
  • the derived record names the source version, target version, and migration rule
Diagnostics
  • Instance-record-manifest
  • Instance-migration-record
the terminal playback result uses the closed vocabulary

playback-result-uses-closed-vocabulary

scenarioonce

Applies for every adoption

Instance playback is in progress until it ends. Its terminal playback result is exactly one of diverged, rejected, or complete.

Given

each Instance playback from start until it ends

When
  • the playback result is read before and after termination
Then
  • before termination the playback is in progress
  • at termination the playback result is exactly one of diverged, rejected, or complete, and never two of them
Diagnostics
  • Instance-playback-result
Row.id records its selected start before claimed results

record-establishes-declared-start

scenarioper replay-record row

Applies for every adoption

The recording version, platform, content-set identity, settings, and mod identity are set from Row.recording declared in before the first captured seed, start, or input and do not change during the recording. Row.id then Bind start capture. The test names the address and restates nothing from it.

Given

a new Row.id recording about to begin, with its manifest at Row.recording declared in

When
  • recording establishes its start
Then
  • the recorder Bind start capture
  • the recording version, platform, content-set identity, settings, and mod identity are set from Row.recording declared in before the first captured seed, start, or input and do not change during the recording
Diagnostics
  • Instance-record-manifest
  • Instance-recording-trace
Row.id captures every mapped action in cited order

input-log-captures-complete-action-order

scenarioper replay-record row

Applies when Replay record is Seed and input log or Input log from fixed start.

From the start at Row.recording declared in, Row.id captures every mapped game action in complete order at the clock, step, or turn cited at Row.input clock declared in. The test names both addresses and restates nothing from them.

Given

one Row.id recording with mapped game actions before and after the cited start

When
  • input capture runs from the start named at Row.recording declared in using the clock, step, or turn at Row.input clock declared in
Then
  • every mapped game action after capture begins enters one ordered input log in complete order at the cited clock, step, or turn
  • no action before capture begins enters the log
Diagnostics
  • Instance-input-log-trace
  • Instance-recording-trace
Row.id captures no input log

seed-only-record-captures-no-input

scenarioper replay-record row

Applies when Replay record is Seed only.

A sealed seed-only Row.id record carries its seed and no input log.

Given

a complete Row.id recording with player actions during its lifetime

When
  • the sealed record is inspected
Then
  • the record carries its seed and no recorded input log
Diagnostics
  • Instance-record-manifest
  • Instance-input-log-trace
Row.id records its comparison reference source

claim-records-reference-or-recomputation-source

scenarioper reproduction-claims row

Applies for every adoption

At every point cited at Row.comparison points, recording captures the reference Row.id needs or all sealed data that the cited method of the replay-record row needs to recompute it. The record distinguishes those two sources. The test names the address and restates nothing from it.

Given

recording reaches each Row.id comparison point cited at Row.comparison points

When
  • the recorder handles the claim at that point
Then
  • the record captures the comparison reference required by Row.id's matching standard or all sealed source data required by the cited recomputation method of the replay-record row
  • the record distinguishes a captured reference from sealed recomputation source data
Diagnostics
  • Instance-reference-source
  • Instance-recording-trace
Row.id seals one immutable record at its boundary

record-seals-at-boundary

scenarioper replay-record row

Applies for every adoption

At the boundary cited at Row.recording declared in, Row.id seals its instance identity and contents. Any later edit creates a different instance of the same replay kind. The test names the address and restates nothing from it.

Given

one Row.id recording approaching the end boundary at Row.recording declared in

When
  • capture reaches that boundary and a later edit is requested
Then
  • capture ends at the cited boundary and seals the record's instance identity and contents
  • the later edit creates a different record instance of the same replay kind and leaves the sealed record unchanged
Diagnostics
  • Instance-record-manifest
  • Instance-recording-trace
Row.id checks record-wide identity before consumption

record-wide-identity-precedes-consumption

scenarioper replay-record row

Applies for every adoption

Before consuming a seed, start, or input, Row.id reads the record identity at Row.recording declared in and the cited compatibility conditions. When a record-wide identity that it carries fails, the game refuses the record through Row.difference report declared in; neither an unchanged version id nor the update policy overrides a failed identity. The test names both addresses and restates nothing from them.

Given

sealed Row.id records in which each record-wide identity this adoption carries fails in turn — content-set identity, settings, mods, and the fixed start where present — including a content patch whose version id is unchanged

When
  • playback selection begins
Then
  • the version, platform, content-set identity, settings, and mod identity at Row.recording declared in and every cited compatibility condition are read before any seed, start, or input is consumed
  • for each failed record-wide identity that the adoption carries, the game refuses the record and presents the incompatibility report through Row.difference report declared in before any seed, start, or input is consumed
  • the unchanged version id does not override the failed content identity
  • the update policy does not override a failed identity
Diagnostics
  • Instance-identity-check-trace
  • Instance-rejection-report
  • Instance-input-log-trace
Row.id plays a compatible record

compatible-record-is-played

scenarioper replay-record row

Applies for every adoption

A sealed Row.id record whose complete replay identity matches the running game and whose cited compatibility conditions hold is played and not refused. Playback consumes the seed, start, or inputs that the record carries and reaches the result complete or diverged, never rejected.

Given

a sealed Row.id record whose version, platform, content-set identity, settings, mods, and start all match the running game and whose cited compatibility conditions hold

When
  • playback selection checks the compatible record
Then
  • the game does not refuse the record
  • playback consumes the seed, start, or inputs the record carries
  • playback reaches a terminal result that is complete or diverged, never rejected
Diagnostics
  • Instance-identity-check-trace
  • Instance-playback-result
Row.id compares only on the recording platform

recorded-platform-only-excludes-other-platforms

scenarioper reproduction-claims row

Applies when row platform reach is Recorded platform only.

On another platform, recorded-platform-only claim Row.id is excluded, is not compared, and cannot diverge. Other eligible claims continue where they exist. The comparison log distinguishes exclusion from a match.

Given

a playback on a platform different from the recording platform with Row.id and at least one other eligible claim where the adoption can construct one

When
  • claim platform reach is selected
Then
  • Row.id is not compared and cannot cause divergence
  • every other eligible claim continues; where no other eligible claim exists, this test checks nothing in this step
  • the comparison log records platform exclusion rather than a match
Diagnostics
  • Instance-comparison-log
  • Instance-playback-result
Row.id compares on every supported platform

every-supported-platform-excludes-only-unsupported-platforms

scenarioper reproduction-claims row

Applies when row platform reach is Every supported platform.

Claim Row.id remains eligible on every supported platform. It is excluded without divergence on an unsupported platform, and other eligible claims continue. The comparison log distinguishes exclusion from a match.

Given

Row.id playback on each supported platform and on each unsupported running platform the adoption can construct

When
  • claim platform reach is selected
Then
  • Row.id remains eligible on every supported platform
  • on each constructible unsupported running platform it is not compared and cannot cause divergence, while every other eligible claim continues; where no unsupported running platform can be constructed, this test checks nothing in this step
  • the comparison log distinguishes unsupported-platform exclusion from a match
Diagnostics
  • Instance-platform-matrix
  • Instance-comparison-log
Row.id refuses a record whose version differs from the running version

same-version-only-rejects-version-mismatch

scenarioper replay-record row

Applies when After an update is Same version only.

When version ids differ, same-version-only refuses the Row.id record through Row.difference report declared in before a seed, start, or input is consumed. The test names the address and restates nothing from it.

Given

a sealed Row.id record whose recorded version id differs from the running version id

When
  • the update policy is applied
Then
  • the playback result becomes rejected and the incompatibility report is presented through Row.difference report declared in
  • no seed, start, or input is consumed
Diagnostics
  • Instance-rejection-report
  • Instance-input-log-trace
  • Instance-playback-result
Row.id migrates once or refuses the record

migration-runs-once-before-playback

scenarioper replay-record row

Applies when After an update is Migrate then replay.

For differing versions, Row.id runs Row.migration declared in once. Success creates the derived record, playback consumes only that record, and Bind input clock requirement. When the migration or the clock mapping fails, the game refuses the record through Row.difference report declared in before consumption. For equal version ids, no migration runs, no derived record is created, and playback consumes the source record. The test names both addresses and restates nothing from them.

Given

sealed Row.id records whose version ids are equal to and differ from the running version, including successful and failed migration and each input-log record this adoption can construct with and without a running-version clock mapping

When
  • playback selection applies the update policy at Row.migration declared in
Then
  • when the recorded and running version ids differ, the migration rule runs once; success creates the derived record and playback consumes only that derived record
  • when the recorded and running version ids are equal, no migration runs, no derived record is created, and playback consumes the source record
  • Bind input clock requirement
  • after a failed migration, or a failed clock mapping where an input clock exists, the game refuses the record through Row.difference report declared in before any seed, start, or input is consumed
Diagnostics
  • Instance-migration-record
  • Instance-rejection-report
  • Instance-input-log-trace
Row.id presents the known changes between versions before playback

best-effort-presents-known-differences

scenarioper replay-record row

Applies when After an update is Best effort with declared divergence.

For differing versions, best-effort-with-declared-divergence presents the known changes at Row.cross version divergence declared in before playback consumes the unchanged source record; Bind input clock requirement. When the running version no longer has the cited clock, the game refuses the record through Row.difference report declared in before an input is consumed. For equal version ids, the cross-version notice is not presented and playback proceeds on the source record. Where the game does not refuse the record, every difference follows the divergence response. The test names both addresses and restates nothing from them.

Given

sealed Row.id source records whose version ids are equal to and differ from the running version and, for each record with a cited input clock, running versions where that clock exists and no longer exists

When
  • playback selection under best-effort-with-declared-divergence applies the update policy at Row.cross version divergence declared in
Then
  • when the version ids differ, the cited known changes are presented before playback consumes the source record, and the source record remains unchanged
  • when the version ids are equal, the cross-version notice is not presented and playback proceeds on the source record
  • for a differing version, Bind input clock requirement
  • where the record carries a cited input clock and that clock no longer exists, the game refuses the record through Row.difference report declared in before an input is consumed
  • where the game does not refuse the record, a later difference follows the selected divergence response
Diagnostics
  • Instance-cross-version-notice
  • Instance-record-manifest
  • Instance-rejection-report
Row.id supplies the recorded seed or refuses the replay

seeded-playback-recreates-start

scenarioper replay-record row

Applies when Replay record is Seed only or Seed and input log.

Seeded Row.id playback supplies the recorded seed before generating a claimed seeded result. If the seed cannot be established, the game refuses the replay before any input is consumed.

Given

a playable Row.id record, once with its recorded seed available and once with the required seed unavailable

When
  • playback recreates the start
Then
  • the available run supplies the recorded seed before generating a claimed seeded result
  • the playback result of the unavailable run becomes rejected before any input is consumed
Diagnostics
  • Instance-start-trace
  • Instance-playback-result
Row.id verifies or restores the fixed start

fixed-start-playback-verifies-or-restores

scenarioper replay-record row

Applies when Replay record is Input log from fixed start.

Fixed-start Row.id playback verifies or restores the fixed starting state of the record playback consumes, which is the derived record wherever a migration ran, through Row.fixed start declared in before the first input. If playback cannot establish the state, the game refuses the replay. The test names the address and restates nothing from it.

Given

a playable Row.id record, once with its fixed start available and once with it unavailable

When
  • playback applies the state rule at Row.fixed start declared in
Then
  • the available run verifies or restores the fixed starting state of the record playback consumes, which is the derived record wherever a migration ran, before the first input
  • the playback result of the unavailable run becomes rejected before any input is consumed
Diagnostics
  • Instance-start-trace
  • Instance-playback-result
Row.id consumes recorded inputs in cited order

input-log-playback-consumes-cited-order

scenarioper replay-record row

Applies when Replay record is Seed and input log or Input log from fixed start.

Row.id playback consumes the recorded input log once, in its recorded order, at the clock, step, or turn cited at Row.input clock declared inBind clock after migration. The test names the address and restates nothing from it.

Given

a playable Row.id record with distinct mapped actions in its input log

When
  • playback runs at the clock, step, or turn cited at Row.input clock declared in
Then
  • every recorded input is consumed once in recorded order at the clock, step, or turn cited at Row.input clock declared inBind clock after migration
  • no live input replaces or reorders a recorded action
Diagnostics
  • Instance-input-log-trace
  • Instance-playback-result
Row.id accepts live input without a recorded log

seed-only-playback-accepts-live-input

scenarioper replay-record row

Applies when Replay record is Seed only.

Seed-only Row.id playback accepts live input and consumes no recorded input log. Each claim follows its own live-input answer.

Given

playable Row.id records with the same seed and different live input histories

When
  • playback runs
Then
  • each run accepts its live inputs and consumes no recorded input log
  • each reproduction claim follows its own live-input answer
Diagnostics
  • Instance-live-input-trace
  • Instance-comparison-log
Row.id cannot change when live inputs vary

seed-fixed-claim-ignores-live-input-variation

scenarioper reproduction-claims row

Applies when row shifts with live input is Seed fixes this claim.

With the same sealed seed-only record, varying live inputs cannot change Row.id at the points cited at Row.comparison points. The test names the address and restates nothing from it.

Given

playbacks from the same sealed seed-only record with different live input histories

When
  • Row.id is read at each comparison point at Row.comparison points
Then
  • the result named for Row.id does not change between runs
Diagnostics
  • Instance-live-input-trace
  • Instance-comparison-log
Row.id reads only its cited live-input facts

live-input-shifted-claim-reads-only-cited-facts

scenarioper reproduction-claims row

Applies when row shifts with live input is Live input may shift this claim.

Claim Row.id reads no live-input fact outside Row.live input dependence declared in. A difference permitted there is not compared and does not diverge; if that rule recomputes the actual-input reference, deterministic recomputation happens first. Comparison points are at Row.comparison points. The test names both addresses and restates nothing from them.

Given

playbacks from the same sealed seed-only record whose live input histories vary inside and outside the facts at Row.live input dependence declared in

When
  • Row.id reaches each comparison point at Row.comparison points
Then
  • the claimed result reads no live-input fact outside Row.live input dependence declared in
  • a result differing only as that citation permits is recorded as not compared and does not diverge
  • where that citation recomputes a comparison reference for the actual inputs, the reference is deterministically recomputed from the sealed record before comparison
Diagnostics
  • Instance-live-input-trace
  • Instance-reference-source
  • Instance-comparison-log
Row.id obtains its reference from the sealed record

claim-reference-comes-from-sealed-record

scenarioper reproduction-claims row

Applies for every adoption

At Row.comparison points, Row.id reads a captured comparison reference or deterministically recomputes it from the sealed record through the cited method of the replay-record row. The reference-source record distinguishes the two and proves live play supplied neither. Where the adoption cannot construct one of the two forms, this test checks nothing for that form. The test names the address and restates nothing from it.

Given

Row.id playbacks using a captured reference and, where the adoption can construct one, a deterministically recomputed reference

When
  • playback reaches the points at Row.comparison points
Then
  • the reference is read from the sealed record or deterministically recomputed from it using the cited method of the replay-record row and Row.comparison points
  • the reference-source record distinguishes capture from recomputation and proves no reference was read from live play
  • where the adoption cannot construct one of the two reference forms, this test checks nothing for that form
Diagnostics
  • Instance-reference-source
  • Instance-comparison-log
Row.id reads conditions before comparison

unmet-claim-condition-skips-comparison

scenarioper reproduction-claims row

Applies for every adoption

At each constructible point where Row.conditions is not met, Row.id is not compared and does not diverge. The game does not refuse the record and does not make playback terminal because of that condition alone. Every other eligible claim, where the adoption declares one, is still compared at its own points, and the logs distinguish the skip from a match. If no such point exists, this test checks nothing. The test names the address and restates nothing from it.

Given

each Row.id comparison point this adoption can construct where the conditions at Row.conditions are not met

When
  • playback reaches that point
Then
  • the conditions are read before a comparison is attempted
  • the claim is recorded as not compared and does not mark a divergence
  • the game does not refuse the record, and playback does not become terminal, because of that claim's unmet condition alone
  • every other eligible claim is still compared at its own comparison points; where no other eligible claim exists, this test checks nothing in this step
  • where no unmet-condition point can be constructed, this test checks nothing
Diagnostics
  • Instance-condition-trace
  • Instance-comparison-log
  • Instance-playback-result
Row.id compares every included byte

bit-exact-claim-compares-declared-bytes

scenarioper reproduction-claims row

Applies when row matching standard is Bit exact state.

Bit-exact claim Row.id compares every byte named at Row.reproduces after subtracting Row.excludes. Excluded state is never compared. The test names both addresses and restates nothing from them.

Given

eligible Row.id comparisons with each included byte changed in turn and, where Row.excludes names excluded state, that state changed separately

When
  • playback compares the result to its comparison reference
Then
  • every state byte named at Row.reproduces after subtracting Row.excludes is compared bit for bit
  • each changed included byte fails the matching standard; changed excluded state is never compared; where the cited section says that nothing is excluded, this test checks nothing about excluded state
Diagnostics
  • Instance-comparison-log
  • Instance-reference-source
Row.id compares every included outcome field

outcome-equivalent-claim-compares-declared-fields

scenarioper reproduction-claims row

Applies when row matching standard is Outcome equivalent.

Outcome-equivalent claim Row.id compares every outcome field named at Row.reproduces after subtracting Row.excludes. Excluded state is never compared. The test names both addresses and restates nothing from them.

Given

eligible Row.id comparisons with each included outcome field changed in turn and, where Row.excludes names excluded state, that state changed separately

When
  • playback compares the result to its comparison reference
Then
  • every outcome field named at Row.reproduces after subtracting Row.excludes is compared
  • each changed included field fails the matching standard; changed excluded state is never compared; where the cited section says that nothing is excluded, this test checks nothing about excluded state
Diagnostics
  • Instance-comparison-log
  • Instance-reference-source
Row.id passes only within the declared allowed gap

position-claim-uses-adoption-gap

scenarioper reproduction-claims row

Applies when row matching standard is Allowed position gap.

Position claim Row.id measures distance in the space at Row.reproduces, subtracts Row.excludes, and passes exactly when the distance is no greater than the declared allowed gap at Value cite allowed position gap. Every position claim in this adoption uses that one value. The test names the addresses and restates neither the gap nor the cited rules.

Given

eligible Row.id comparisons whose distance in the space cited at Row.reproduces is below, equal to, and above the value at Value cite allowed position gap

When
  • playback applies the allowed-position-gap matching standard
Then
  • the measured distance uses the cited space and excludes the state at Row.excludes
  • the comparison passes exactly when the distance is no greater than the declared allowed gap and fails when it is greater
  • every position claim in this adoption reads the same adoption-wide value at Value cite allowed position gap
Diagnostics
  • Instance-comparison-log
  • Instance-allowed-gap-source
the Row.artifact result repeats from the declared seed record

seed-fixed-claim-repeats-from-declared-record

generalper reproduction-claims row

Applies when Replay record is Seed only and row shifts with live input is Seed fixes this claim.

Across Inputs scope, the Row.artifact result from the same sealed seed-only record satisfies Row.id's matching standard at Row.comparison points whenever the conditions at Row.conditions hold. The test names both addresses and restates nothing from them.

Holds

for every case in scope where the conditions at Row.conditions hold, playback using the same sealed seed-only record satisfies Row.id's selected matching standard at the points cited at Row.comparison points

Seeds

Inputs seeds

Scope

Inputs scope

Diagnostics
  • Instance-record-manifest
  • Instance-comparison-log
the Row.artifact result repeats within its cited live-input rule

live-input-shifted-claim-repeats-within-cited-rule

generalper reproduction-claims row

Applies when Replay record is Seed only and row shifts with live input is Live input may shift this claim.

Across Inputs scope, a Row.artifact case is eligible where the conditions at Row.conditions hold and no difference permitted by Row.live input dependence declared in applies. In every eligible case, playback from the same sealed seed-only record satisfies the claim's matching standard at Row.comparison points. A result that differs only as the live-input citation permits is recorded as not compared. The test names the addresses and restates nothing from them.

Holds

for every case in scope where the conditions at Row.conditions hold and no difference permitted by Row.live input dependence declared in applies, playback from the same sealed seed-only record satisfies the claim's matching standard at the points cited at Row.comparison points; a result that differs only as that citation permits is recorded as not compared

Seeds

Inputs seeds

Scope

Inputs scope

Diagnostics
  • Instance-record-manifest
  • Instance-condition-trace
  • Instance-live-input-trace
  • Instance-comparison-log
the Row.artifact result repeats from the declared seed and input record

seed-and-input-claim-repeats-from-declared-record

generalper reproduction-claims row

Applies when Replay record is Seed and input log.

Across Inputs scope, the Row.artifact result from the same sealed seed and ordered input log satisfies Row.id's matching standard at Row.comparison points whenever the claim is eligible. The test names the address and restates nothing from it.

Holds

for every eligible case for the Row.artifact result in scope, playback using the same sealed seed and ordered input log satisfies Row.id's selected matching standard at the points cited at Row.comparison points

Seeds

Inputs seeds

Scope

Inputs scope

Diagnostics
  • Instance-record-manifest
  • Instance-input-log-trace
  • Instance-comparison-log
the Row.artifact result repeats from the declared fixed start and input record

fixed-start-input-claim-repeats-from-declared-record

generalper reproduction-claims row

Applies when Replay record is Input log from fixed start.

Across Inputs scope, the Row.artifact result from the same sealed fixed-start identity and ordered input log satisfies Row.id's matching standard at Row.comparison points whenever the claim is eligible. The test names the address and restates nothing from it.

Holds

for every eligible case for the Row.artifact result in scope, playback using the same sealed fixed-start identity and ordered input log satisfies Row.id's selected matching standard at the points cited at Row.comparison points

Seeds

Inputs seeds

Scope

Inputs scope

Diagnostics
  • Instance-record-manifest
  • Instance-input-log-trace
  • Instance-comparison-log
changes outside cited conditions do not fail this contract

outside-conditions-make-no-promise

scenarioonce

Applies for every adoption

A change outside the cited conditions is never itself a reason to refuse a record or to mark a divergence. A divergence arises only when a claimed result fails its comparison at an eligible comparison point. If the adoption can construct no such change, this test checks nothing.

Given

each change outside the cited conditions that the Instance adoption can construct

When
  • the change is observed during playback
Then
  • no change outside the cited conditions is itself a reason for refusal or for a divergence mark; a divergence arises only from a failed comparison of a claimed result at an eligible comparison point
  • where no such change can be constructed, this test checks nothing
Diagnostics
  • Instance-condition-trace
  • Instance-comparison-log
  • Instance-playback-result
Row.id retains the first failed eligible comparison

first-difference-retains-complete-record

scenarioper replay-record row

Applies for every adoption

At the first failed eligible comparison, Row.id becomes diverged and retains the claim, point, expected and observed results, versions, platforms, and last consumed input when present. The records distinguish failure from a skipped comparison.

Given

one Row.id playback with a first failed eligible comparison, with a last consumed input where this record has one

When
  • the comparison fails its claim's matching standard
Then
  • the playback result becomes diverged at that first difference
  • the retained divergence record holds the claim id, comparison point, expected result, observed result, recorded and running versions, recorded and running platforms, and last consumed input when present
  • the retained record distinguishes this failed comparison from a skipped comparison
Diagnostics
  • Instance-divergence-record
  • Instance-playback-result
  • Instance-comparison-log
Row.id reports and stops at the first difference

stop-and-report-ends-at-first-difference

scenarioper replay-record row

Applies when Divergence response is Stop and report.

At the first difference, Row.id presents the retained difference through Row.difference report declared in, consumes no later input, and ends diverged. The test names the address and restates nothing from it.

Given

one Row.id playback whose next eligible comparison is its first difference, with a later recorded or live input where playback can have one

When
  • the difference is retained
Then
  • the difference is presented through Row.difference report declared in before any later input is consumed
  • no later input is consumed and playback ends with result diverged
Diagnostics
  • Instance-divergence-record
  • Instance-difference-report
  • Instance-input-log-trace
Row.id reports and continues from playback state

continue-and-flag-keeps-visible-divergence

scenarioper replay-record row

Applies when Divergence response is Continue and flag.

At the first difference, Row.id presents it through Row.difference report declared in before the next input, keeps a visible diverged mark, and continues from playback's own state. The test names the address and restates nothing from it.

Given

one Row.id playback at its first difference with later playback remaining

When
  • the difference is retained
Then
  • the difference is presented through Row.difference report declared in before the next input is consumed
  • a visible diverged mark remains and playback continues from its own state
Diagnostics
  • Instance-divergence-record
  • Instance-difference-report
  • Instance-playback-result
Row.id continues with an internal diverged mark

continue-silently-keeps-internal-divergence

scenarioper replay-record row

Applies when Divergence response is Continue silently.

At the first difference, Row.id marks the difference inside the replay controller, sends no report to the player, to the ordinary log, or to telemetry, and continues from playback's own state. It remains diverged.

Given

one Row.id playback at its first difference with later playback remaining

When
  • the difference is retained
Then
  • the replay controller marks the difference internally, sends no report to the player, to the ordinary log, or to telemetry, and continues from playback's own state
  • the playback result remains diverged rather than appearing complete
Diagnostics
  • Instance-divergence-record
  • Instance-outward-report-audit
  • Instance-playback-result
later comparisons are informational only

later-comparisons-never-resynchronize

scenarioonce

Applies when Divergence response is Continue and flag or Continue silently.

For each constructible continuing run, later comparisons are informational: they do not replace the first difference or resynchronize playback to a reference. Playback advances from its own state. For a continuing run with no later comparison point, this test checks nothing.

Given

each continuing Instance playback that can construct a first difference, with and without later comparison points

When
  • playback continues after the first difference
Then
  • later comparisons are retained as informational and never replace the first difference
  • playback is never resynchronized to a comparison reference and advances only from its own state
  • where a continuing run has no later comparison point, this test checks nothing for that run
Diagnostics
  • Instance-divergence-record
  • Instance-comparison-log
  • Instance-playback-state-trace
complete means every comparison actually made matched

complete-means-all-made-comparisons-matched

scenarioper replay-record row

Applies for every adoption

When Row.id reaches its end at Row.recording declared in without an eligible failure, complete means every comparison actually made matched. It promises nothing about excluded claims, unmet conditions, or excluded state, which the log distinguishes from matches. The test names the address and restates nothing from it.

Given

one Row.id record reaching the end boundary at Row.recording declared in with no failed eligible comparison

When
  • the terminal playback result is assigned
Then
  • the playback result becomes complete exactly when every comparison actually made matched
  • the comparison log separately records excluded claims, unmet conditions, and excluded state, and complete makes no promise about them
Diagnostics
  • Instance-playback-result
  • Instance-comparison-log
same-moment events preserve Event resolution order

same-moment-events-preserve-event-resolution-order

scenarioonce

Applies for every adoption

Events at the same replay moment enter in the total order Event resolution supplies. The replay lifecycle introduces no reordering of its own between the supplied order and processing.

Given

two or more events offered at the same Instance replay moment in a known total order from Event resolution

When
  • the events enter the replay lifecycle
Then
  • the lifecycle processes them in exactly the supplied total order
  • the replay lifecycle introduces no reordering of its own between the supplied order and processing
Diagnostics
  • Instance-event-order-trace
declaration check: the adoption declares exactly one replay-record row

adoption-declares-exactly-one-replay-record

scenarioonce

Applies for every adoption

This declaration check reads the adoption, not the running game. A legal adoption has exactly one replay-record row. With any other count, the adoption is invalid, and this test fails. The validator does not enforce the maximum.

Given

the Instance adoption document, not the running game

When
  • a reviewer counts replay-record rows
Then
  • the adoption has exactly one replay-record row; with zero rows or more than one row, the adoption is invalid, and this test fails
Diagnostics
  • Instance-declaration-record
declaration check: the adoption declares at least one reproduction claim

adoption-declares-at-least-one-reproduction-claim

scenarioonce

Applies for every adoption

This declaration check reads the adoption, not the running game. A legal adoption has at least one reproduction claim. With an empty claim list, the adoption is invalid, and this test fails. The validator does not enforce the minimum.

Given

the Instance adoption document, not the running game

When
  • a reviewer counts reproduction-claims rows
Then
  • the adoption has at least one reproduction-claims row; with an empty list, the adoption is invalid, and this test fails
Diagnostics
  • Instance-declaration-record
declaration check: Row.id's matching standard agrees with its cited prose

claim-standard-agrees-with-cited-prose

scenarioper reproduction-claims row

Applies for every adoption

This declaration check reads the adoption and Row.reproduces with Row.excludes, not the running game. The cited prose must describe the kind of result selected by Row.id's matching standard. With any other pairing, the adoption is invalid, and this test fails. The test names both addresses and restates nothing from them.

Given

the Instance adoption and the prose at Row.reproduces and Row.excludes, not the running game

When
  • a reviewer compares the selected matching-standard with the included and excluded result description
Then
  • the prose names bytes for bit-exact-state, outcome fields for outcome-equivalent, or positions and their space for allowed-position-gap, matching the row's selected standard
  • with any disagreement, the adoption is invalid, and this test fails
Diagnostics
  • Instance-declaration-record
declaration check: Row.id was tested on more than one platform

every-platform-claim-has-multiple-platform-evidence

scenarioper reproduction-claims row

Applies when row platform reach is Every supported platform.

This declaration check reads the adoption and existing verification evidence, not the running game. Every-supported-platform claim Row.id is legal only with evidence from more than one supported platform. With narrower evidence, the adoption is invalid, and this test fails.

Given

the Instance adoption and its verification evidence, not a new running-game execution

When
  • a reviewer checks the evidence for every-supported-platform claim Row.id
Then
  • the evidence records this claim tested on more than one supported platform; with one platform or none, the adoption is invalid, and this test fails
Diagnostics
  • Instance-platform-matrix
  • Instance-declaration-record
declaration check: Row.id has a separate exclusions section

claim-excludes-cites-separate-section

scenarioper reproduction-claims row

Applies for every adoption

This declaration check reads the adoption and cited prose, not the running game. Row.excludes must be a section separate from Row.reproduces and must name exclusions or explicitly say there are none. With any other shape, the adoption is invalid, and this test fails. The test names both addresses and restates nothing from them.

Given

the Instance adoption and the prose at Row.reproduces and Row.excludes, not the running game

When
  • a reviewer checks the two cited sections
Then
  • Row.excludes names a section separate from Row.reproduces and that section names every exclusion or states explicitly that nothing is excluded
  • with a shared section, an omitted exclusion, or no statement when nothing is excluded, the adoption is invalid, and this test fails
Diagnostics
  • Instance-declaration-record
declaration check: each of Row.id's four required citations names what its field requires

claim-citations-state-their-own-duties

scenarioper reproduction-claims row

Applies for every adoption

This declaration check reads the adoption and cited prose, not the running game. Row.reproduces, Row.excludes, Row.conditions, and Row.comparison points must respectively state the included result, separate exclusions, conditions, and reference and comparison points. With any wrong meaning, the adoption is invalid, and this test fails. The test names every address and restates nothing from them.

Given

the Instance adoption and the prose at Row.reproduces, Row.excludes, Row.conditions, and Row.comparison points, not the running game

When
  • a reviewer checks the meaning of each required citation
Then
  • the four addresses respectively name the included result, the separate exclusions, the promise conditions, and the capture-or-recomputation and comparison points
  • with a citation that has another meaning, the adoption is invalid, and this test fails
Diagnostics
  • Instance-declaration-record
declaration check: Row.id cites its live-input dependence rule

live-input-shifted-claim-cites-dependence-rule

scenarioper reproduction-claims row

Applies when row shifts with live input is Live input may shift this claim.

This declaration check reads the adoption and Row.live input dependence declared in, not the running game. A live-input-sensitive Row.id claim is legal only when that citation names every permitted input-history fact and excludes all others. With any other shape, the adoption is invalid, and this test fails. The test names the address and restates nothing from it.

Given

the Instance adoption and the prose at Row.live input dependence declared in, not the running game

When
  • a reviewer checks live-input-may-shift-this-claim row Row.id
Then
  • the citation names every live-input history fact allowed to change this claimed result, and unlisted live input is excluded
  • with a missing citation or a citation that has another meaning, the adoption is invalid, and this test fails
Diagnostics
  • Instance-declaration-record
declaration check: Row.id's shared conditions section covers every citing claim

shared-conditions-section-covers-every-citing-claim

scenarioper reproduction-claims row

Applies for every adoption

This declaration check reads the adoption and the cited prose at Row.conditions, not the running game. A section cited by more than one claim states the conditions for every citing claim by name. With a shared section that covers only some citing claims, the adoption is invalid, and this test fails. Where no other claim cites the section, this test checks nothing.

Given

the Instance adoption and the cited prose at Row.conditions, not the running game

When
  • a reviewer checks every reproduction claim that cites the same conditions section
Then
  • where the section at Row.conditions is also cited by another claim in this adoption, it states the conditions for each citing claim by name
  • where no other claim cites it, this test checks nothing
  • with a shared section that covers only some citing claims, the adoption is invalid, and this test fails
Diagnostics
  • Instance-declaration-record
declaration check: Row.id's position gap unit matches its cited space

position-gap-unit-matches-cited-space

scenarioper reproduction-claims row

Applies when row matching standard is Allowed position gap.

This declaration check reads the adoption and the cited prose at Row.reproduces and Value cite allowed position gap, not the running game. The cited space names a position unit, and the adoption's gap value, whether a number or a cited rule, is one distance in that unit. With any other pairing, the adoption is invalid, and this test fails.

Given

the Instance adoption and the cited prose at Row.reproduces and Value cite allowed position gap, not the running game

When
  • a reviewer compares the cited position space with the adoption's allowed gap value
Then
  • the space cited at Row.reproduces names a position unit, and the adoption's gap value at Value cite allowed position gap, whether a number or a cited rule, is one distance in that unit
  • with any other pairing, the adoption is invalid, and this test fails
Diagnostics
  • Instance-declaration-record
the replay mechanism holds for the whole run

replay-holds

generalonce

Applies for every adoption

Across Inputs scope, every playback enters the mechanism's stages in order, leaves them only at a terminal result, and never revisits an earlier stage. References never come from live play; rejected or diverged playback consumes no forbidden input; each terminal result is exactly diverged, rejected, or complete. The pack's default audit seeds apply unless the adoption supplies its own.

Holds

every playback entered the mechanism's numbered stages in order, left them only at a terminal result, and never revisited an earlier stage; no comparison read a comparison reference from live play; no rejected or diverged playback consumed an input that its selected response or its refusal forbade it to consume; every terminal playback result was exactly one of diverged, rejected, or complete

Seeds

Inputs seeds

Scope

Inputs scope

Diagnostics
  • Instance-recording-trace
  • Instance-identity-check-trace
  • Instance-reference-source
  • Instance-comparison-log
  • Instance-input-log-trace
  • Instance-playback-result
  • Instance-first-ordering-violation

Use this contract in your package ↑