clone

a browser grid puzzle game where you push words around to rewrite the rules of each level

main
miau-is-true / openspec / changes / add-rule-driven-automata / specs / rule-driven-automata / spec.md
spec.md 10.1K source

ADDED Requirements

Requirement: Levels MAY declare a deterministic property automaton

A level MAY author automata records with { id, subject?, property, pattern, phase? }. pattern SHALL be an ordered list of { action: 'move', dx, dy, cue?, sound? } or { action: 'wait', cue?, sound? } objects. Move deltas SHALL be cardinal. A missing subject SHALL enable property-carried mode; a present subject SHALL restrict matching to that noun. Runtime state MAY add derived fields, but carriers, flattened instanceIds, active, and next SHALL NOT be required authored mod fields. An absent automata field SHALL preserve current level behavior.

Scenario: A property-carried automaton starts at phase zero

  • WHEN a level declares { id: 'clock', property: 'TICK', pattern: [{ action: 'move', dx: -1, dy: 0 }, { action: 'wait' }] }
  • THEN the initial state reports automata entry clock, phase zero, and the first normalized pattern step

Scenario: A subject restricts the carrier

  • WHEN a level declares { id: 'mouse-clock', subject: 'MOUSE', property: 'TICK', pattern: [{ action: 'move', dx: -1, dy: 0 }] }
  • THEN only the noun matched by MOUSE IS TICK follows the automaton and other nouns matched by IS TICK do not

Scenario: A legacy level remains compatible

  • WHEN a level has no automata field
  • THEN the engine uses existing board-rule state and exposes no automata entry

Requirement: Board rules SHALL activate and transfer property-carried automata

An automaton SHALL be active for each entity whose noun is currently matched by the parsed SUBJECT IS PROPERTY rule, subject to an optional automaton subject restriction. The property word SHALL remain part of the visible board sentence, and pushing it SHALL transfer or remove the active behavior after the next rule parse without mutating global rules.

Scenario: A visible property rule activates a carrier

  • WHEN the board forms MOUSE IS TICK for an automaton with property TICK
  • THEN the current MOUSE entity is active for that automaton and follows its current pattern step

Scenario: Pushing the property word transfers the carrier

  • WHEN a player pushes the TICK word so the board changes from MOUSE IS TICK to BELL IS TICK
  • THEN the next parsed state removes MOUSE as an active carrier and makes BELL active for the automaton

Requirement: Turns SHALL resolve player and automaton actions deterministically

For an accepted player turn, the engine SHALL resolve the player move first, re-parse rules and transformations, resolve automaton actions for current active entities, re-parse rules and transformations again, then resolve SINK, DEFEAT, and WIN. Automaton actions SHALL use the existing atomic push rules, move front-first along their action direction, and tie by stable entity ID. A blocked player input SHALL not start a turn.

Scenario: Player movement precedes automaton movement

  • WHEN a player move pushes a property word into a new sentence
  • THEN the engine reparses that sentence before selecting active entities and the new active entity acts in the same accepted turn

Scenario: Automaton movement uses front-first pushing

  • WHEN two active entities act right with a PUSH chain ahead
  • THEN the engine resolves the front-most entity first, applies the same atomic push rules as YOU, and produces stable automated movement entries

Scenario: Contacts settle after both movement phases

  • WHEN an automaton action moves an entity into SINK, DEFEAT, or WIN contact
  • THEN the engine resolves those contacts only after the second parse/transform phase and exposes the settled result

Requirement: Phase SHALL advance on active accepted turns

If at least one entity is active for an automaton after the player phase, its shared phase SHALL advance exactly once after the automaton beat, including when the action is blocked or is wait. A blocked or invalid player input SHALL not advance phase. The automata state SHALL retain id, optional subject, property, pattern, phase, and active.

Scenario: An active entity advances phase

  • WHEN a player makes an accepted turn while at least one entity is active for TICK
  • THEN the automata state increments phase once and the next pattern step becomes the step used by the following turn

Scenario: A blocked automaton action still consumes the beat

  • WHEN an accepted player turn occurs but the active entity's move is blocked by STOP or bounds
  • THEN the entity stays in place, automated reports the block, and phase still advances once

Scenario: Explicit wait is a beat

  • WHEN the active automaton step has action: 'wait' and the player makes an accepted turn
  • THEN no automaton entity moves, phase advances once, and the automated entry carries any cue or sound

Scenario: No active entity pauses the automaton

  • WHEN an accepted player turn leaves no entity matched by the automaton property
  • THEN phase and the automata entry remain unchanged and no automated movement is emitted

Requirement: State and events SHALL expose automated movement and beat feedback

The settled state and event automata entries SHALL expose the normalized authored fields id, optional subject, property, pattern, and phase, plus derived active, carriers: [{ noun, instanceIds }], flattened instanceIds, and next, where next is the action object at pattern[phase]. Settled events SHALL additionally expose an automated array whose entries report action, entity ID, from/to coordinates when moved, blocked details when blocked, and optional cue/sound. The presentation MAY derive current/next beat labels from these fields and SHALL expose that feedback in visible and accessible text; reduced motion SHALL apply the same state immediately. Derived fields SHALL not be required authored mod fields.

Scenario: An automated move is observable

  • WHEN an accepted turn advances an active automaton move
  • THEN the settled event automata entry includes the derived carrier groups, flattened instanceIds, and next action, and automated includes action move, entity ID, from/to coordinates, and cue/sound when supplied

Scenario: A blocked automated action is observable

  • WHEN an active automaton move is blocked
  • THEN the automated entry includes the action, entity ID, and block details while the state retains the entity position and the automata entry still exposes its derived carriers, instanceIds, and next

Scenario: Derived carrier fields follow active rules

  • WHEN a rule word is pushed and the active rule changes from MOUSE IS TICK to BELL IS TICK
  • THEN the next state and event automata entry reports carriers for BELL, flattened BELL instanceIds, and the action object at pattern[phase] without requiring those fields in the authored level data

Scenario: Reduced motion keeps beat feedback readable

  • WHEN reduced motion is enabled during an automaton turn
  • THEN the stage derives and displays the current/next pattern steps immediately without changing the simulation result

Requirement: Automata SHALL be validated in local and shared pack paths

The host SHALL validate automaton IDs, optional subject, property vocabulary, object action tokens, cardinal move deltas, pattern bounds, phase bounds, cue/sound values, and duplicate IDs before registering or installing a pack. Trusted local CommonJS modules MAY provide automata data; data-only shared payloads SHALL carry normalized records and SHALL never execute code.

Scenario: A valid local automaton is registered

  • WHEN a trusted local module exports a level with valid object pattern steps
  • THEN the loader registers the normalized automata entry only after complete pack validation

Scenario: Invalid automaton data is rejected atomically

  • WHEN a pack contains an unknown action, non-cardinal delta, invalid property, or duplicate automaton ID
  • THEN validation reports the pack and level path and registers none of its automata or levels

Scenario: A shared automaton remains data-only

  • WHEN a shared payload contains normalized automata entries
  • THEN the decoder validates and previews the entries without evaluating module source or installing before explicit confirmation

Requirement: Automata state SHALL be part of Undo, reset, replay, and solver state

Undo snapshots, reset state, deterministic replay records, and solver state keys SHALL include normalized automata id, optional subject, property, pattern, phase, and active state. Undo SHALL restore the preceding phase and active state; replay and solver SHALL reproduce the same automated movement and phase sequence for the same accepted intents.

Scenario: Undo restores a phase transition

  • WHEN the player undoes a turn that advanced an automaton from phase 3 to phase 4
  • THEN the prior phase, active state, board, and resolved rules are restored exactly

Scenario: Reset restores native automata state

  • WHEN the player resets after automaton turns
  • THEN every automata entry returns to its declared phase or zero and no prior automated movement remains

Scenario: Solver distinguishes phase states

  • WHEN two search nodes have identical board coordinates but different automata phases or active states
  • THEN the solver treats them as distinct states and does not collapse one path into the other

Requirement: Automata SHALL provide a visual feedback handoff

The presentation handoff SHALL use normalized pattern steps, phase, active, and automated cue/sound fields to show the current and next pattern actions. It SHALL keep this feedback separate from simulation geometry and preserve readable state under reduced motion.

Scenario: A pattern step is ready for visual review

  • WHEN an author supplies normalized automata data and a settled automated event
  • THEN reviewers can map phase and action objects to the current/next visual feedback and movement result

Scenario: Missing optional cue does not block play

  • WHEN a valid automaton step omits cue or sound
  • THEN the engine and stage retain the normalized action and phase and use the default visual/audio treatment