docs(plans): add playful visual feedback milestone

This commit is contained in:
2026-09-10 22:08:02 +03:00
parent abb3ff27b7
commit 2501345740
10 changed files with 294 additions and 38 deletions
+159 -4
View File
@@ -1822,7 +1822,7 @@ planning-time observation motivates the milestone:
## Milestone 019 — Reference-derived SVG icon system
**Status:** `IN_PROGRESS`
**Status:** `COMPLETE`
### Objective
@@ -1965,6 +1965,161 @@ the project-owner visual confirmation remains outstanding:
local `player` and `spikes` symbols. It did not create or alter a player
session, so full active-match visual confirmation remains for the project
owner.
- Milestone 019 remains `IN_PROGRESS` pending the project owner's
representative mobile and desktop confirmation that the new icon shapes,
yellow/blue ownership, keys, and exits are clear at normal gameplay size.
- On 2026-09-10, the project owner confirmed after representative player
testing that the new icons are satisfactory. This closes the remaining
visual-confirmation criterion; Milestone 019 is `COMPLETE`.
## Milestone 020 — Playful visual feedback and top message rail
**Status:** `IN_PROGRESS`
### Objective
Replace distracting gameplay warning text with immediate visual feedback and
move the remaining player-facing notices into a playful top-of-screen message
rail that keeps children engaged without obscuring the maze or controls.
### Scope
- Before implementation, reconcile `MVP.md`, `ARCHITECTURE.md`,
`docs/UI_STYLE.md`, and supporting player-UI documentation with the new
feedback hierarchy and copy rules.
- When the server rejects a movement intention because of a wall or maze
boundary, shake the visible maze briefly in the attempted cardinal direction.
Do not show a toast, tooltip, spike notice, or any textual warning for the
blocked move.
- Keep blocked-movement feedback local and presentation-only. It must not move
the authoritative player position, reveal a hidden wall, infer unseen maze
state, or change the existing `blocked` protocol response.
- When movement is rejected with `rate_limited`, briefly darken and blur only
the maze image so the player understands that input is arriving too quickly.
Do not display the current server-speed warning or any replacement text.
- Bound, coalesce, and safely clear shake and blur feedback. Repeated blocked or
rate-limited responses may restart or extend one current effect only within a
documented maximum duration; they must not create animation queues, timers,
DOM nodes, or a permanently blurred maze.
- Move connection loss, reconnection, session, lobby, protocol, and other
messages that still require text to a dedicated rail at the top of the
screen, above the application top bar and the player status panel. Respect
display safe areas and do not cover essential status or controls.
- Rewrite player-facing messages as short, varied, child-friendly Russian
jokes or playful reactions. Remove visible engineering language such as
`WebSocket`, protocol packets, request limits, and internal server details;
retain technical detail only in diagnostics or the secondary connection
panel where appropriate.
- Define priority, deduplication, replacement, persistence, and dismissal rules
for the top message rail. Connection loss remains visible until recovery;
lower-priority messages are bounded and cannot flood or indefinitely delay a
more important connection state.
- Keep the rail legible but lively through icon, color, and restrained motion.
Avoid rapid flashing, excessive movement, or overlapping announcements, and
preserve Russian live-region semantics for assistive technology.
- In reduced-motion mode, replace maze shaking with a single non-animated
directional border pulse or equivalent static wall-impact cue. The
rate-limit darkening and blur may remain because they do not imply movement,
but their transitions must be effectively immediate.
- Preserve optional sound and haptic feedback, authoritative server behavior,
observer read-only behavior, hidden-state protection, offline assets, and the
existing firmware and LittleFS budgets.
### Deliverables
- Updated feedback, message-placement, reduced-motion, and humorous-copy
contracts in the canonical and supporting UI documentation.
- Direction-aware maze-shake feedback for blocked movement with no visible
blocked-move text.
- Bounded maze darkening and blur for `rate_limited` movement with no visible
rate-limit text.
- Responsive top message rail with safe-area placement, bounded prioritization,
deduplication, persistent connection state, and playful Russian copy.
- Deterministic browser tests plus representative mobile and desktop visual,
motion, reduced-motion, and accessibility verification evidence.
### Acceptance criteria
1. A `blocked` response causes one brief shake of the maze in the attempted
direction without moving the authoritative map position. No blocked-move
text, toast, tooltip, spike notice, or generic error notification becomes
visible.
2. The blocked effect uses only the direction of the matching outstanding
movement intention and the server rejection. It does not inspect, retain,
infer, or expose hidden maze geometry.
3. A `rate_limited` movement response darkens and blurs only the maze region for
a documented bounded duration. The HUD, direction pad, key action, top bar,
and message rail remain readable, and no rate-limit warning text appears.
4. Repeated `blocked` or `rate_limited` responses coalesce into at most one
active effect of each type, use a bounded number of timers and DOM nodes,
and restore the exact normal maze presentation after the documented maximum
duration, disconnect, pause, result, screen change, or application reset.
5. With reduced motion enabled, blocked movement produces a single static or
non-animated directional border cue instead of shaking. Rate-limit feedback
remains understandable without animation, sound, vibration, or text.
6. Every remaining player-facing transient or persistent system message appears
in the top message rail above the application top bar and player status
panel. No ordinary notice remains anchored near the bottom of the maze or
behind mobile controls.
7. At `412 x 915`, `412 x 916`, compact landscape, representative tablet and
desktop player viewports, and observer viewports of `1024 x 768` or larger,
the message rail respects safe areas, does not create page overflow, and
does not cover essential status, map controls, dialogs, or observer tools.
8. Visible messages are concise Russian, child-friendly, non-offensive, and
playful. Reachable normal-operation copy contains no `WebSocket`, packet,
protocol, queue, rate-limit, request-processing, or similar engineering
terminology.
9. Connection loss produces a persistent high-priority playful message until
reconnection. Recovery replaces it with a short positive message; repeated
reconnect attempts do not stack duplicates or hide the current connection
state.
10. The rail maintains a documented bounded message count and priority order,
deduplicates repeated events, exposes appropriate Russian live-region
semantics, and never rapidly flashes or animates indefinitely.
11. Browser tests cover directional wall shake, absence of blocked text,
rate-limit blur and absence of rate-limit text, effect coalescing and reset
paths, reduced motion, top placement, safe areas, message priority and
deduplication, connection persistence, playful-copy constraints, supported
viewports, and observer presentation.
12. All host tests pass, compressed web assets remain within the 1.5 MiB budget
and LittleFS partition, firmware remains within the factory partition, and
no protocol, game-authority, projection, or hidden-state contract changes.
13. The project owner confirms on a representative mobile browser that wall
collisions and excessive input are understandable without warning text,
the top messages do not obstruct play, and the humorous copy keeps the
experience lively without becoming repetitive or distracting, or explicitly
approves a documented evidence deviation.
### Evidence
The following planning-time observation motivated the milestone:
- On 2026-09-10, the project owner requested removal of the visible
`Там стена. Очень убедительная.` blocked-movement warning in favor of shaking
the maze, replacement of the server-speed warning with temporary maze
darkening and blur, and relocation of connection and other necessary messages
above the top panel. The owner also required playful, non-engineering Russian
copy intended to retain children's attention. Static inspection found the
current blocked and `rate_limited` responses feeding the shared notice path,
while `.notice` is positioned near the bottom of the viewport. Implementation
and completion verification are deferred to this milestone.
- On 2026-09-10, the feedback and rail contracts were reconciled in `MVP.md`,
`ARCHITECTURE.md`, `docs/UI_STYLE.md`, and `docs/PLAYER_UI.md`. The browser
records each outstanding move direction, uses it only after the matching
`blocked` response to restart one 340 ms directional maze effect, and uses
one restartable 520 ms maze-only `rate_limited` effect. Both timers are
cleared by control reset, disconnect, pause, result, and reset paths. The
map projection offset is held in CSS variables during the effect, preserving
the centered authoritative player position at board edges.
- `node --test test/web/test_player_app.js` passed: 22 tests, 0 failures. The
focused deterministic checks include the message rail placement and live
semantics, direction correlation, no blocked/rate-limit text, maze-only
blur, and reduced-motion behavior.
- `bash scripts/run_host_tests.sh` passed all portable host suites, the same
22 browser tests, and the deterministic web-asset check:
`web asset reproducibility: PASS (..., 27068/1572864 bytes)`.
- `/home/sasa/.platformio/penv/bin/pio run` passed for `esp32-c6-devkitm-1`:
RAM `58868/327680` bytes and factory flash `1027966/2097152` bytes.
`/home/sasa/.platformio/penv/bin/pio run -t buildfs` passed and produced the
configured `2031616/2031616` byte LittleFS image.
- Milestone 020 remains `IN_PROGRESS`: representative mobile/desktop visual,
reduced-motion, accessibility, and project-owner confirmation evidence for
acceptance criteria 7 and 13 has not been recorded. Milestone 021 has not
been started.