clone

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

docs: describe nine-proof stage and pack sharing workflow

Dami committed 2a783bb
commit
2a783bbb3d657ff0b959b21f21d2a13c79b29229
parent
4d13d1e890bd916401c6ebf087555a1028196158
author
Dami <dami.etoile@gmail.com>
4 files changed, +131 -21
MREADME.md36++++++++++++----
Mdocs/modding.md68++++++++++++++++++++++++++++--
Mdocs/roadmap.md42++++++++++++++++---
Mprogress.md6+-
M README.md +28 -8
@@ -1,6 +1,6 @@
11 # Miau Is True22 3-A small browser puzzle engine for moving words, changing rules, and solving grid puzzles. The first playable release uses emoji objects, pushable sentence tiles, three teaching levels, and local CommonJS level packs.3+A small browser puzzle engine for moving words, changing rules, and solving grid puzzles. The current verified content set contains nine authored proofs: three core levels, three Basic Proofs levels, and three Word Lab levels.44 55 ## Run it66
@@ -9,26 +9,46 @@ npm install
99 npm run dev1010 ```1111 12-Open the local URL printed by Vite. Run `npm test` for the engine and content fixtures, and `npm run build` to produce `dist/`.12+Open the local URL printed by Vite. Run `npm test` for the engine, pack, sharing, and content fixtures, and `npm run build` to produce `dist/`.1313 1414 The current [public test build](https://fcbc.n.zip/) uses the stable nzip site15-alias `public:miau-is-true`. Its current revision expires October 23, 2026;16-re-publishing to the same target preserves the URL. The site is a static test17-origin that can support a later shoo.dev identity integration. The current game18-has no account or sign-in flow.15+alias `public:miau-is-true`. A refreshed public revision is planned after the16+current stage integration pass; re-publishing to the same target preserves the17+URL. The site is a static test origin that can support a later shoo.dev identity18+integration. The current game has no account or sign-in flow.1919 2020 ## Play2121 2222 - Arrow keys or WASD: move one cell.2323 - Z: undo a successful move.2424 - R: restart the current level.25-- F: toggle fullscreen.25+- The desktop fullscreen button is available in developer mode (`?dev`).26+- Pause includes sound and optional music controls.2627 - Touch controls, Undo, Restart, and Continue are available on screen.2728 2829 Each word is a pushable object. Straight sentences read left to right or top to bottom. `MIAU IS YOU` makes the cat controllable; moving `STOP` out of `ROCK IS STOP` makes rocks passable. `AND` can join subjects or predicates. Words can also turn one noun into another, such as `MIAU IS ROCK`.2930 3031 The first property set is `YOU`, `PUSH`, `STOP`, `WIN`, `SINK`, and `DEFEAT`. This engine has its own MIAU levels and presentation; it does not attempt full compatibility with Baba Is You.3132 33+The engine also exposes physical sentence spans for presentation. Each span34+keeps its word IDs and horizontal or vertical axis, while semantic rules remain35+deduplicated. Settled turn events report movement, push provenance, rule36+deltas, transformations, destruction, blocked inputs, and win state.37+38+The bundled content is currently:39+40+- Core: `src/levels.js`, three required onboarding proofs.41+- Basic Proofs: `mods/garden-basics.cjs` (stable internal pack ID `garden-basics`), PUSH, SINK, and DEFEAT follow-ups.42+- Word Lab: `mods/word-lab.cjs`, shared control, noun transformation, and rule cargo.43+44+The pack service and persistent pack library are implemented and tested for45+preview, explicit install, reload, export, URL sharing, replacement, forking,46+and removal. A local module imported from Workshop first opens a Gift preview;47+the player chooses **Keep and play** before it is installed. A shared `#pack=`48+URL follows the same pending Gift flow. Workshop provides Import, Play, Share49+link, Export, and Remove actions. URL data is decoded without evaluating50+CommonJS source. The stage and browser integration pass is still in progress.51+3252 ## Make a mod3353 3454 Use the **Import module** control to select a trusted local `.cjs` or `.js` file. A mod exports a CommonJS object with a manifest, level data, and optional noun palette. See [the example mod](mods/example.cjs) and [modding guide](docs/modding.md). Local modules execute JavaScript in the browser, so load files you trust.
@@ -36,7 +56,7 @@ Use the **Import module** control to select a trusted local `.cjs` or `.js` file
3656 ## Design and workflow3757 3858 - [Design backbone](docs/design-backbone.md): vocabulary, turn order, puzzle design research, and extension boundaries.39-- [Roadmap](docs/roadmap.md): the next OpenSpec changes and decisions to settle.59+- [Roadmap](docs/roadmap.md): verified work, active OpenSpec changes, and long-term plans.4060 - `openspec/`: behavioral specs and the history of proposed changes. Start a new feature with `openspec new change <name>`, read `openspec instructions` for each artifact, validate before implementation, then archive after verification.4161 4262 Pretext sizes variable-length hint copy. Grid coordinates are fixed integers, so emoji and text metrics never change collision geometry. UI sounds come from the supplied Kenney UI Pack (CC0; license in `public/audio/LICENSE.txt`).
M docs/modding.md +64 -4
@@ -15,6 +15,7 @@ module.exports = {
1515 manifest: { id: 'hello-miau', name: 'Hello Miau', version: '1.0.0' },1616 palette: { MIAU: '🐈', FLAG: '🚩' },1717 levels: [{18+ id: 'intro',1819 width: 5,1920 height: 3,2021 objects: [
@@ -29,8 +30,10 @@ module.exports = {
2930 3031 The engine recognizes `word` records as rule text and `object` records as3132 things in the puzzle. Word and noun values are normalized to uppercase. A32-level's `width` and `height` are cell counts, and every object position must be33-inside that rectangle. Multiple objects may share a cell.33+level's `id` is its stable lowercase identity within the pack; changing a34+title does not change that identity. `width` and `height` are cell counts, and35+every object position must be inside that rectangle. Multiple objects may36+share a cell.3437 3538 ## Module contract3639
@@ -47,7 +50,9 @@ Manifest IDs use lowercase letters, numbers, `.`, `_`, and `-`, and must start
4750 with a letter. Tokens use uppercase letters, numbers, `_`, and `-`. `IS` and4851 `AND`, `YOU`, `PUSH`, `STOP`, `WIN`, `SINK`, and `DEFEAT` are reserved rule4952 tokens. They may appear as word text, but cannot be object nouns, palette keys,50-or vocabulary entries. A level may also include `title` and `hint`.53+or vocabulary entries. Every level requires a unique lowercase `id` and may54+also include `title` and `hint`. A pack can contain at most 64 levels, each55+with at most 4096 entities. The local CommonJS source limit is 512 KiB.5156 5257 ## The `@miau/engine` helper5358
@@ -62,7 +67,7 @@ module.exports = {
6267 levels: [level(4, 2, [6368 word('CAT', 0, 0), word('IS', 1, 0), word('YOU', 2, 0),6469 object('CAT', 0, 1),65- ], { title: 'First step' })],70+ ], { id: 'first-step', title: 'First step' })],6671 };6772 ```6873
@@ -92,3 +97,58 @@ Validation reports every problem in one pass: malformed manifest fields,
9297 missing levels, out-of-bounds positions, duplicate IDs, unsupported object9398 kinds, invalid rule tokens, and invalid palette entries. This lets an editor9499 show actionable errors without starting a partially loaded mod.100+101+## Bundled teaching packs102+103+The repository includes two authored packs in addition to the three core104+levels:105+106+- `mods/garden-basics.cjs` displays as **Basic Proofs**. Its stable internal107+ pack ID remains `garden-basics`, with level IDs `garden-push`,108+ `garden-pond`, and `garden-thorns`. The levels isolate PUSH, SINK, and109+ DEFEAT, with a winning route for each.110+- `mods/word-lab.cjs` (`word-lab`) contains `shared-control`,111+ `change-what-you-are`, and `rules-are-cargo`. The levels cover shared YOU,112+ noun transformation, and editing a stacked predicate.113+114+Together with the core pack, these provide nine verified level proofs. The115+tests load each CommonJS file, create an engine game from every level, and116+replay a concrete winning intent sequence.117+118+## Pack service and sharing119+120+`src/pack-service.js` provides the presentation-independent pack operations:121+122+`listPacks`, `importPackText`, `exportPack`, `packLink`, `decodePackLink`,123+`installPack`, and `removePack`.124+125+Import and link decoding return a preview and do not change the catalog. The126+caller must explicitly pass the preview to `installPack`; duplicate IDs can be127+replaced or kept as a fork with a new ID and `forkOf` metadata. URL fragments128+are data-only and never execute CommonJS source.129+130+A valid shared URL enters a pending Gift state. **Keep and play** is the131+explicit install action; leaving the Gift state preserves the existing catalog.132+Local imports follow the same flow: Workshop, Import, Gift preview, then133+explicit **Keep and play**. Workshop also offers Play, Share link, Export134+`.cjs`, and Remove. Installed authored pack data is persisted through the pack135+library and reloaded without evaluating CommonJS. The service and pending136+install contract are covered by unit tests; the final stage and browser137+integration pass remains in progress.138+139+## OpenSpec status140+141+Physical sentence spans are shipped and archived under142+`openspec/changes/archive/2026-09-23-expose-sentence-spans/`. Pack sharing and143+stage integration are active changes under144+`openspec/changes/share-level-packs/` and145+`openspec/changes/build-ink-signal-stage/`; their remaining presentation and146+browser gates are not treated as shipped here.147+148+## Sentence spans for renderers149+150+The engine keeps semantic rules and physical sentences separate. A rule record151+contains its source word IDs and `axis` (`h` or `v`); `state.sentences` lists152+every maximal physical span, including exact duplicate sentences. Renderers153+can draw sentence bars from those spans without reparsing the board, while154+rule ledgers can continue to deduplicate identical semantic rules.
M docs/roadmap.md +36 -6
@@ -1,12 +1,34 @@
11 # Roadmap22 3-This is a planning queue, not a claim that the later vocabulary already works. Each milestone should become an OpenSpec change with scenarios and engine fixtures before implementation.3+This page distinguishes verified work from planned work. Each new milestone4+still needs an OpenSpec change with scenarios and engine fixtures before it is5+called shipped.46 5-## 0. Playable foundation — `build-dynamic-rule-engine`7+## Verified nine-proof stage8+9+The current content and engine proof set is nine authored levels:10+11+- Core: three MIAU teaching levels for YOU, PUSH, STOP, WIN, and AND.12+- Basic Proofs (`garden-basics` is the stable internal pack ID): three13+ CommonJS levels for PUSH, SINK, and DEFEAT.14+- Word Lab: three CommonJS levels for shared control, noun transformation,15+ and moving one property out of a stacked rule.16+17+The engine exposes E3 physical sentence spans (`state.sentences`) with source18+IDs and axis, while semantic rule records remain deduplicated. E3 is archived19+under `openspec/changes/archive/2026-09-23-expose-sentence-spans/`.20+21+The E4 pack service and persistent pack library are implemented and tested for22+preview, explicit installation, reload, replacement, forking, export, URL23+links, and removal. Local imports and shared URLs both enter an explicit Gift24+preview before installation. Workshop exposes Import, Play, Share link, Export,25+and Remove. The integrated stage and browser verification work remains active.26+27+## 1. Playable foundation — shipped628 729 Three MIAU puzzles establish the turn contract: stacked occupancy, cardinal movement, atomic push chains, `IS` and `AND`, six properties, transformations, undo, a CommonJS content format, and a fixed emoji grid. The completed OpenSpec change is archived at `openspec/changes/archive/2026-09-23-build-dynamic-rule-engine/`; its behavioral requirements are now the live specs in `openspec/specs/`.830 9-## 1. Make the rule language composable31+## 2. Make the rule language composable — planned1032 1133 Proposed changes: `add-negation-and-conditions`, then `add-paired-interactions`.1234
@@ -17,7 +39,7 @@ Proposed changes: `add-negation-and-conditions`, then `add-paired-interactions`.
1739 1840 **Gate:** every new word has a small teaching level, a rule display explanation, a conflict test, and an undo/replay fixture.1941 20-## 2. Let mods define behavior42+## 3. Let mods define behavior — planned2143 2244 Proposed change: `add-deterministic-mod-systems`.2345
@@ -25,7 +47,7 @@ The current CommonJS contract adds nouns, emoji, and levels. A later contract sh
2547 2648 **Gate:** a sample mod adds one genuinely new property, reproduces the same result from a recorded intent sequence, and fails cleanly when its handler errors.2749 28-## 3. Author and test puzzles50+## 4. Author and test puzzles — planned2951 3052 Proposed change: `add-level-editor-and-replay`.3153
@@ -36,7 +58,15 @@ Proposed change: `add-level-editor-and-replay`.
3658 3759 **Gate:** a designer can build, play, undo, export, reload, and replay a puzzle without changing source files.3860 39-## 4. Campaign and sharing61+## 5. Campaign and sharing — v0.3 in progress62+63+The pack service, persistence, data-only sharing path, local import preview,64+URL Gift preview, and Workshop actions are implemented. The active OpenSpec65+change is `openspec/changes/share-level-packs/`; the active stage change is66+`openspec/changes/build-ink-signal-stage/`. Remaining work includes the final67+browser integration pass, public test URL refresh, and campaign UI polish.68+Do not mark the designer-owned S3 through S10 work shipped until those gates69+are verified.4070 4171 Proposed change: `add-campaign-progression`.4272
M progress.md +3 -3
@@ -4,10 +4,10 @@ Original prompt: I want to create a web app game engine that supports 'baba is y
44 55 2026-09-23: Research inventory added at docs/design-backbone.md, drawing from creator interviews, GDC material, and Sokoban design literature. OpenSpec initialized for Codex; active change `build-dynamic-rule-engine` has proposal, four capability specs, design, and tasks. Git initialized on main with focused commits requested by the user.66 7-2026-09-23: Engine, three teaching levels, CommonJS loader, UI, and audio assets implemented in parallel. `npm test` and `npm run build` pass at this point. First Playwright canvas screenshot exposed a missing MIAU emoji mapping and interface gaps; fixes are in progress.7+2026-09-23: Engine, three teaching levels, CommonJS loader, UI, and audio assets implemented in parallel. The verified content set now contains nine proof levels across Core, Basic Proofs (stable internal pack ID `garden-basics`), and Word Lab. Sound and optional music controls are available from Pause. `npm test` and `npm run build` pass.88 99 2026-09-23: Playwright browser checks pass for rule breaking, keyboard and touch movement, undo, reset, valid and invalid CommonJS imports, victory, and continuing to the next level. Inspected the rule-break and victory screenshots and the text game state; the rule table updates when STOP moves. Level 2's wall-rule shortcut was sealed and its intended push solution still passes. The designer requested richer settled turn events (E1/E2); source IDs and axes are implemented, and the event payload is receiving a final ordering/contact review before OpenSpec archival.1010 11-2026-09-23: E2 event review completed. Movement includes push provenance and contact-destroyed movers; rule deltas retain source IDs and axis; blocked events identify the physical blocker. All 24 Node tests and the production build pass. The local and public nzip origins both pass the Playwright integration check. Published https://fcbc.n.zip/ to the existing `public:miau-is-true` alias with a 30-day TTL. OpenSpec change `build-dynamic-rule-engine` was validated and archived; four capability specs are now live.11+2026-09-23: E2 event review completed. Movement includes push provenance and contact-destroyed movers; rule deltas retain source IDs and axis; blocked events identify the physical blocker. E3 sentence spans are implemented and archived at `openspec/changes/archive/2026-09-23-expose-sentence-spans/`: `state.sentences` preserves every maximal physical sentence with source IDs and axis while semantic rules deduplicate. E4 pack-service and pack-library operations are implemented and unit tested, including local import preview, explicit install, reload, export, sharing, replacement, forking, and removal. Local imports and shared URLs both enter the Gift preview and require **Keep and play**. Workshop exposes Import, Play, Share link, Export, and Remove. The active OpenSpec changes are `share-level-packs` and `build-ink-signal-stage`; their final browser and public URL gates remain in progress. A refreshed revision of https://fcbc.n.zip/ is planned after that pass. OpenSpec change `build-dynamic-rule-engine` was validated and archived.1212 13-TODO: The visual design owner is developing the board-first presentation and can consume E1/E2 through docs/design-inbox.md. Future mechanic changes should begin with a new OpenSpec change from the roadmap.13+TODO: v0.3 integration is in progress: finish the browser verification and public test URL refresh for the local and URL Gift flows, Workshop actions, persistent packs, and optional music. Keep designer-owned S3 through S10 work planned until its gates are verified. Future mechanic changes should begin with a new OpenSpec change from the roadmap.