diff --git a/PLANS.md b/PLANS.md index 16fbf64..12ffdff 100644 --- a/PLANS.md +++ b/PLANS.md @@ -853,7 +853,7 @@ Implementation and required verification are complete. ## Milestone 010 — On-device integration and resource hardening -**Status:** `IN_PROGRESS` +**Status:** `COMPLETE` ### Objective @@ -949,10 +949,42 @@ the ESP32-C6 Flash, RAM, socket, and network limits. (internal free 235,372 bytes, largest block 212,992 bytes, queue high-water 10, six-client high-water 6). Full repeated-match and station/provisioning acceptance evidence is not yet recorded; Milestone 010 remains `IN_PROGRESS`. +- On 2026-09-08, the project owner ran + `./scripts/ws_protocol_client.py 192.168.1.50 --verify-m010 --stress-moves 80 + --repeat-matches 2` against the target device. It passed six-client load with + four complete observers, six-client responsiveness (86.9 ms), slow/malformed + stress (455.4 ms maximum player latency and 387 dropped latest observer + updates), and two repeated match cycles (16-byte heap range). Final + diagnostics recorded active connections 2, connection high-water 6, queue + high-water 8, queue depth 0, 202,292-byte minimum internal free heap, + 184,320-byte minimum largest block, 20 malformed messages, 21 rate-limited + messages, 80 accepted commands, two completed/reset matches, and no PSRAM + requirement. The subsequent `/health` response was `serving` for version + `0.10.0`. Acceptance criteria 1--4 and 6 now have concrete evidence; + physical station/fallback provisioning and browser-recovery evidence for + criterion 5 remains pending, so Milestone 010 is `IN_PROGRESS`. +- On 2026-09-08, `./scripts/run_host_tests.sh` passed every health, Wi-Fi + configuration, NVS, provisioning, lobby/protocol, maze, game, disconnect + recovery, browser, and web-asset suite. Its deterministic maze sweep covered + 1,024 seeds and its repeated-match reset test completed 128 cycles. The + owner also ran `pio run -e esp32-c6-devkitm-1`, which passed with 124,276 of + 327,680 RAM bytes and 1,028,956 of 2,097,152 application bytes, and + `pio run -e esp32-c6-devkitm-1 --target buildfs`, which passed with the + 2,031,616-byte LittleFS image exactly fitting its 2,031,616-byte partition. +- On 2026-09-08, the owner confirmed physical station recovery after network + disruption. `/api/wifi/status` returned + `{"state":"station_connected","accessPointSsid":"maze32-F7B9",` + `"ip":"192.168.1.50"}`, and bounded station retries behaved as expected. + The owner also confirmed the fallback provisioning page worked as expected + and that both active player sessions restored their original slots through + saved tokens. Together with the successful target stress run, host + regressions, production builds, and fixed-limit evidence above, this + satisfies every Milestone 010 acceptance criterion. Milestone 010 is + `COMPLETE`; Milestone 011 remains `NOT_STARTED`. ## Milestone 011 — Gameplay tuning and MVP acceptance -**Status:** `NOT_STARTED` +**Status:** `IN_PROGRESS` ### Objective @@ -988,6 +1020,21 @@ criterion on the release candidate. ### Evidence -Completion evidence is not yet available because this milestone has not -started. Required evidence includes playtest data, the mapped acceptance report, -final build hashes and sizes, and project-owner approval of any deviations. +Implementation is in progress. `docs/BALANCE_REPORT.md` locks the current MVP +gameplay configuration and records the deterministic maze metrics. The +playtest procedure and result table are in `docs/PLAYTEST_REPORT.md`, and the +criterion-by-criterion evidence register is in `docs/MVP_ACCEPTANCE.md`. +Representative completed-match timings and the final release build record are +still required before this milestone can be marked `COMPLETE`. +- On 2026-09-08, `bash scripts/run_host_tests.sh` passed its health, Wi-Fi, + NVS, provisioning, lobby/protocol, maze, game, disconnect-recovery, browser, + and web-asset suites. The locked 1,024-seed sweep reported cycles `133..133`, + dead ends `704..854`, start-to-key distance `416..1442`, and key-to-exit + distance `346..1244`; every generated map satisfied the key-distance balance + invariant. `pio run -e esp32-c6-devkitm-1` passed using 124,276 of 327,680 + RAM bytes and 1,028,956 of 2,097,152 application bytes. The matching + `buildfs` command passed using 2,031,616 of 2,031,616 LittleFS bytes. + `docs/MVP_ACCEPTANCE.md` records version `0.10.0`, build hashes, and the + 19,253-byte reproducible web payload. Human playtest evidence for the + approximately five-minute target remains pending, so Milestone 011 is + `IN_PROGRESS` and Milestone 012 has not started. diff --git a/docs/BALANCE_REPORT.md b/docs/BALANCE_REPORT.md new file mode 100644 index 0000000..00fa2e7 --- /dev/null +++ b/docs/BALANCE_REPORT.md @@ -0,0 +1,71 @@ +# MVP gameplay balance + +This document locks the gameplay configuration evaluated for Milestone 011. +It is not a claim that the required human playtests have completed; their +results belong in `docs/PLAYTEST_REPORT.md`. + +## Locked configuration + +| Parameter | Locked value | Purpose | +| --- | ---: | --- | +| Maze dimensions | 128 x 64 cells | MVP map size | +| Initial vision radius | 3 cells | Current-view-only exploration | +| Cross-half connection pairs | 3 | Multiple routes between conceptual halves | +| Extra cycle pairs | 64 | Alternative routes without removing dead ends | +| Minimum start-to-exit separation | 64 cells | Keeps exits distant from starts | +| Landmark pairs | 8 | Spatial-memory cues in symmetric positions | +| Vision-artifact pairs | 4 | Eight one-use artifacts; exceeds the MVP minimum of two | +| Compass pairs | 1 | One compass for each player's own exit | +| Movement cooldown | 150 ms | Server-enforced minimum accepted-move interval | +| Enhanced-vision duration | 10 successful moves | MVP artifact duration | +| Draw window | 200 ms | Authoritative simultaneous-exit boundary | +| Match timer | None | Matches end only by defined result conditions | + +The values come from `maze32_maze_default_config()` and +`maze32_game_default_config()`. They are server-owned defaults; browser +clients cannot alter them. + +## Deterministic generation evidence + +`test/host/test_maze_generation.c` generates and validates seeds 0 through +1,023 with this configuration. For every generated map it proves reachability, +central symmetry, positive cycles and dead ends, at least four cross-half +connections, paired player-relative route distances, and this balance +invariant: + +``` +start_to_key_distance >= key_to_exit_distance +``` + +The test measures shortest traversable routes, not straight-line distance. It +therefore establishes that finding a key is never made easier by a shorter +required route than the later exit search. It does not substitute for human +search behaviour in a maze with fog of war, landmarks, compasses, and +artifacts. + +The most recent recorded sweep (2026-09-08) reported: + +| Metric | Observed range across 1,024 seeds | +| --- | ---: | +| Cycles | 133..133 | +| Dead ends | 704..854 | +| Start to key | 416..1,442 cells | +| Key to exit | 346..1,244 cells | +| Start to exit | 102..992 cells | +| Generation attempts | 1 | + +At the 150 ms cooldown, an uninterrupted shortest 416-cell key route takes at +least 62.4 seconds of accepted-move time. Actual match duration also includes +route discovery, current-view-only navigation, the exit search, detours, +interactions, and player decisions. The approximately five-minute target must +be confirmed by the representative human-playtest procedure; no hard timer is +introduced to force that outcome. + +## Tuning decision + +No parameter change is justified before representative timing evidence exists. +Changing maze density or cooldown solely from shortest-path metrics would risk +making the target duration less representative of real fog-of-war play. If the +playtest median materially misses the five-minute target, change only the +smallest relevant locked value, rerun the 1,024-seed suite, record the new +range here, and repeat the affected playtests. diff --git a/docs/MVP_ACCEPTANCE.md b/docs/MVP_ACCEPTANCE.md new file mode 100644 index 0000000..9cde5fb --- /dev/null +++ b/docs/MVP_ACCEPTANCE.md @@ -0,0 +1,39 @@ +# MVP acceptance evidence register + +This register maps the MVP acceptance criteria to existing evidence and the +remaining Milestone 011 evidence. It prevents release approval from relying on +unrecorded assumptions. + +| MVP criterion | Evidence | Status | +| --- | --- | --- | +| 1. Firmware and LittleFS fit | Milestone 010 target builds: application 1,028,956 / 2,097,152 bytes; LittleFS 2,031,616 / 2,031,616 bytes. | Passing; repeat for release candidate. | +| 2. Persistent station and fallback provisioning | Milestone 010 owner confirmation: persisted station connection and bounded retry; fallback provisioning page worked. | Passing. | +| 3. Two-player lobby, countdown, and refresh | Host lobby/protocol and browser tests; Milestone 010 owner confirmation that both player tokens restored their slots. | Passing. | +| 4. Four read-only observers | Milestone 010 six-client target run assembled four complete observer maps; Milestone 009 authorization tests. | Passing. | +| 5. Fair repeated 128 x 64 maps | 1,024-seed host sweep and maze validation; locked metrics in `docs/BALANCE_REPORT.md`. | Passing. | +| 6. Projection security | Host game visibility and payload-security tests; player and observer browser-contract tests. | Passing. | +| 7. Controls and cooldown | Host game-core and browser keyboard/swipe tests; 150 ms locked cooldown. | Passing. | +| 8. Key and inventory mechanics | Host game-mechanics tests covering pickup, drop, sabotage, meeting return, and exits. | Passing. | +| 9. Artifact and compass rules | Host game-mechanics tests covering ten successful moves and role-specific compass projections. | Passing. | +| 10. Victory and draw window | Host game-mechanics test covering outward exit and 200 ms draw boundary. | Passing. | +| 11. Disconnect recovery | Host disconnect-recovery tests and Milestone 009 physical acceptance evidence. | Passing. | +| 12. Approximately five-minute normal match | `docs/PLAYTEST_REPORT.md` must contain at least five completed representative matches. | Pending. | +| 13. Russian offline UI and browser coverage | Milestone 008 owner checks in Chrome 152, Firefox 155, Safari 26.6, and Edge 152.0.4191.53; asset verification enforces the offline and 1.5 MiB budget. | Passing; repeat asset check for release candidate. | + +## Release-candidate record + +Before marking Milestone 011 complete, add the exact date, application version, +firmware and LittleFS build commands, sizes, and the web-asset reproducibility +digest from the final candidate below. This record must match the tested image. + +| Field | Release-candidate value | +| --- | --- | +| Date | 2026-09-08 (pre-playtest candidate) | +| Application version | 0.10.0 | +| Firmware build command and size | `pio run -e esp32-c6-devkitm-1`; 1,028,956 / 2,097,152 application bytes; `firmware.bin` 1,029,584 bytes, SHA-256 `e654643cb9f16ec03c8d54d981da32ab8e64616f99d23d4a6bb14c8ac7f69c17` | +| LittleFS build command and size | `pio run -e esp32-c6-devkitm-1 --target buildfs`; 2,031,616 / 2,031,616 bytes; SHA-256 `526e2d03ca4473adb0fe075f4b075aaaeec85ef982240f6578e8cbbb4bec7f35` | +| Web asset digest and compressed size | `8f3207a208c26aa9f0faff0b0fd8db8e8f8e44537bd6db2c0f914ca5f352920a`; 19,253 / 1,572,864 bytes | +| Approved deviations | None recorded | + +No deviation from `MVP.md` has been approved. A pending item is not passing +evidence and must not be treated as release acceptance. diff --git a/docs/PLAYTEST_REPORT.md b/docs/PLAYTEST_REPORT.md new file mode 100644 index 0000000..f50959c --- /dev/null +++ b/docs/PLAYTEST_REPORT.md @@ -0,0 +1,40 @@ +# Milestone 011 playtest report + +## Protocol + +Run representative completed two-player matches on the target ESP32-C6 with +the locked configuration in `docs/BALANCE_REPORT.md`. Use two active players +and, where practical, one observer. Do not impose a time limit or coach a +route. Start timing when the authoritative countdown completes and stop at the +authoritative result. A draw, reconnect timeout, abandoned match, or technical +failure is recorded separately and does not count as a completed match. + +For each completed match, record the maze seed or map hash, both players' +experience level, winner or draw, elapsed time, whether either player used a +vision artifact or compass, and any gameplay defect. Do not record session +tokens, Wi-Fi passwords, or other credentials. + +Use at least five completed matches involving more than one pair of players. +The target is that ordinary completed matches cluster around five minutes; +there is deliberately no hard timer. If a result materially misses that target +or a participant reports a balance issue, describe it and repeat the affected +tests after any parameter change. + +## Results + +No representative completed human matches have been recorded yet. + +| Run | Date | Seed or map hash | Player experience | Result | Elapsed | Artifact / compass use | Defects or balance notes | +| --- | --- | --- | --- | --- | --- | --- | --- | +| 1 | Pending | Pending | Pending | Pending | Pending | Pending | Pending | +| 2 | Pending | Pending | Pending | Pending | Pending | Pending | Pending | +| 3 | Pending | Pending | Pending | Pending | Pending | Pending | Pending | +| 4 | Pending | Pending | Pending | Pending | Pending | Pending | Pending | +| 5 | Pending | Pending | Pending | Pending | Pending | Pending | Pending | + +## Assessment + +Pending the five completed matches above. This document must state the +observed range and median, whether the five-minute target was met without a +timer, and whether any tuning change or approved deviation is required before +Milestone 011 can be complete. diff --git a/scripts/ws_protocol_client.py b/scripts/ws_protocol_client.py old mode 100644 new mode 100755