Action legibility
action-legibility-2
This contract defines the behavior of action prompts: an interact prompt, an unavailable action, or a shared button.
This contract decides which actions players can discover, what players see when an action cannot be used, and which action a shared button runs.
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
Up to 2 questions. Some appear only after earlier answers.
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.
By default, how can players discover an action in a situation where the action applies?
- Asked when
- the action cases list has at least one row.
- If not asked
- With no action case, this adoption makes no default discovery promise.
Why this is asked
Different actions may need different help. This answer is the default answer. An action case can choose another answer in its own row.
By default, what appears when an action cannot be used?
- Asked when
- the action cases list has at least one row.
- If not asked
- With no action case, this adoption makes no default unavailable-action promise.
Why this is asked
A missing prompt, a dimmed control, and an explanation create different expectations. This answer is the default answer.
Numbers and rulesno numbers, 1 rule
Numbers
This contract has no numbers to set.
Rules
-
Forbidden when Action discovery default is None, and Unavailable action default is Reason is shown.
Lists3 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.
Action cases
action-cases
Actions in the situations where their discovery and unavailable presentation are promised. The effective answer of a case is its own answer, or the default answer when the row says use-game-default. When the effective discovery answer is not none, the case has at least one availability-presentations row on each platform that it covers. When the effective discovery answer is none, the case has no availability-presentations row. No case has the effective discovery answer none together with the effective unavailable answer reason-is-shown. No two cases cover the same action in overlapping situations.
An empty list means: No action receives a legibility promise from this adoption.
Each row is: id, action-declared-in, situation-declared-in, discoverability, when-unavailable, presentation-rule-declared-in.
Every field
| Field | Kind | When it appears | Meaning |
|---|---|---|---|
id |
string | Required | A short name for this case in your game's words, such as open-door-nearby or jump-at-gap. |
action-declared-in |
reference | Required | Where your game's rules name the action, its ordinary permission, and its complete effect. |
situation-declared-in |
reference | Required | Where your game's rules name every play situation that this case covers. The same rules also name the nearest similar situations that this case does not cover. |
discoverability |
choice: use-game-default, looks-usable, explanation-on-demand, current-binding-is-shown, assistive-tech-can-name-it, none | Required | The minimum discovery promise for this action case. Use the default answer, or choose another answer for this row. A secret arcade command may state that no discovery route exists. |
when-unavailable |
choice: use-game-default, hidden, shown-unavailable, reason-is-shown, unchanged, never-unavailable | Required | What the player-facing presentation does while the action cannot be used. Use the default answer, or choose another answer for this row. A crafting action may remain visible with its missing material named. |
presentation-rule-declared-in |
reference | Required | Where your game's rules state every player-facing discovery route and every unavailable state of this case. When no route exists, the rules say so explicitly. |
Availability presentations
availability-presentations
Independent channels that present one action case's availability. No two rows repeat one action case and channel pair.
An empty list means: No action case promises a player-facing availability channel.
Each row is: id, action-case, channel, platform-declared-in, channel-rule-declared-in.
Every field
| Field | Kind | When it appears | Meaning |
|---|---|---|---|
id |
string | Required | A short name in your game's words for one action case and one channel, such as jump-at-gap-shape. |
action-case |
string | Required | The id of the action-cases row of this adoption presented through this channel. |
channel |
choice: text, icon, shape, outline-or-contrast, audio-cue, spatial-audio, narration, audio-description, haptic | Required | The independent presentation channel. Text and icons can name or depict an action; shape, contrast, sound, position, speech, description, and touch can distinguish availability under their cited rules. |
platform-declared-in |
reference | Optional | Where your game's rules name the platform on which this presentation applies. When this field is absent, the presentation applies on every platform that the action case covers. |
channel-rule-declared-in |
reference | Required | Where your game's rules state the form of this channel in the available state and in the unavailable state. For a case whose effective unavailable answer is never-unavailable or unchanged, the rules state the available form alone. The rules also state whether the channel identifies the action. A channel is judged by an observer who meets that channel alone. |
Shared input cases
shared-input-cases
Situations where one action input can offer several actions and one choice must be made visible.
An empty list means: No action input offers several actions in one situation.
Each row is: id, situation-declared-in, actions-declared-in, action-input, action-input-declared-in, selection, selection-rule-declared-in, presentation-rule-declared-in.
Every field
| Field | Kind | When it appears | Meaning |
|---|---|---|---|
id |
string | Required | A short name for the situation in your game's words, such as porch-interactions. |
situation-declared-in |
reference | Required | Where your game's rules name the situation in which several actions share one action input. |
actions-declared-in |
reference | Required | Where your game's rules list the candidate actions and the conditions that make each candidate eligible. |
action-input |
string | Required | The name of the one action input that carries these candidates, such as porch-interact. |
action-input-declared-in |
reference | Required | Where your game's control rules name this shared input and the physical activation that produces it. |
selection |
choice: rule-selects-one, player-selects-one | Required | Whether the cited rule selects one candidate by ordering or a situation test, or the player chooses before the attempt. A village interact may prefer talking over picking up an item. |
selection-rule-declared-in |
reference | Required | Where your game's rules select exactly one offered action and decide every reachable tie. |
presentation-rule-declared-in |
reference | Required | Where your game's rules say how the selected action is identified to the player before the shared input becomes an action attempt. |
For builders
Exact wording for builders and 52 pack tests
Exact wording for builders
This text decides the order of the steps for action discovery, availability presentation, and shared-input selection. The questions and rows supply choices and cited game rules. They do not change the order.
An action input is one signal that the game receives. Control options declares it when that contract is adopted; otherwise it comes from the game's Fixed control rule. Control options owns how bindings emit it; this contract consumes one action input and the candidate actions it carries. The current binding comes from the same optional source. An action case is one action in one cited situation. A candidate is an action carried by the input whose optional binding context holds and whose Fixed permission rule — or a forgiveness acceptance from Input forgiveness — accepts it in the situation at the accepted moment. Forgiveness applies to each candidate separately. The forgiveness rows of a candidate action read the shared input as the input of that action. When forgiveness shifts the acceptance for one candidate, the accepted moment that this contract reads shifts with it. An action is offered when it is identified to the player as the result of selection.
1. Read the current situation and every matching action case — action cases are platform-neutral — then every presentation row whose optional platform citation applies on the current platform. When no action case matches, this adoption makes no legibility promise.
2. Resolve each row's effective discovery and unavailable answers. A row value other than use-game-default applies. Otherwise the answer to the matching question applies.
3. Read ordinary action permission from the cited Fixed action rule. This contract does not grant permission and does not make an unavailable action succeed.
4. While an action is available, apply its effective discovery promise through the matching presentation rows. Under none, no discovery route is promised.
5. While an action is unavailable, apply its effective unavailable answer. Hidden removes its presentation. Shown-unavailable keeps identity and marks the state. Reason-is-shown also names the current block. Unchanged exposes no availability difference. Never-unavailable admits no unavailable state in the cited situation.
6. Read the one action input and all of its candidate actions. This contract consumes one input carrying its candidates; it never splits one input into several.
7. When the action input has at most one candidate at the accepted moment, that candidate is offered and no shared-input-cases row is needed. A physical input may differ by platform without changing this step.
8. When the action input has several candidates, exactly one matching shared-input-cases row applies. Under rule-selects-one, its cited rule uses its declared ordering or situation test. Under player-selects-one, an explicit choice is required. The row consumes one input with N candidates and offers exactly one. Present that offered action under the row's cited presentation rule before the accepted input becomes an action attempt. Other candidates may remain visible, but none is presented as what will happen now. While an input waits in a buffer, this presentation does not promise which candidate will be offered. The promise applies from the accepted moment.
9. First, the physical input occurs. Then Control options, when adopted, emits the action input. Then Input forgiveness, when adopted, may shift the accepted moment. Then this contract selects the offered candidate at the accepted moment. The result is one action proposal. Thus an interact buffered during a cutscene evaluates candidates in the situation where the input is accepted, not the situation where it was pressed. Event resolution owns ordering, refusal, and effects after the proposal.
10. Whenever a presentation shows the current binding, it shows the actual current device control, including the touch region or gesture on a touch platform.
11. When availability, situation, platform, binding, or candidate eligibility changes, recompute the presentation from step 1. A previous prompt or selection does not remain current unless the cited rules still select it.
The order of the steps is: situation, row defaults, ordinary permission, discovery, unavailable presentation, candidate set, shared-input selection at the accepted moment with its offered-action presentation, one action proposal, current-device binding, and refresh.
Verification pack
sha256:e8bc008156a44034a292f2641015b40a9840cd8afb0e08e4405009d0e3f362b4
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.
52 pack tests
Placeholders are filled from the adoption's answers, numbers, rows, and test inputs.
action legibility uses one action input, action cases, candidates, and offered actions
action-legibility-vocabulary
Applies for every adoption
An action input is one signal that the game receives. It comes from Control options when that contract is adopted, otherwise from the game's Fixed control rule. An action case is one action in one cited situation. A candidate is an action the input carries whose permission or forgiveness acceptance holds at the accepted moment. An action is offered when selection identifies it to the player.
- Given
the
Instanceadoption and a player-facing physical control, where the adoption or its cited control rules name an action input; where they name none, this test checks nothing- When
- the control path, matching action cases, candidate actions, and offered result are identified
- Then
- the action input is one signal that the game receives; it comes from Control options when adopted and otherwise from the game's Fixed control rule
- each action case is one action in one cited situation
- a candidate is an action the input carries whose binding context, when one exists, holds and whose ordinary permission or Input forgiveness acceptance holds at the accepted moment
- an action is offered only when it is identified to the player as the result of selection
- Diagnostics
Instance-candidate-setInstance-offered-action
with no matching action case, the adoption makes no action-legibility promise
no-action-case-makes-no-promise
Applies for every adoption
Where no matching action case exists because the adoption has no action-cases row, the adoption makes no discovery, unavailable-presentation, or availability promise and both default answers are absent. Where an action case exists, this test checks nothing.
- Given
the
Instanceadoption, its action-cases rows, and its default answers- When
- the adoption's action-legibility promises are read
- Then
- where no matching action case exists because the adoption has no action-cases row, the adoption makes no discovery, unavailable-presentation, or availability promise and the default discovery answer and the default unavailable-action answer are both absent; where an action case exists, this test checks nothing
- Diagnostics
Instance-declaration-record
Row.id applies exactly in its cited situations
action-case-matches-cited-situation
Applies for every adoption
Action case Row.id applies in every situation named at Row.situation declared in and does not apply in any situation excluded there. It applies on every platform the adoption covers; differences between platforms are stated only in availability-presentations rows. The test leaves the rule's content to that citation. For a situation that the citation neither covers nor excludes, this test checks nothing.
- Given
the action case
Row.idand the Fixed situation rule atRow.situation declared in- When
- the cited covered situations and the nearest similar excluded situations are each reached
- Then
Row.idapplies in every situation the citation coversRow.iddoes not apply in any situation the citation excludesRow.idapplies on every platform the adoption covers; differences between platforms are stated only in availability-presentations rows- for a situation that the citation neither covers nor excludes, this test checks nothing
- Diagnostics
Instance-situation-trace
Row.id looks usable by its row answer
discovery-looks-usable-override
Applies when row discoverability is Looks usable.
Audit class: observer-judged. An observer, not the running game, judges this. The row overrides the default answer: while Row.id is available, at least one matching availability presentation identifies the action as one that can be attempted, before the attempt.
- Given
Row.idavailable in a situation atRow.situation declared in, before an attempt- When
- an observer examines the matching availability presentations
- Then
- at least one presentation identifies
Row.idas an action that can be attempted in the current situation before the attempt
- at least one presentation identifies
- Diagnostics
Instance-Row.id-observer-resultInstance-presentation-trace
Row.id looks usable by the default answer
discovery-looks-usable-default
Applies when Action discovery default is Looks usable and row discoverability is Use game default.
Audit class: observer-judged. An observer, not the running game, judges this. The row uses the default answer: while Row.id is available, at least one matching availability presentation identifies the action as one that can be attempted, before the attempt.
- Given
Row.idavailable in a situation atRow.situation declared in, before an attempt- When
- an observer examines the matching availability presentations
- Then
- at least one presentation identifies
Row.idas an action that can be attempted in the current situation before the attempt
- at least one presentation identifies
- Diagnostics
Instance-Row.id-observer-resultInstance-presentation-trace
Row.id has an explanation route by its row answer
discovery-explanation-on-demand-override
Applies when row discoverability is Explanation on demand.
Audit class: observer-judged. An observer, not the running game, judges this. The row overrides the default answer: while Row.id applies, the route at Row.presentation rule declared in is available in the situation, names the action, and explains how to attempt it. The test restates nothing from the cited rule.
- Given
Row.idapplies in a situation atRow.situation declared in- When
- an observer uses the discovery route declared at
Row.presentation rule declared in
- an observer uses the discovery route declared at
- Then
- the route is available in the current situation
- the route names the action and explains how to attempt it
- Diagnostics
Instance-Row.id-observer-result
Row.id has an explanation route by the default answer
discovery-explanation-on-demand-default
Applies when Action discovery default is Explanation on demand and row discoverability is Use game default.
Audit class: observer-judged. An observer, not the running game, judges this. The row uses the default answer: while Row.id applies, the route at Row.presentation rule declared in is available in the situation, names the action, and explains how to attempt it. The test restates nothing from the cited rule.
- Given
Row.idapplies in a situation atRow.situation declared in- When
- an observer uses the discovery route declared at
Row.presentation rule declared in
- an observer uses the discovery route declared at
- Then
- the route is available in the current situation
- the route names the action and explains how to attempt it
- Diagnostics
Instance-Row.id-observer-result
Row.id shows the current device control by its row answer
discovery-current-binding-override
Applies when row discoverability is Current binding is shown.
Audit class: observer-judged. An observer, not the running game, judges this. The row overrides the default answer: every prompt for Row.id names the actual current device control. An old binding, a wrong-device binding, or a hardware glyph in place of the actual touch region or gesture fails.
- Given
every prompt for
Row.idon each covered device, including a touch device where covered- When
- an observer compares the prompt with the current device control under the applicable control rule
- Then
- every prompt names the actual current device control
- no prompt names an old binding or a wrong-device binding as current
- on a touch platform, the prompt names the actual touch region or gesture rather than a hardware glyph
- Diagnostics
Instance-Row.id-observer-resultInstance-prompt-bindings
Row.id shows the current device control by the default answer
discovery-current-binding-default
Applies when Action discovery default is Current binding is shown and row discoverability is Use game default.
Audit class: observer-judged. An observer, not the running game, judges this. The row uses the default answer: every prompt for Row.id names the actual current device control. An old binding, a wrong-device binding, or a hardware glyph in place of the actual touch region or gesture fails.
- Given
every prompt for
Row.idon each covered device, including a touch device where covered- When
- an observer compares the prompt with the current device control under the applicable control rule
- Then
- every prompt names the actual current device control
- no prompt names an old binding or a wrong-device binding as current
- on a touch platform, the prompt names the actual touch region or gesture rather than a hardware glyph
- Diagnostics
Instance-Row.id-observer-resultInstance-prompt-bindings
Row.id exposes its name and role by its row answer
discovery-assistive-name-override
Applies when row discoverability is Assistive tech can name it.
Audit class: observer-judged. An observer, not the running game, judges this. The row overrides the default answer: a player-facing interface element for Row.id exposes a determinable action name and role to supported assistive technology.
- Given
Row.idavailable through a player-facing interface element in a covered situation- When
- an observer inspects that element through each supported assistive technology
- Then
- the assistive interface exposes a determinable action name and role for
Row.id
- the assistive interface exposes a determinable action name and role for
- Diagnostics
Instance-Row.id-observer-resultInstance-assistive-tree
Row.id exposes its name and role by the default answer
discovery-assistive-name-default
Applies when Action discovery default is Assistive tech can name it and row discoverability is Use game default.
Audit class: observer-judged. An observer, not the running game, judges this. The row uses the default answer: a player-facing interface element for Row.id exposes a determinable action name and role to supported assistive technology.
- Given
Row.idavailable through a player-facing interface element in a covered situation- When
- an observer inspects that element through each supported assistive technology
- Then
- the assistive interface exposes a determinable action name and role for
Row.id
- the assistive interface exposes a determinable action name and role for
- Diagnostics
Instance-Row.id-observer-resultInstance-assistive-tree
Row.id promises no discovery route by its row answer
discovery-none-override
Applies when row discoverability is None.
Audit class: observer-judged. An observer, not the running game, judges this. The row overrides the default answer: Row.id promises no identity or availability before the attempt. Accidental discovery and memorable content do not violate this answer; secrecy beyond that promise is outside the contract.
- Given
Row.idbefore an attempt in every situation atRow.situation declared in- When
- an observer examines every player-facing presentation before the attempt
- Then
- no presentation promises the action's identity or availability before the attempt
- accidental discovery and memorable authored content do not fail this answer
- Diagnostics
Instance-Row.id-observer-resultInstance-presentation-trace
Row.id promises no discovery route by the default answer
discovery-none-default
Applies when Action discovery default is None and row discoverability is Use game default.
Audit class: observer-judged. An observer, not the running game, judges this. The row uses the default answer: Row.id promises no identity or availability before the attempt. Accidental discovery and memorable content do not violate this answer; secrecy beyond that promise is outside the contract.
- Given
Row.idbefore an attempt in every situation atRow.situation declared in- When
- an observer examines every player-facing presentation before the attempt
- Then
- no presentation promises the action's identity or availability before the attempt
- accidental discovery and memorable authored content do not fail this answer
- Diagnostics
Instance-Row.id-observer-resultInstance-presentation-trace
Row.id uses its cited ordinary permission
action-permission-remains-cited
Applies for every adoption
Ordinary permission for Row.id stays at Row.action declared in. This contract grants none and does not make an unavailable action succeed. Where the cited rule admits no unavailable state, this test checks nothing about an unavailable attempt. The test restates nothing from the cited action rule.
- Given
the action at
Row.action declared inin an ordinarily permitted state and, where the cited action rule admits one, an ordinarily unavailable state in a covered situation- When
- the player attempts the action in each state
- Then
- ordinary permission is read from
Row.action declared in - this contract grants no permission
- where an unavailable state exists, the unavailable attempt does not succeed because of any discovery route, availability presentation, or shared-input selection; where none exists, this test checks nothing about an unavailable attempt
- ordinary permission is read from
- Diagnostics
Instance-permission-trace
Row.id applies on its covered platform scope
presentation-applies-on-covered-platforms
Applies for every adoption
Availability presentation Row.id applies on every platform its action case covers unless a platform citation narrows it, and that narrower scope is carried by its platform citation.
- Given
availability presentation
Row.idfor the case namedRow.action case- When
- the case is reached on each platform it covers
- Then
- the row applies on every platform its action case covers unless a platform citation narrows it, and that narrower scope is carried by its platform citation
- Diagnostics
Instance-presentation-trace
action presentations agree with the cited action cases
listed-action-presentations-agree
Applies for every adoption
Audit class: observer-judged. An observer, not the running game, judges this. Every player-facing presentation of a covered action agrees with that action case's Fixed action citation and never presents it as another covered action. For a presentation outside the stated scope, this test checks nothing.
- Scope
every player-facing prompt, explanation, control reminder, and availability presentation
- Holds
each presentation of an action case agrees with its Fixed action citation and never presents one covered action as another; for a player-facing presentation outside this scope, this test checks nothing
- Diagnostics
Instance-observer-resultInstance-presentation-trace
Row.id prompts update after a binding change by its row answer
remapped-prompt-updates-override
Applies when row discoverability is Current binding is shown.
Audit class: observer-judged. An observer, not the running game, judges this. Where Control options changes Row.id's binding, every later prompt, hint, reminder, and control summary names the new current device control, and none names the old control as current. This contract checks the presentation; Control options performs the remap. Where the adoption cannot construct that change, this test checks nothing.
- Given
the control source for
Row.idand its current device control- When
- where Control options is adopted and permits a binding change, it changes the action to another supported current device control and an observer compares every later prompt, hint, reminder, and control summary with the configured control; otherwise this test checks nothing
- Then
- each later presentation names the new current device control
- none names the old control as current
- Diagnostics
Instance-Row.id-observer-resultInstance-prompt-bindings
Row.id prompts update after a binding change by the default answer
remapped-prompt-updates-default
Applies when Action discovery default is Current binding is shown and row discoverability is Use game default.
Audit class: observer-judged. An observer, not the running game, judges this. Where Control options changes Row.id's binding, every later prompt, hint, reminder, and control summary names the new current device control, and none names the old control as current. This contract checks the presentation; Control options performs the remap. Where the adoption cannot construct that change, this test checks nothing.
- Given
the control source for
Row.idand its current device control- When
- where Control options is adopted and permits a binding change, it changes the action to another supported current device control and an observer compares every later prompt, hint, reminder, and control summary with the configured control; otherwise this test checks nothing
- Then
- each later presentation names the new current device control
- none names the old control as current
- Diagnostics
Instance-Row.id-observer-resultInstance-prompt-bindings
Row.id is hidden while unavailable by its row answer
unavailable-hidden-override
Applies when row when unavailable is Hidden.
Audit class: observer-judged. An observer, not the running game, judges this. The row overrides the default answer: Row.id follows its effective discovery promise while available and its availability presentation is absent while unavailable.
- Given
Row.idavailable and then unavailable in a covered situation- When
- an observer compares the player-facing availability presentation in both states
- Then
- the available state follows the case's effective discovery promise
- the action's availability presentation is absent while the action is unavailable
- Diagnostics
Instance-Row.id-observer-resultInstance-presentation-trace
Row.id is hidden while unavailable by the default answer
unavailable-hidden-default
Applies when Unavailable action default is Hidden and row when unavailable is Use game default.
Audit class: observer-judged. An observer, not the running game, judges this. The row uses the default answer: Row.id follows its effective discovery promise while available and its availability presentation is absent while unavailable.
- Given
Row.idavailable and then unavailable in a covered situation- When
- an observer compares the player-facing availability presentation in both states
- Then
- the available state follows the case's effective discovery promise
- the action's availability presentation is absent while the action is unavailable
- Diagnostics
Instance-Row.id-observer-resultInstance-presentation-trace
Row.id stays identifiable and distinctly unavailable by its row answer
unavailable-shown-override
Applies when row when unavailable is Shown unavailable.
Audit class: observer-judged. An observer, not the running game, judges this. The row overrides the default answer: while unavailable, Row.id stays identifiable and has a distinct unavailable state.
- Given
Row.idavailable and then unavailable in a covered situation- When
- an observer compares its availability presentation in both states
- Then
- the action remains identifiable while unavailable
- the unavailable presentation is distinct from the available presentation
- Diagnostics
Instance-Row.id-observer-resultInstance-presentation-trace
Row.id stays identifiable and distinctly unavailable by the default answer
unavailable-shown-default
Applies when Unavailable action default is Shown unavailable and row when unavailable is Use game default.
Audit class: observer-judged. An observer, not the running game, judges this. The row uses the default answer: while unavailable, Row.id stays identifiable and has a distinct unavailable state.
- Given
Row.idavailable and then unavailable in a covered situation- When
- an observer compares its availability presentation in both states
- Then
- the action remains identifiable while unavailable
- the unavailable presentation is distinct from the available presentation
- Diagnostics
Instance-Row.id-observer-resultInstance-presentation-trace
Row.id names its current block by its row answer
unavailable-reason-override
Applies when row when unavailable is Reason is shown.
Audit class: observer-judged. An observer, not the running game, judges this. The row overrides the default answer: while Row.id is unavailable, its presentation identifies it, marks it unavailable, and names the current block under Row.presentation rule declared in. The test restates nothing from the cited rule.
- Given
Row.idunavailable for each current block admitted byRow.action declared in- When
- an observer examines its availability presentation
- Then
- the presentation identifies the action
- the presentation marks the action unavailable
- the presentation names the current blocking reason
- Diagnostics
Instance-Row.id-observer-resultInstance-presentation-trace
Row.id names its current block by the default answer
unavailable-reason-default
Applies when Unavailable action default is Reason is shown and row when unavailable is Use game default.
Audit class: observer-judged. An observer, not the running game, judges this. The row uses the default answer: while Row.id is unavailable, its presentation identifies it, marks it unavailable, and names the current block under Row.presentation rule declared in. The test restates nothing from the cited rule.
- Given
Row.idunavailable for each current block admitted byRow.action declared in- When
- an observer examines its availability presentation
- Then
- the presentation identifies the action
- the presentation marks the action unavailable
- the presentation names the current blocking reason
- Diagnostics
Instance-Row.id-observer-resultInstance-presentation-trace
Row.id looks identical across availability states by its row answer
unavailable-unchanged-override
Applies when row when unavailable is Unchanged.
Audit class: observer-judged. An observer, not the running game, judges this. The row overrides the default answer: any player-facing presentation of Row.id that exists is identical while available and unavailable. If none exists, this test checks nothing.
- Given
any player-facing presentation of
Row.idthat exists once the action is available and once it is unavailable in the same covered situation- When
- an observer compares the two states
- Then
- where a player-facing presentation exists, it is identical across the available and unavailable states; where none exists, this test checks nothing
- Diagnostics
Instance-Row.id-observer-resultInstance-presentation-trace
Row.id looks identical across availability states by the default answer
unavailable-unchanged-default
Applies when Unavailable action default is Unchanged and row when unavailable is Use game default.
Audit class: observer-judged. An observer, not the running game, judges this. The row uses the default answer: any player-facing presentation of Row.id that exists is identical while available and unavailable. If none exists, this test checks nothing.
- Given
any player-facing presentation of
Row.idthat exists once the action is available and once it is unavailable in the same covered situation- When
- an observer compares the two states
- Then
- where a player-facing presentation exists, it is identical across the available and unavailable states; where none exists, this test checks nothing
- Diagnostics
Instance-Row.id-observer-resultInstance-presentation-trace
Row.id has no reachable unavailable state by its row answer
unavailable-never-override
Applies when row when unavailable is Never unavailable.
Audit class: observer-judged. An observer, not the running game, judges this. The row overrides the default answer: no reachable state in a covered situation makes Row.id unavailable.
- Given
every reachable state in every covered situation for
Row.id- When
- an observer checks ordinary permission throughout those states
- Then
- no reachable state makes
Row.idunavailable
- no reachable state makes
- Diagnostics
Instance-Row.id-observer-resultInstance-permission-trace
Row.id has no reachable unavailable state by the default answer
unavailable-never-default
Applies when Unavailable action default is Never unavailable and row when unavailable is Use game default.
Audit class: observer-judged. An observer, not the running game, judges this. The row uses the default answer: no reachable state in a covered situation makes Row.id unavailable.
- Given
every reachable state in every covered situation for
Row.id- When
- an observer checks ordinary permission throughout those states
- Then
- no reachable state makes
Row.idunavailable
- no reachable state makes
- Diagnostics
Instance-Row.id-observer-resultInstance-permission-trace
Row.id presents its channel form through Bind channel phrase alone
action-channel-announces
Applies for every adoption
Audit class: observer-judged. An observer, not the running game, judges this. The channel-rule-declared-in field says a channel is judged by an observer who meets that channel alone. On every platform where this row applies, every other discovery route and availability presentation is removed or held identical, so the observer meets Bind channel phrase alone. Where both states are presented, the observer meets at least two presentations of each with the balance undisclosed and order unknown; under hidden, the unavailable form is the absence of this channel and the observer meets at least two presentations of the available form and at least two of its absence; under never-unavailable, the observer meets at least two presentations of the available form alone. Where the effective unavailable answer of the case this row names admits a distinct unavailable form, the observer names availability every time from that channel alone; under unchanged, the observer cannot distinguish the two forms above chance; under never-unavailable, this test checks nothing about how the observer names availability. Where Row.channel rule declared in states that this channel also identifies the action, the observer names which action it is and that identity agrees with the case this row names; where it does not, this test checks nothing about the identity of the action. The presented form or forms follow Row.channel rule declared in; the test restates nothing from it.
- Given
on every platform where this row applies, controlled presentations for the action case named
Row.action case: the available and unavailable forms where its effective unavailable answer admits a distinct unavailable form, the available form and its absence under hidden, the available and unavailable state presentations under unchanged, and the available form alone under never-unavailable; every other discovery route and availability presentation is removed or held identical across the states being compared, so the observer meetsBind channel phrasealone; developer instrumentation that is not player-facing and a frozen background held identical are not routes- When
- where both states are presented, an observer meets at least two presentations of each with the balance undisclosed and the order unknown; under hidden, the unavailable form is the absence of this channel, and the observer meets at least two presentations of the available form and at least two of its absence; under never-unavailable, the observer meets at least two presentations of the available form alone
- Then
- where the effective unavailable answer of the case this row names admits a distinct unavailable form, the observer correctly names availability every time from
Bind channel phrasealone; under unchanged, the observer instead cannot distinguish the two forms above chance; under never-unavailable, this test checks nothing about how the observer names availability - the presented form or forms follow
Row.channel rule declared in - where
Row.channel rule declared instates that this channel also identifies the action, the observer correctly names which action it is and that identity agrees with the case this row names; where it does not, this test checks nothing about the identity of the action - where the case this row names has a reachable unavailable state, the channel presents exactly the state its effective unavailable answer requires; where it has none, this test checks nothing about the unavailable state
- where the effective unavailable answer of the case this row names admits a distinct unavailable form, the observer correctly names availability every time from
- Diagnostics
Instance-Row.id-observer-result
one action input stays one signal with its candidates
shared-input-stays-one
Applies for every adoption
Where the adoption or its cited control rules name an action input, one action input is consumed once with all its candidates; where none is named, this test checks nothing. With exactly one candidate at the accepted moment, that candidate is offered and no shared-input-cases row is needed, as the contract says. With no candidate or with several candidates, this test checks nothing about the offered candidate.
- Given
one action input carrying its candidate actions at an accepted moment, where the adoption or its cited control rules name an action input; where they name none, this test checks nothing
- When
- the candidate set is read
- Then
- the action input is consumed once with all its candidates and is never split into several inputs
- when exactly one candidate remains, that candidate is offered and no shared-input-cases row is needed, as the contract says
- when no candidate remains or several candidates remain, this test checks nothing about the offered candidate
- Diagnostics
Instance-candidate-setInstance-offered-action
Row.id offers one rule-selected candidate
shared-input-rule-selects-one
Applies when row selection is Rule selects one.
For Row.id, the rule at Row.selection rule declared in selects exactly one candidate by its declared ordering or situation test at the accepted moment, after any forgiveness shift. The action is offered under Row.presentation rule declared in before the input becomes an attempt; no other candidate is presented as what will happen now. One action proposal follows. The test restates neither cited rule. This test checks nothing about ordering, refusal, and effects after the proposal.
- Given
action input
Row.action inputwith several candidates fromRow.actions declared inin the situation atRow.situation declared in- When
- the accepted moment arrives, after any Input forgiveness shift
- Then
Row.selection rule declared inselects exactly one candidate by its ordering or situation test and decides every reachable tie- the selected action is offered under
Row.presentation rule declared inbefore the accepted input becomes an attempt - no other candidate is presented as what will happen now
- one action proposal follows
- this test checks nothing about ordering, refusal, and effects after that proposal
- Diagnostics
Instance-candidate-setInstance-offered-actionInstance-presentation-trace
Row.id offers one player-selected candidate
shared-input-player-selects-one
Applies when row selection is Player selects one.
For Row.id, the player makes the explicit choice required at Row.selection rule declared in at the accepted moment, after any forgiveness shift. Exactly one action is offered under Row.presentation rule declared in before the input becomes an attempt; no other candidate is presented as what will happen now. One action proposal follows. The test restates neither cited rule. This test checks nothing about ordering, refusal, and effects after the proposal.
- Given
action input
Row.action inputwith several candidates fromRow.actions declared inin the situation atRow.situation declared in- When
- the accepted moment arrives, after any Input forgiveness shift, and the player makes the explicit choice required at
Row.selection rule declared in
- the accepted moment arrives, after any Input forgiveness shift, and the player makes the explicit choice required at
- Then
- the explicit choice completes before the input becomes an attempt and selects exactly one candidate
- the selected action is offered under
Row.presentation rule declared inbefore the accepted input becomes an attempt - no other candidate is presented as what will happen now
- one action proposal follows
- this test checks nothing about ordering, refusal, and effects after that proposal
- Diagnostics
Instance-candidate-setInstance-offered-actionInstance-presentation-trace
Row.id reads a buffered shared input in its accepted situation
buffered-shared-input-reads-accepted-situation
Applies when row selection is Rule selects one or Player selects one.
For Row.id, a buffered input reads its candidate set and offered action in the accepted situation, not the situation where it was pressed. No candidate is presented as what will happen now while the input waits. Where forgiveness shifts acceptance for one candidate only, this contract reads that shifted moment as the accepted moment. Where the adoption cannot construct a buffered input, this test checks nothing.
- Given
an input pressed in one covered situation and accepted in another after an Input forgiveness shift; where the adoption cannot construct a buffered input, this test checks nothing
- When
- the input waits and then reaches its accepted moment
- Then
- the candidate set and the offered action are read in the accepted situation
- no candidate is presented as what will happen now while the input waits
- where forgiveness shifts acceptance for one candidate only, this contract reads that shifted moment as the accepted moment
- Diagnostics
Instance-candidate-setInstance-offered-actionInstance-presentation-trace
availability and offered-action presentations refresh after relevant changes
presentation-refreshes-after-change
Applies for every adoption
Where an availability or offered-action presentation exists, the game recomputes it from the current situation and the matching declarations after a change in availability, situation, platform, binding, or candidate eligibility. A previous prompt or selection stays current only when the cited rules still select it. Without a presentation, this test checks nothing. For a kind of change that the adoption cannot construct, this test checks nothing about that kind of change.
- Given
where the adoption has a live availability or offered-action presentation, that presentation followed separately by a change in availability, situation, platform, binding, or candidate eligibility; where it has none, this test checks nothing
- When
- each change takes effect
- Then
- the presentation is recomputed from the current situation and the matching declarations
- the previous prompt or selection remains current only when the cited rules still select it
- for a kind of change that the adoption cannot construct, this test checks nothing
- Diagnostics
Instance-refresh-logInstance-prompt-bindingsInstance-offered-action
action legibility keeps the order of its steps
action-legibility-authority-order
Applies for every adoption
The contract reads situation, row defaults, ordinary permission, discovery, unavailable presentation, candidate set, shared-input selection at the accepted moment with its offered-action presentation, one action proposal, current-device binding, and refresh in that order. For a part that this adoption does not exercise, this test checks nothing.
- Given
a covered action input and situation that exercise every applicable part of the
Instanceadoption- When
- the game handles the action input
- Then
- the game reads situation, row defaults, ordinary permission, discovery, unavailable presentation, candidate set, shared-input selection at the accepted moment with its offered-action presentation, one action proposal, current-device binding, and refresh in that order
- for a part that the adoption does not exercise, this test checks nothing
- Diagnostics
Instance-presentation-traceInstance-candidate-setInstance-offered-actionInstance-refresh-log
the adoption makes no promise beyond action legibility
legibility-boundaries
Applies for every adoption
The adoption makes no promise about physical controls, input timing help, displayed game facts, or event order. A route that highlights without naming an action or explaining how to attempt it is not a discovery answer. A control layout the game's Fixed rules do not make a cited situation is not a situation of this contract.
- Given
the
Instanceadoption and features outside its declared answers and rows- When
- the adoption's promise boundary is reviewed
- Then
- the adoption makes no promise about physical controls
- the adoption makes no promise about input timing help
- the adoption makes no promise about displayed game facts
- the adoption makes no promise about event order
- a route that highlights without naming an action or explaining how to attempt it is not a discovery answer
- a control layout the game's Fixed rules do not make a cited situation is not a situation of this contract
- Diagnostics
Instance-declaration-record
declaration check: Row.id has the presentation shape its effective answers require
effective-answers-have-legal-presentation-shape
Applies for every adoption
This declaration check reads the adoption, not the running game. The action-cases description supplies all three duties. Resolve Row.id's effective answers from its row and the default answers. For every platform the case covers, every effective discovery answer except none requires an applicable presentation row; none requires no presentation row; and none cannot pair with reason-is-shown. This test checks nothing about a duty that does not apply to the effective answers. Any other shape makes the adoption invalid, and this test fails.
- Given
the
Instanceadoption, its two default answers, and action caseRow.id, not the running game- When
- a reviewer resolves the row's effective discovery and unavailable answers
- Then
- when the effective discovery answer is not none, then for each platform the case covers, at least one availability-presentations row that applies on that platform names
Row.id, as the action-cases description requires; under none, this test checks nothing about this requirement - when the effective discovery answer is none, no availability-presentations row names
Row.id, as the action-cases description requires; under another answer, this test checks nothing about this requirement - the effective answers are never none together with reason-is-shown, as the action-cases description requires
- a missing row, forbidden row, or forbidden effective pair makes the adoption invalid, and this test fails
- when the effective discovery answer is not none, then for each platform the case covers, at least one availability-presentations row that applies on that platform names
- Diagnostics
Instance-declaration-record
declaration check: Row.id names an action case in this adoption
presentation-action-case-join
Applies for every adoption
This declaration check reads the adoption, not the running game. The action-case field says the value is the id of an action-cases row of this adoption presented through the channel. Availability presentation Row.id must therefore name an existing action case: Row.action case. When the named action case is missing or misspelled, the adoption is invalid, and this test fails.
- Given
the
Instanceadoption and availability presentationRow.id, not the running game- When
- a reviewer checks the action case that the row names
- Then
- an action-cases row with id
Row.action caseexists in this adoption - a missing or misspelled action case makes the adoption invalid, and this test fails
- an action-cases row with id
- Diagnostics
Instance-declaration-record
declaration check: Row.id lists every candidate and always selects one
shared-input-completeness
Applies for every adoption
This declaration check reads the adoption and its cited prose, not the running game. For Row.id, Row.actions declared in must list every candidate the input can carry in the cited situation and each eligibility condition; Row.selection rule declared in must select exactly one and decide every reachable tie. Any other shape makes the adoption invalid, and this test fails. The test names the addresses and restates nothing from them.
- Given
the
Instanceadoption and shared-input caseRow.id, not the running game- When
- a reviewer compares the cited candidate and selection rules in every reachable cited situation
- Then
Row.actions declared inlists every candidate thatRow.action inputcan carry in the situation atRow.situation declared inand states each eligibility conditionRow.selection rule declared inselects exactly one candidate and decides every reachable tie- a missing candidate, uncovered result, or reachable tie makes the adoption invalid, and this test fails
- Diagnostics
Instance-declaration-recordInstance-candidate-set
declaration check: every multi-candidate input has exactly one matching row
multi-candidate-input-has-one-row
Applies for every adoption
This declaration check reads the adoption and its cited prose, not the running game. Every situation where one action input has several candidates must have exactly one matching shared-input-cases row. For an input with at most one candidate, this test checks nothing. A missing or duplicate match makes the adoption invalid, and this test fails.
- Given
the
Instanceadoption and every cited situation where one action input can have several candidates, not the running game- When
- a reviewer matches shared-input-cases rows to those situations and inputs
- Then
- each action input with several candidates has exactly one matching shared-input-cases row
- an input with at most one candidate needs no row, and this test checks nothing about such an input
- a missing or duplicate match makes the adoption invalid, and this test fails
- Diagnostics
Instance-declaration-record
declaration check: presentation pairs do not repeat and action cases do not overlap
rows-do-not-repeat-or-overlap
Applies for every adoption
This declaration check reads the adoption and its cited prose, not the running game. The availability-presentations description forbids a repeated action-case and channel pair, and the action-cases description forbids two cases for the same action in overlapping situations. The contract sets no maximum row count. A repetition or overlap makes the adoption invalid, and this test fails.
- Given
the
Instanceadoption and its cited prose, not the running game- When
- a reviewer compares every presentation-row pair and every pair of action cases
- Then
- no two availability-presentations rows repeat one action-case and channel pair
- no two action-cases rows cover the same action in overlapping situations
- the contract imposes no maximum row count
- a repeated pair or overlapping action case makes the adoption invalid, and this test fails
- Diagnostics
Instance-declaration-record
declaration check: Row.id's action citation states its duty
action-citation-duty
Applies for every adoption
This declaration check reads the adoption and Row.action declared in, not the running game. The citation must name Row.id's action, ordinary permission, and complete effect. A missing duty makes the adoption invalid, and this test fails. The test names the address and restates nothing from it.
- Given
the
Instanceadoption andRow.action declared in, not the running game- When
- a reviewer checks the citation's meaning
- Then
Row.action declared innames the action, its ordinary permission, and its complete effect- a missing duty makes the adoption invalid, and this test fails
- Diagnostics
Instance-declaration-record
declaration check: Row.id's situation citation states its duty
action-situation-citation-duty
Applies for every adoption
This declaration check reads the adoption and Row.situation declared in, not the running game. The citation must name every covered play situation and the nearest similar excluded situations for Row.id. A missing duty makes the adoption invalid, and this test fails. The test names the address and restates nothing from it.
- Given
the
Instanceadoption andRow.situation declared in, not the running game- When
- a reviewer checks the citation's meaning
- Then
Row.situation declared innames every play situation covered byRow.idand the nearest similar situations excluded from it- a missing duty makes the adoption invalid, and this test fails
- Diagnostics
Instance-declaration-record
declaration check: Row.id's presentation citation states its duty
action-presentation-citation-duty
Applies for every adoption
This declaration check reads the adoption and Row.presentation rule declared in, not the running game. The citation must state every discovery route and unavailable state for Row.id, including an explicit no-route statement where applicable. A missing duty makes the adoption invalid, and this test fails. The test names the address and restates nothing from it.
- Given
the
Instanceadoption andRow.presentation rule declared in, not the running game- When
- a reviewer checks the citation's meaning
- Then
Row.presentation rule declared instates every discovery route and unavailable state forRow.id, including an explicit statement when no route exists- a missing duty makes the adoption invalid, and this test fails
- Diagnostics
Instance-declaration-record
declaration check: Row.id's platform citation states its duty
presentation-platform-citation-duty
Applies for every adoption
This declaration check reads the adoption and Bind platform citation, not the running game. The citation must name the platform on which Row.id applies, and the row applies only there. A missing duty makes the adoption invalid, and this test fails. The test names the address and restates nothing from it.
- Given
the
Instanceadoption andBind platform citation, not the running game- When
- a reviewer checks the citation's meaning
- Then
Bind platform citationnames the platform on whichRow.idapplies- the row applies only on that platform
- a missing duty makes the adoption invalid, and this test fails
- Diagnostics
Instance-declaration-record
declaration check: Row.id's channel citation states its duty
channel-rule-citation-duty
Applies for every adoption
This declaration check reads the adoption and Row.channel rule declared in, not the running game. The channel-rule-declared-in field requires both forms, or the available form alone for a never-unavailable or unchanged case, and says the citation states whether the channel identifies the action. A missing duty makes the adoption invalid, and this test fails. The test names the address and restates nothing from it.
- Given
the
Instanceadoption andRow.channel rule declared in, not the running game- When
- a reviewer checks the citation's meaning
- Then
Row.channel rule declared instatesRow.id's available and unavailable forms, or the available form alone for a never-unavailable or unchanged case, and whether the channel identifies the action- a missing duty makes the adoption invalid, and this test fails
- Diagnostics
Instance-declaration-record
declaration check: the situation citation of Row.id states its duty
shared-situation-citation-duty
Applies for every adoption
This declaration check reads the adoption and Row.situation declared in, not the running game. The citation must name the situation in which several actions share Row.action input. A missing duty makes the adoption invalid, and this test fails. The test names the address and restates nothing from it.
- Given
the
Instanceadoption andRow.situation declared in, not the running game- When
- a reviewer checks the citation's meaning
- Then
Row.situation declared innames the situation in which several actions shareRow.action input- a missing duty makes the adoption invalid, and this test fails
- Diagnostics
Instance-declaration-record
declaration check: the candidate citation of Row.id states its duty
shared-actions-citation-duty
Applies for every adoption
This declaration check reads the adoption and Row.actions declared in, not the running game. The citation must list every candidate for Row.action input in the cited situation and each eligibility condition. A missing duty makes the adoption invalid, and this test fails. The test names the address and restates nothing from it.
- Given
the
Instanceadoption andRow.actions declared in, not the running game- When
- a reviewer checks the citation's meaning
- Then
Row.actions declared inlists every candidate action forRow.action inputin the cited situation and the conditions that make each candidate eligible- a missing duty makes the adoption invalid, and this test fails
- Diagnostics
Instance-declaration-record
declaration check: the action-input citation of Row.id states its duty
shared-action-input-citation-duty
Applies for every adoption
This declaration check reads the adoption and Row.action input declared in, not the running game. The Fixed control rule must name shared action input Row.action input and the physical activation that produces it. A missing duty makes the adoption invalid, and this test fails. The test names the address and restates nothing from it.
- Given
the
Instanceadoption andRow.action input declared in, not the running game- When
- a reviewer checks the citation's meaning
- Then
Row.action input declared innames the shared action inputRow.action inputand the physical activation that produces it- a missing duty makes the adoption invalid, and this test fails
- Diagnostics
Instance-declaration-record
declaration check: the selection citation of Row.id states its duty
shared-selection-citation-duty
Applies for every adoption
This declaration check reads the adoption and Row.selection rule declared in, not the running game. The citation must select exactly one offered action and decide every reachable tie. A missing duty makes the adoption invalid, and this test fails. The test names the address and restates nothing from it.
- Given
the
Instanceadoption andRow.selection rule declared in, not the running game- When
- a reviewer checks the citation's meaning
- Then
Row.selection rule declared inselects exactly one offered action and decides every reachable tie- a missing duty makes the adoption invalid, and this test fails
- Diagnostics
Instance-declaration-record
declaration check: the presentation citation of Row.id states its duty
shared-presentation-citation-duty
Applies for every adoption
This declaration check reads the adoption and Row.presentation rule declared in, not the running game. The citation must identify the selected offered action before Row.action input becomes an action attempt. A missing duty makes the adoption invalid, and this test fails. The test names the address and restates nothing from it.
- Given
the
Instanceadoption andRow.presentation rule declared in, not the running game- When
- a reviewer checks the citation's meaning
- Then
Row.presentation rule declared inidentifies the selected offered action beforeRow.action inputbecomes an action attempt- a missing duty makes the adoption invalid, and this test fails
- Diagnostics
Instance-declaration-record
action legibility holds for the whole run
legibility-holds
Applies for every adoption
Across Inputs scope, every available covered action meets its effective discovery promise; every unavailable covered action meets its effective unavailable answer; every channel distinguishes the states it promises; every shared input offers exactly one action before the attempt; and no prompt names an old binding as current. For a case that the adoption cannot construct, this test checks nothing.
- Holds
every available covered action met its effective discovery promise; every unavailable covered action met its effective unavailable answer; every availability-presentation channel distinguished the states it promises; every shared input offered exactly one action before the attempt; no prompt named an old binding as current; for a case that the adoption cannot construct, this test checks nothing
- Seeds
Inputs seeds- Scope
Inputs scope- Diagnostics
Instance-observer-resultInstance-presentation-traceInstance-prompt-bindingsInstance-candidate-setInstance-offered-actionInstance-refresh-log