world-index-navigation Specification
Purpose
TBD - created by archiving change add-world-index-navigation. Update Purpose after archive.
Requirements
Requirement: Each registered pack SHALL own a world and INDEX sheet range
The catalog and INDEX layout SHALL create one world record and one or more pack-owned sheets for every registered pack, including core. Sheets SHALL hold at most fifteen nodes, and a world with more than fifteen proofs SHALL continue onto another sheet in the same world. World order SHALL be core first, then bundled registration order, then imported install order. Layout SHALL NOT infer world identity from origin or a hard-coded pack ID list.
Scenario: Bundled packs remain separate worlds
- WHEN core, crossword, crate-works, and tidewater are registered in that order as the approved default bundle
- THEN the layout exposes four worlds in that order, with each pack's nodes
in its own sheet range and no bundled node assigned
worldId: core
Scenario: Example packs remain available through import
- WHEN garden-basics or word-lab is imported
- THEN it becomes its own world after the default bundle without changing core, crossword, crate-works, or tidewater progress and order
Scenario: A long pack continues within its own world
- WHEN an imported pack has sixteen ordered proofs
- THEN it receives two sheets with the same world ID, fifteen nodes on the first sheet, and one node on the second sheet
Scenario: Registration order survives replacement and forking
- WHEN a bundled pack is replaced or an imported pack is forked
- THEN replacement keeps the existing world position and the fork appends as a new imported world without reordering other worlds
Requirement: World identity metadata SHALL use nonblocking W11 validation
An optional manifest.world SHALL accept a glyph that is exactly one grapheme
cluster counted with Intl.Segmenter at granularity: 'grapheme' and no more
than 16 UTF-16 code units. Its tagline SHALL be at most 80 characters, contain
no newline, use sentence case, and contain no · (U+00B7). Its accent SHALL
be one of you, push, stop, win, sink, defeat, or tick. An invalid
optional identity field SHALL add a nonblocking W11 note and fall back to the
first palette glyph, no tagline, and the default --fg path. Invalid gameplay
fields SHALL continue to reject the complete pack atomically.
Scenario: Valid world metadata is exposed
- WHEN a pack declares
{ glyph: '🌊', tagline: 'A wet proof.', accent: 'sink' } - THEN the normalized catalog world exposes those values with the pack's stable ID, author, origin, and registration order
Scenario: Invalid world metadata keeps the pack playable
- WHEN a pack declares
accent: 'glow', a multi-grapheme glyph, or an overlong tagline - THEN registration succeeds with a W11 note, uses the fallback world identity, and keeps the pack's gameplay and active-level data available
Scenario: World tagline reports the middle-dot correction clearly
- WHEN a tagline contains
· - THEN the pack receives a W11 note saying
Tagline can't use ·; use a comma or a dash.and the normalized world has no tagline
Scenario: Gameplay validation remains atomic
- WHEN a pack has valid or invalid
manifest.worldmetadata but an invalid gameplay field - THEN the pack is rejected by the existing gameplay validator and is not added to the catalog
Scenario: A legacy pack receives defaults
- WHEN an otherwise valid pack omits
manifest.world - THEN registration succeeds and its world metadata uses the default glyph, no tagline, and the default foreground path accent
Requirement: INDEX progress SHALL be scoped per world
The INDEX view model SHALL expose the active world ID/number, world name, world
completion count, total proof count, and current world-strip position. Solved
state SHALL remain keyed by { packId, levelId }. The opener of every world
SHALL be available, later proofs SHALL unlock in order within that world, and a
proof solved in one world SHALL not unlock or count toward another world.
Scenario: Completion counts do not leak between worlds
- WHEN one proof is solved in world
alphaand none is solved in worldbeta - THEN alpha reports
1 /, beta reportsalphaTotal 0 /, and beta's second proof remains locked behind beta's openerbetaTotal
Scenario: Entering a world selects its local cursor
- WHEN the player leaves world
alphaafter selecting its third proof and later returns - THEN the INDEX restores alpha's saved cursor when it still exists, or selects alpha's first available node, without changing the active proof in another world
Requirement: INDEX SHALL navigate between worlds without wraparound
The navigator SHALL map Q/E, gamepad LB/RB, and one two-finger horizontal swipe per gesture to one-world-left/right actions. Walking forward from a world's terminal path node SHALL enter the next world's first node; walking backward from the first node SHALL enter the previous world's terminal node. The first and last world boundaries SHALL be no-ops with existing blocked-navigation feedback. Intra-world sheet boundaries SHALL remain distinct from world boundaries.
Scenario: Q and E switch one adjacent world
- WHEN the active world is the second of three and the player presses Q once, then E once
- THEN the navigator enters world one, then world two, with one transition per input and no proof move recorded
Scenario: Outer boundaries do not wrap
- WHEN the player presses Q in world one or E in world three
- THEN the world and active proof remain unchanged and the navigator returns a blocked-navigation indication
Scenario: Path edges cross worlds in travel direction
- WHEN the player walks right off the final path node of world one
- THEN the cursor enters world two's first node; walking left from world two's first node returns to world one's final node, without wrapping past the first or last world
Requirement: INDEX SHALL provide a stable world presentation seam
The INDEX scene SHALL consume a pure world view model containing world number,
world count, name, glyph, tagline, accent, per-world completion, and strip
position. The first entry into a world and Workshop PLAY SHALL emit a
world-card request with origin index or workshop, at most once per world per
session. The seam SHALL not change integer board coordinates or simulation
state.
Scenario: First entry requests a world card
- WHEN the player enters an unvisited world from INDEX
- THEN the scene emits one
world-cardrequest containing that world's normalized identity andorigin: indexbefore settling on its sheet
Scenario: Workshop PLAY requests the same card seam
- WHEN the player chooses PLAY for an unvisited pack in Workshop
- THEN the scene emits one
world-cardrequest withorigin: workshop, preserving the pack's first node and current simulation state
Scenario: Re-entry does not replay the card
- WHEN the player returns to a world whose card request was already settled during the current session
- THEN the world header view model updates without another card request