Ordering & resolution

Dodge roll invulnerability

dodge-roll-invulnerability · an adoption of Timed window, version 2

Tests included

Use in your package

The first button opens the authoring tool with these answers and numbers already filled in. You still add the rules and tuning of your own game.

What is in the zip file

The zip file holds the adoption 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/.

The contract that this adoption uses

This contract covers named timed windows, such as invulnerability, cooldowns, status effects, and restart locks. It says what happens when a window's opening occurs again while the window is open (a repeat opening), when play is suspended, when the window ends early, and when it expires. This contract does not cover what opens each window or how long each window lasts.

Read the full Timed window contract →

Questions

The supplied answer is marked on each question. Pick other answers to see what changes. Nothing is saved here: the zip file and the authoring tool use the supplied answers.

Numbersno numbers

This contract has no numbers to set.

Rulesno rules

A rule is a check between the numbers. Validation reports a rule that fails.

This contract has no rules between its numbers.

Lists1 list

Each list holds the rows this adoption supplies. A list can be empty.

Windows

windows

IdOpens atDurationDuration unitClockWhile suspendedOn retriggerRetrigger capEnds earlyEarly end
dodge-roll-i-frames02-mechanics.md#dodge-roll-startplayer.dodge_roll_iframe_secondsseconds02-mechanics.md#real-time-clockstopsignore—expiry-only—
dodge-roll-cooldown02-mechanics.md#dodge-roll-startplayer.dodge_roll_cooldown_secondsseconds02-mechanics.md#real-time-clockstopsignore—expiry-only—
Test inputsscope and seeds

Some tests need a scope or seeds from the adoption before they can run.

declared-window-set

Declared window set

Scope
the player's dodge-roll windows: invulnerability from roll start through 400 milliseconds (0.4 seconds), and cooldown from roll start through 800 milliseconds (0.8 seconds); the four-unit and six-unit numbers in the suspension check are neutral teaching units, not this game's timing
Acceptance tests9 tests apply

The contract comes with 7 tests. A test that runs once per row is counted once for each row. Tests that do not apply to these answers are still listed, with the reason.

declared-window-set

the declared window list matches the game

generalonce

Applies to dodge-roll-invulnerability.

The window list in dodge-roll-invulnerability is complete for the player's dodge-roll windows: invulnerability from roll start through 400 milliseconds (0.4 seconds), and cooldown from roll start through 800 milliseconds (0.8 seconds); the four-unit and six-unit numbers in the suspension check are neutral teaching units, not this game's timing: every window in scope has one row, no window has two rows, and no row names something outside the scope.

Test steps and diagnostics
Scope

the player's dodge-roll windows: invulnerability from roll start through 400 milliseconds (0.4 seconds), and cooldown from roll start through 800 milliseconds (0.8 seconds); the four-unit and six-unit numbers in the suspension check are neutral teaching units, not this game's timing

Holds

every timed window in scope has exactly one row in dodge-roll-invulnerability, and every row in dodge-roll-invulnerability names a timed window in scope

opens-and-expires · dodge-roll-i-frames

dodge-roll-i-frames opens and expires on its declared clock

scenarioper windows row

Applies to the dodge-roll-i-frames row.

dodge-roll-i-frames opens on the occurrence defined at 02-mechanics.md#dodge-roll-start, reads its seconds duration from player.dodge_roll_iframe_seconds, and closes after that much progress on the clock defined at 02-mechanics.md#real-time-clock.

Test steps and diagnostics
Given

the dodge-roll-i-frames window closed, with its opening defined at 02-mechanics.md#dodge-roll-start, its duration at player.dodge_roll_iframe_seconds in seconds, and its clock at 02-mechanics.md#real-time-clock

When
  • the opening defined at 02-mechanics.md#dodge-roll-start occurs once, with no repeat opening and no declared early ending
Then
  • dodge-roll-i-frames becomes open when that occurrence happens
  • a change to the value or calculation at player.dodge_roll_iframe_seconds after that moment does not move this copy's endpoint; the copy still closes after the duration read at opening
  • it is still open when the clock at 02-mechanics.md#real-time-clock has advanced by exactly that duration
  • it is closed at the first observable step after the clock has advanced beyond that duration
Diagnostics
  • dodge-roll-invulnerability-dodge-roll-i-frames-open-close-trace
  • dodge-roll-invulnerability-dodge-roll-i-frames-clock-trace

opens-and-expires · dodge-roll-cooldown

dodge-roll-cooldown opens and expires on its declared clock

scenarioper windows row

Applies to the dodge-roll-cooldown row.

dodge-roll-cooldown opens on the occurrence defined at 02-mechanics.md#dodge-roll-start, reads its seconds duration from player.dodge_roll_cooldown_seconds, and closes after that much progress on the clock defined at 02-mechanics.md#real-time-clock.

Test steps and diagnostics
Given

the dodge-roll-cooldown window closed, with its opening defined at 02-mechanics.md#dodge-roll-start, its duration at player.dodge_roll_cooldown_seconds in seconds, and its clock at 02-mechanics.md#real-time-clock

When
  • the opening defined at 02-mechanics.md#dodge-roll-start occurs once, with no repeat opening and no declared early ending
Then
  • dodge-roll-cooldown becomes open when that occurrence happens
  • a change to the value or calculation at player.dodge_roll_cooldown_seconds after that moment does not move this copy's endpoint; the copy still closes after the duration read at opening
  • it is still open when the clock at 02-mechanics.md#real-time-clock has advanced by exactly that duration
  • it is closed at the first observable step after the clock has advanced beyond that duration
Diagnostics
  • dodge-roll-invulnerability-dodge-roll-cooldown-open-close-trace
  • dodge-roll-invulnerability-dodge-roll-cooldown-clock-trace

retrigger-behavior · dodge-roll-i-frames

dodge-roll-i-frames handles a repeat opening in the declared way

generalper windows row

Applies to the dodge-roll-i-frames row.

Repeat openings of dodge-roll-i-frames follow one rule: a repeat opening leaves the open copy and its remaining time unchanged and opens no new copy; in a worked trace with four units left, four remain. The worked arithmetic makes the meaning exact, even when the game's own duration uses another number or unit.

Test steps and diagnostics
Scope

repeat openings of dodge-roll-i-frames while at least one copy is open

Holds

a repeat opening leaves the open copy and its remaining time unchanged and opens no new copy; in a worked trace with four units left, four remain

Diagnostics
  • dodge-roll-invulnerability-dodge-roll-i-frames-trigger-trace
  • dodge-roll-invulnerability-dodge-roll-i-frames-remaining-time-trace
  • dodge-roll-invulnerability-dodge-roll-i-frames-open-copy-count

retrigger-behavior · dodge-roll-cooldown

dodge-roll-cooldown handles a repeat opening in the declared way

generalper windows row

Applies to the dodge-roll-cooldown row.

Repeat openings of dodge-roll-cooldown follow one rule: a repeat opening leaves the open copy and its remaining time unchanged and opens no new copy; in a worked trace with four units left, four remain. The worked arithmetic makes the meaning exact, even when the game's own duration uses another number or unit.

Test steps and diagnostics
Scope

repeat openings of dodge-roll-cooldown while at least one copy is open

Holds

a repeat opening leaves the open copy and its remaining time unchanged and opens no new copy; in a worked trace with four units left, four remain

Diagnostics
  • dodge-roll-invulnerability-dodge-roll-cooldown-trigger-trace
  • dodge-roll-invulnerability-dodge-roll-cooldown-remaining-time-trace
  • dodge-roll-invulnerability-dodge-roll-cooldown-open-copy-count

retrigger-extends-to-cap

Row.id extends at a repeat opening without passing its cap

generalper windows row

Does not apply to dodge-roll-invulnerability: no row in windows matches on-retrigger extend to cap.

expiry-is-the-only-ending · dodge-roll-i-frames

dodge-roll-i-frames cannot end early

generalper windows row

Applies to the dodge-roll-i-frames row.

dodge-roll-i-frames has no early ending: using it, removing related state, or changing the world does not close it. When a repeat opening changes the remaining time, that change is not an early closure. Only the end of its duration closes the copy.

Test steps and diagnostics
Scope

the finite list of events and world changes that the game's Fixed prose associates with dodge-roll-i-frames, plus its game-local acceptance-test sample of ordinary play while a copy is open with time remaining

Holds

no event or world change in scope closes any open dodge-roll-i-frames copy before its duration ends; a copy's remaining time changes only through ordinary progress on the clock at 02-mechanics.md#real-time-clock or through this row's declared repeat-opening behavior; when a repeat opening changes the remaining time, that change is not an early closure

Diagnostics
  • dodge-roll-invulnerability-dodge-roll-i-frames-open-close-trace

expiry-is-the-only-ending · dodge-roll-cooldown

dodge-roll-cooldown cannot end early

generalper windows row

Applies to the dodge-roll-cooldown row.

dodge-roll-cooldown has no early ending: using it, removing related state, or changing the world does not close it. When a repeat opening changes the remaining time, that change is not an early closure. Only the end of its duration closes the copy.

Test steps and diagnostics
Scope

the finite list of events and world changes that the game's Fixed prose associates with dodge-roll-cooldown, plus its game-local acceptance-test sample of ordinary play while a copy is open with time remaining

Holds

no event or world change in scope closes any open dodge-roll-cooldown copy before its duration ends; a copy's remaining time changes only through ordinary progress on the clock at 02-mechanics.md#real-time-clock or through this row's declared repeat-opening behavior; when a repeat opening changes the remaining time, that change is not an early closure

Diagnostics
  • dodge-roll-invulnerability-dodge-roll-cooldown-open-close-trace

declared-ending-closes

Row.id closes at its declared early ending

scenarioper windows row

Does not apply to dodge-roll-invulnerability: no row in windows matches ends-early declared ending.

suspension-behavior · dodge-roll-i-frames

dodge-roll-i-frames treats suspended play in the declared way

scenarioper windows row

Applies to the dodge-roll-i-frames row.

Suspended play leaves an observable answer for every dodge-roll-i-frames copy: every open copy keeps its remaining time; the observed copy is still open with four units left when play resumes and closes only after four more units advance on its cited clock. Each remaining-time trace is read during the suspension so the two answers cannot pass on the same later state.

Test steps and diagnostics
Given

one or more dodge-roll-i-frames copies open, with an observed copy having four seconds left and a remaining-time trace for every copy

When
  • ordinary play is suspended for an interval that would advance the clock at 02-mechanics.md#real-time-clock by six seconds during ordinary play, while that clock and every open copy are observed
Then
  • every open copy keeps its remaining time; the observed copy is still open with four units left when play resumes and closes only after four more units advance on its cited clock
  • the remaining-time trace shows whether time advanced during the suspension, even if the stored open state after play resumes could look the same
Diagnostics
  • dodge-roll-invulnerability-dodge-roll-i-frames-remaining-time-trace
  • dodge-roll-invulnerability-dodge-roll-i-frames-suspension-trace

suspension-behavior · dodge-roll-cooldown

dodge-roll-cooldown treats suspended play in the declared way

scenarioper windows row

Applies to the dodge-roll-cooldown row.

Suspended play leaves an observable answer for every dodge-roll-cooldown copy: every open copy keeps its remaining time; the observed copy is still open with four units left when play resumes and closes only after four more units advance on its cited clock. Each remaining-time trace is read during the suspension so the two answers cannot pass on the same later state.

Test steps and diagnostics
Given

one or more dodge-roll-cooldown copies open, with an observed copy having four seconds left and a remaining-time trace for every copy

When
  • ordinary play is suspended for an interval that would advance the clock at 02-mechanics.md#real-time-clock by six seconds during ordinary play, while that clock and every open copy are observed
Then
  • every open copy keeps its remaining time; the observed copy is still open with four units left when play resumes and closes only after four more units advance on its cited clock
  • the remaining-time trace shows whether time advanced during the suspension, even if the stored open state after play resumes could look the same
Diagnostics
  • dodge-roll-invulnerability-dodge-roll-cooldown-remaining-time-trace
  • dodge-roll-invulnerability-dodge-roll-cooldown-suspension-trace
JSONthe adoption as one file

Answers you try on this page do not change this file. To change an adoption, open it in the authoring tool.

{
  "contract": "timed-window",
  "version": 2,
  "origin": "https://opengdd.org/contracts/timed-window-2",
  "summary": "This contract covers named timed windows, such as invulnerability, cooldowns, status effects, and restart locks. It says what happens when a window's opening occurs again while the window is open (a repeat opening), when play is suspended, when the window ends early, and when it expires. This contract does not cover what opens each window or how long each window lasts.",
  "mechanism": [
    "Each row declares one timed window. The row cites the game's own Fixed material for what opens it, its duration, and the clock that advances it; the contract owns none of those game-specific rules or numbers. An opening is an event of the entity the window is given to. Each entity that the game's rules give the window has its own copies of the window, and that entity's own events open, advance, and close them, unless the adoption's Fixed prose explicitly names the window as shared. Every sentence and every generated check that speaks of open copies means the copies of one entity, unless the window is named as shared. The validator cannot check this; a reviewer does.",
    "When the cited opening occurs, the duration is read once and the window opens for that duration; later changes to the cited number or calculation do not move an open copy's endpoint. A fixed duration cites its tuning number; a duration computed from game state cites the Fixed prose that defines the calculation. A window includes its named last moment: it is still open exactly when the cited clock has advanced by that duration, and closed at any point after that, unless its row says it can end early.",
    "A repeat opening occurs when a row's opening occurs again while that window is open. The row's on-retrigger answer applies at a repeat opening. ignore leaves the open copy unchanged. new-duration replaces its remaining time with the newly granted duration. keep-longer keeps whichever is longer: the remaining time or the newly granted duration. extend-to-cap adds the newly granted duration to the time remaining, but never leaves more than the row's cited cap. The same open copy continues under ignore, new-duration, keep-longer, and extend-to-cap, and its history shows one opening; only stack creates a new copy. stack opens another independent copy and leaves every open copy unchanged. A game whose extension has a largest permitted duration names that duration as its cap; a game that permits no largest duration states the exception in its own prose and adopts this contract as promised rather than checked. A game whose stacking has a largest number of open copies states that limit in its own prose and adopts this row as promised rather than checked; this contract does not count copies.",
    "Under expiry-only, nothing closes any open copy before its duration ends; when a repeat opening changes an open copy's remaining time, that change is not an early closure. Under declared-ending, the event or condition cited by the row closes every open copy on the entity the ending happens to, unless the cited prose names more copies; this covers copies being used, canceled, dispelled, or otherwise ended by the game.",
    "stops means the row's clock does not advance while ordinary play is suspended. keeps-running means it does. The cited clock definition decides what ordinary play being suspended means; this contract does not define suspension or catch-up behavior.",
    "The answers belong to each window row, not to the game as a whole. If one apparent window follows different repeat-opening rules for different opening causes, this version does not model those causes separately; the game must name them as separate windows or state the exception in its own prose."
  ],
  "questions": {},
  "declares": {
    "rows": {
      "windows": {
        "description": "List every named window. An empty list states that the game has no timed window. A person who reviews the design checks that statement. A cap uses the window's unit and cannot be shorter than its normal duration. The duration unit must match the clock. A real-time window cannot use turns to avoid the suspension choice. No automatic check covers these rules. A person who reviews the design checks them.",
        "record": {
          "id": {
            "type": "string",
            "required": true,
            "pattern": "kebab-case",
            "unique": true,
            "description": "A short name for the window in your game's words, such as poison."
          },
          "opens-at": {
            "type": "citation",
            "required": true,
            "description": "Where your game's rules say what opens the window. A poison window might open when a poisoned attack hits."
          },
          "duration": {
            "type": "citation",
            "required": true,
            "description": "Where your game's rules say how long the window lasts. Cite a number for a duration that does not change, or the rule that calculates the duration from game state. The value is read when the window opens. For example, poison may read its turn count when the attack hits."
          },
          "duration-unit": {
            "type": "string",
            "required": true,
            "options": [
              "seconds",
              "frames",
              "ticks",
              "turns"
            ],
            "description": "The unit used by the duration and its clock. Seconds measure real time. Frames count updates. Ticks count clock steps. Turns count game turns. A poison effect might use turns."
          },
          "clock": {
            "type": "citation",
            "required": true,
            "description": "Where your game's rules name the clock that closes this window. A poison effect may use the turn clock."
          },
          "while-suspended": {
            "type": "string",
            "when": {
              "row": {
                "duration-unit": [
                  "seconds",
                  "frames",
                  "ticks"
                ]
              }
            },
            "options": [
              "stops",
              "keeps-running"
            ],
            "description": "Does the window's clock stop while ordinary play is suspended? This choice applies only to a window that counts seconds, frames, or ticks. If the clock stops, an invulnerability window keeps all its remaining time while play is suspended. If the clock keeps running, the window can expire before play resumes."
          },
          "on-retrigger": {
            "type": "string",
            "required": true,
            "options": [
              "ignore",
              "new-duration",
              "keep-longer",
              "extend-to-cap",
              "stack"
            ],
            "description": "What a new opening does while this window is already open (a repeat opening). Ignore leaves the poison window unchanged. New duration replaces its remaining time with the duration from the new poison hit. Keep longer uses whichever time is longer. Extend to cap adds time without passing its cap. Stack opens another independent poison copy. Only stacking creates a new copy. Every other choice continues the current copy and keeps one opening in its history."
          },
          "retrigger-cap": {
            "type": "citation",
            "when": {
              "row": {
                "on-retrigger": [
                  "extend-to-cap"
                ]
              }
            },
            "description": "Where your game's rules state the largest amount of time that can remain after an extension. A poison effect may cap all extensions at its maximum duration. Add this only when repeat openings extend up to a cap. Use the same unit as the duration."
          },
          "ends-early": {
            "type": "string",
            "required": true,
            "options": [
              "expiry-only",
              "declared-ending"
            ],
            "description": "Whether the window can close before its duration ends. Expiry only keeps a poison effect open until time runs out. A declared ending lets a cure close every open poison copy on the entity it cures, unless the cited rules name more copies."
          },
          "early-end": {
            "type": "citation",
            "when": {
              "row": {
                "ends-early": [
                  "declared-ending"
                ]
              }
            },
            "description": "Where your game's rules name every event or condition that ends this window early. This includes using or canceling it. For poison, this may be an antidote or cleansing the target. Add this only when the window can end early."
          }
        }
      }
    }
  },
  "pack": "sha256:17a5a688b1156f0eb450003d53e006d9d200942120d829376abff01587728044",
  "answers": {},
  "values": {},
  "rows": {
    "windows": [
      {
        "id": "dodge-roll-i-frames",
        "opens-at": "02-mechanics.md#dodge-roll-start",
        "duration": "player.dodge_roll_iframe_seconds",
        "duration-unit": "seconds",
        "clock": "02-mechanics.md#real-time-clock",
        "while-suspended": "stops",
        "on-retrigger": "ignore",
        "ends-early": "expiry-only"
      },
      {
        "id": "dodge-roll-cooldown",
        "opens-at": "02-mechanics.md#dodge-roll-start",
        "duration": "player.dodge_roll_cooldown_seconds",
        "duration-unit": "seconds",
        "clock": "02-mechanics.md#real-time-clock",
        "while-suspended": "stops",
        "on-retrigger": "ignore",
        "ends-early": "expiry-only"
      }
    ]
  },
  "verification": {
    "declared-window-set": {
      "scope": "the player's dodge-roll windows: invulnerability from roll start through 400 milliseconds (0.4 seconds), and cooldown from roll start through 800 milliseconds (0.8 seconds); the four-unit and six-unit numbers in the suspension check are neutral teaching units, not this game's timing"
    }
  }
}