clone

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

main
miau-is-true / openspec / specs / game-presentation / spec.md
spec.md 8.7K source

game-presentation Specification

Purpose

Define how the browser presents a fixed-coordinate emoji puzzle board, active word rules, controls, and readable feedback without changing simulation state.

Requirements

Requirement: The app SHALL render the simulation as a readable emoji grid

The renderer SHALL draw the simulation on the ink-and-signal full-screen canvas with fixed integer cell geometry, hard-edged board and tiles, stable stack order, and no decorative overlap. Object nouns SHALL use emoji mappings or readable text fallbacks, word entities SHALL remain legible, and physical sentence spans SHALL drive sentence bars.

Scenario: Stacked entities remain visible

  • WHEN multiple objects or words occupy one cell
  • THEN the renderer preserves their identity with the documented stack offset and does not treat decorative elements as simulation occupancy

Scenario: A modded noun has no emoji fallback

  • WHEN a noun has no declared emoji mapping
  • THEN the renderer uses a readable text fallback within its fixed cell

Scenario: A sentence bar follows state spans

  • WHEN the engine exposes state.sentences
  • THEN the renderer draws maximal horizontal or vertical bars from those physical spans, including exact duplicates

Requirement: The app SHALL show active rules and turn feedback

The presentation SHALL render the current proof HUD, ledger, hints, keycap controls, active/inactive words, and no-YOU state on the stage. It SHALL consume settled engine events for blocked movement, undo, reset, transformations, defeat, victory, and rule changes without changing simulation state. New ledger sentences SHALL stamp tile by tile; broken sentences SHALL strike and fall away. Changed step digits SHALL roll up on forward counts and down on Undo. Pushed word tiles SHALL skid toward actual travel, while pushers remain level. Visible keycaps SHALL press when their corresponding keyboard, gamepad, or touch action fires.

Scenario: A pushed word skids independently of its pusher

  • WHEN a settled accepted turn records a word moved with non-null pushedBy
  • THEN the word tilts toward its travel during its visual tween and rests level at the destination, while the pusher does not tilt

Scenario: Undo rolls the step counter downward

  • WHEN Undo restores an earlier move count
  • THEN the clipped digits roll toward the lower number and settle on the restored count

Scenario: New and broken sentences have distinct motion

  • WHEN a word push forms one sentence and breaks another
  • THEN the new physical sentence's tiles stamp in sequence and the broken sentence strikes, drops, and leaves without altering the engine's rule list

Requirement: Text effects SHALL support variable-length labels without driving grid geometry

The app MAY use Pretext or an equivalent text-effect layer for proof names, hints, ledger labels, pack feedback, and scene copy. Text effects SHALL be laid out in their owning HUD or scene region and SHALL not determine integer simulation coordinates or collision geometry.

Scenario: A long proof title does not move cells

  • WHEN a proof title or hint is longer than its HUD region
  • THEN it fits, wraps, or truncates according to the stage copy rules while every grid cell retains its coordinate and size

Requirement: The presentation SHALL provide accessible control feedback

The app SHALL expose a polite live region and readable text equivalents for movement, undo, restart, menu, scene, rule, level, pack, and outcome status. Keyboard, gamepad, and touch users SHALL be able to reach every player-facing action, and reduced motion SHALL preserve status without animation.

Scenario: Controls are understandable without animation

  • WHEN reduced motion is enabled or animation is unavailable
  • THEN the board, INDEX, active rules, current proof, pack status, and controls remain understandable from static text and tile labels

Requirement: Supported character glyphs SHALL use scoped facing state

The presentation SHALL maintain horizontal facing per entity ID as visual state separate from simulation coordinates. The built-in MIAU 🐈 SHALL have native left-facing direction, including when a pack repeats that same glyph as a plain palette string. A mod palette object MAY declare faces: 'left' | 'right' for another profile glyph; a different plain string and a front-facing glyph such as FENN 🦊 SHALL remain non-directional by default. Every accepted horizontal displacement SHALL update a directional entity's facing to its travel direction, including being pushed. When a pushed entity also moves itself horizontally in the same turn, its self-movement direction SHALL take precedence. Vertical movement, transformation, idle frames, and blocked intents SHALL preserve prior horizontal facing. Undo SHALL restore per-ID facing history, while loading or resetting a level SHALL use its native declared or neutral facing. A facing change MAY use a glyph-only squash; reduced motion SHALL apply the direction immediately.

Scenario: Built-in cat faces forward in every pack

  • WHEN a MIAU entity with the built-in 🐈 glyph moves right in a core proof or a pack with palette.MIAU: '🐈'
  • THEN the settled board mirrors the native-left glyph to face right, without mirroring its cell, shadow, or text

Scenario: Leftward travel uses the native pose

  • WHEN that MIAU entity subsequently moves left
  • THEN the settled board draws the native-left glyph without a mirror

Scenario: Pushes turn a directional actor

  • WHEN a directional entity is successfully pushed one cell to the right
  • THEN its settled horizontal facing is right, while a blocked push leaves its prior facing unchanged

Scenario: Self-movement wins after a push

  • WHEN one accepted turn pushes an actor right and then moves that actor left under an automaton rule
  • THEN the actor's settled horizontal facing is left

Scenario: Vertical movement preserves the horizontal pose

  • WHEN a MIAU entity moves up or down after facing right
  • THEN its horizontal glyph orientation remains right because the side-profile emoji has no vertical view

Scenario: A transformation preserves per-ID facing

  • WHEN an entity transforms to another noun during a settled turn
  • THEN the entity ID retains its prior horizontal facing, unless the resulting noun has no directional glyph and uses its normal fallback

Scenario: A custom mod glyph opts in explicitly

  • WHEN a mod supplies a different profile glyph with faces: 'right'
  • THEN leftward travel mirrors that glyph, while a different plain-string glyph is not mirrored

Scenario: Undo and reset restore the correct pose

  • WHEN the player undoes a directional turn or resets/loads a level
  • THEN Undo restores the prior per-ID facing, and reset/load returns MIAU to the declared native-left pose

Scenario: Reduced motion skips facing animation

  • WHEN reduced motion is enabled and a horizontal move changes facing
  • THEN the settled glyph faces its direction immediately without a transitional squash

Requirement: Undo SHALL restore the complete visual entity state

After a successful Undo, the presentation SHALL reconcile visible entities from the restored engine snapshot by stable ID, including existence, noun or glyph, grid position, facing, control marker, and active visual effects. Effects created by the undone death turn SHALL not remain visible after reconciliation.

Scenario: Proof 05 death then Undo restores MIAU immediately

  • WHEN MIAU dies in proof 05 and the player invokes Undo on a mobile viewport
  • THEN the restored MIAU glyph and its control marker are visible at the prior position on the next presentation frame, and the red death shadow from the undone turn is absent

Scenario: Repeated death and Undo does not accumulate stale effects

  • WHEN the player repeats a death followed by Undo multiple times
  • THEN each restored snapshot shows exactly the engine entities for that turn and no prior death shadow or missing glyph persists

Scenario: Reset clears death presentation state

  • WHEN the player resets after a death or after an Undo
  • THEN the board shows the native initial entities and facing, with no stale destruction effect or missing controlled glyph

Scenario: Reduced motion restores without a transition gap

  • WHEN reduced motion is enabled and the player invokes Undo after death
  • THEN the restored entities and controls appear immediately with no intermediate death animation frame

Scenario: Input paths share the same recovery

  • WHEN Undo is invoked by keyboard, touch, or Standard gamepad after a death
  • THEN each input path produces the same restored visual state and unchanged engine move history