feat(web): render canonical living hedge maze walls

This commit is contained in:
2026-09-11 23:46:02 +03:00
parent 9ce44cdef7
commit 07eaed9c93
10 changed files with 480 additions and 32 deletions
+260
View File
@@ -2591,3 +2591,263 @@ The following planning-time request defines this milestone:
breach variants, and the density and palette defined in `docs/UI_STYLE.md`.
This satisfies the required owner review. Runtime integration remains a
separately planned milestone.
## Milestone 024 — Runtime living hedge rendering
**Status:** `IN_PROGRESS`
### Objective
Replace the maze's simple green wall strokes and provisional perseverance
damage styling with the project-owner-approved Milestone 023 living-hedge SVG
family, so intact walls, impacts, and permanent breakthroughs form one varied,
legible top-down environment on player and observer screens without changing
authoritative gameplay or exposing hidden state.
### Scope
- Do not start this milestone until every preceding milestone is `COMPLETE`.
Use only the intact families, impact sequence, breakthrough frame, breached
variants, density, and palette approved in Milestone 023. Any substantive art
redesign requires returning to a separately planned sample-review milestone.
- Reconcile `docs/UI_STYLE.md`, `docs/PLAYER_UI.md`, and `ARCHITECTURE.md` with
the runtime hedge-rendering contract before changing browser assets.
- Derive a compact runtime SVG sprite from
`docs/hedge-sample-library.svg`; keep the review source untouched and do not
make runtime pages depend on files under `docs/`. Preserve stable semantic
symbol identifiers where practical and remove comparison-sheet-only content.
- Package the runtime sprite locally with the compressed web application. Do
not add remote images, fonts, libraries, network requests, embedded raster
data, or runtime SVG scripts.
- Replace the four solid CSS cell borders with a dedicated decorative edge
layer that draws each server-provided closed wall once. Canonicalize shared
edges so two adjacent visible cells do not produce doubled foliage, darker
overlaps, seams, or inconsistent variants.
- Draw walls at projection boundaries only from the current server-provided
cell and passage bits. Do not assume what lies beyond an unseen edge, fill
unknown space, retain an explored map, or generate decorative geometry for
cells absent from the current projection.
- Select among the six approved intact variants with a documented deterministic
function of the currently visible canonical wall edge and orientation. The
same edge must keep its variant across rerenders and appear consistently to
both players and observers when their approved projections include it, with
no new protocol or authoritative game-state field.
- Rotate or mirror approved symbols for north, east, south, and west while
preserving their shared-edge center, non-directional lighting, foliage
thickness, and joins. Compose approved corner, crossing, and end treatments
only from wall edges explicitly present in the received projection.
- Preserve exact maze geometry and hit testing. Decorative foliage may extend
visually into neighboring cells by a bounded amount, but it cannot change
traversability, pointer targets, player focal-point calculation, map bounds,
projection translation, or page overflow.
- Keep hedge artwork behind players, keys, doors, artifacts, landmarks, and
interaction feedback. Leaves and branches must remain recognizable at 34,
40, and 46 CSS-pixel cells without obscuring the passage center or reducing
object and player contrast.
- Connect Milestone 022 server-approved impact stages one through four to the
matching approved static SVG frames on the exact visible wall that received
the impact. Preserve the existing bounded timer, event correlation,
deduplication, and cleanup behavior; the browser never increments damage or
predicts a breakthrough locally.
- Present the approved breakthrough frame only when justified by the matching
authoritative response and transition to one of the approved permanent
breached variants when the received `opened` passage state changes. Derive
this transition only from current and immediately preceding visible
server-approved state, held in bounded memory and discarded on projection
replacement or reset.
- Render one canonical permanent breach decoration for a shared opened edge so
the gap aligns from both adjacent cells and from both traversal directions.
Breached foliage must remain visible while the opened edge is in the current
projection and disappear when that edge is no longer projected.
- Preserve reduced-motion behavior by using the approved static impact frames
and an immediate permanent breach state, with no shaking, swaying, moving
leaves, or travel animation. Normal motion may use restrained transforms of
the approved shapes but must not allocate unbounded particles or DOM nodes.
- Use bounded reusable DOM or CSS structures. A rerender must have a documented
maximum number of hedge elements derived from the maximum visible projection,
remove obsolete edges, and never accumulate duplicate SVG instances,
animation timers, styles, or event listeners.
- Apply the same hedge family to the observer's full-map renderer without
changing its read-only behavior, pan or zoom controls, minimum viewport, or
authoritative snapshot contents. At overview zoom levels, simplify details
gracefully while retaining continuous wall and breached-gap silhouettes.
- Preserve Russian player-facing copy, Milestone 020 visual feedback,
Milestone 021 focal-point positioning, Milestone 022 game rules, offline
operation, accessibility, and existing firmware and filesystem budgets.
### Deliverables
- Updated runtime hedge-rendering, layering, variation, projection-safety, and
reduced-motion contracts in canonical and supporting documentation.
- Optimized local runtime SVG sprite derived reproducibly from the approved
Milestone 023 source, with deterministic size and dependency validation.
- A deduplicated decorative edge renderer for player and observer maps using
the six intact hedge variants and approved joins and end treatments.
- Runtime wiring for the four approved impact stages, breakthrough frame, and
three deterministic permanent breached variants.
- Deterministic browser tests, asset checks, host regression results, size
evidence, and representative mobile, desktop, observer, and physical-device
visual verification.
### Acceptance criteria
1. Every closed edge in the received player or observer projection is rendered
with an approved living-hedge SVG variant rather than a solid CSS green
border. Visible leaves, twigs, irregular foliage, depth tones, and outline
remain recognizable at supported gameplay scales. Horizontal and vertical
hedge center lines coincide with their authoritative cell edges, never pass
through cell centers, and leave open floor at least as clear as the former
solid green wall presentation.
2. Every visible shared wall has exactly one canonical decorative edge. Adjacent
cells, full rerenders, projection updates, and observer zoom changes produce
no doubled foliage, dark overlap, seam, flicker, or mismatched variant.
3. The documented deterministic selection maps canonical visible wall edges to
all six approved intact variants with representative distribution. The same
edge and orientation produce the same variant across rerenders and roles,
while no random state, hidden topology, or new protocol field is required.
4. North, east, south, and west walls plus continuous runs, corners, crossings,
exposed ends, and projection boundaries align to within one CSS pixel at 34,
40, and 46 CSS-pixel cells and at representative device pixel ratios.
5. The edge layer is derived exclusively from cells and passage/opened bits in
the current server-approved projection. Tests confirm no unknown cell,
missing edge, hidden route, remote breach, or explored-map decoration is
inferred, retained, serialized, or rendered.
6. Hedge artwork does not alter authoritative movement, wall collision,
visibility, object pickup, exits, results, input hit targets, observer
read-only behavior, or player focal positioning. No gameplay or protocol
contract changes are introduced.
7. Players, keys, exits, artifacts, landmarks, controls, and feedback remain
above the hedge layer and clearly legible in normal color, grayscale, and
representative color-vision checks. Decorative overhang creates no page or
map-shell overflow and captures no pointer input.
8. Each server-approved perseverance impact selects the matching approved stage
on the exact currently visible wall. Stages do not advance from local input,
duplicate or reordered messages, impacts on another edge, or events outside
the current projection.
9. A matching fifth-impact transition briefly uses the approved breakthrough
frame in normal-motion mode and settles on one approved permanent breached
variant from the next authoritative opened-edge projection. The visual gap
aligns bidirectionally and cannot be mistaken for a closed wall.
10. All three approved breached variants appear through a stable deterministic
mapping. They remain visible only while their authoritative opened edge is
projected, survive ordinary rerenders without changing variant, and leave
no stale decoration after reset, match end, disconnect, or projection loss.
11. Reduced-motion mode uses static impact stages and changes immediately to the
permanent breach without maze shake, foliage sway, moving leaf fragments,
or breakthrough travel animation. Meaning does not depend on motion, sound,
vibration, text, or green hue alone.
12. The renderer has a tested fixed upper bound for hedge elements, transient
effects, timers, and memory based on the maximum supported projection.
Repeated snapshots and impacts do not accumulate nodes, listeners, styles,
or timers, and obsolete edge elements are removed deterministically.
13. Observer rendering uses the same approved family and canonical edge logic,
keeps full-map pan and zoom responsive, and preserves continuous intact and
breached silhouettes at overview and inspection scales.
14. Automated browser tests cover variant selection, shared-edge deduplication,
every orientation and join, projection boundaries, hidden-state isolation,
layering, impact and breach transitions, cleanup, reduced motion, observer
zoom, supported cell sizes, and zero viewport overflow.
15. The runtime SVG is local, valid, script-free, raster-free, deterministically
generated, and included in web-asset reproducibility checks. All host tests
pass, compressed web assets remain within the 1.5 MiB budget and LittleFS
partition, and firmware remains within the factory partition.
16. The project owner confirms on representative mobile and observer screens
that the maze resembles a varied living hedge from above, repetition is not
distracting, leaves and branches are visible, objects remain easy to find,
impacts visibly damage the correct bush, and permanent openings are clear,
or explicitly approves a documented evidence deviation.
### Evidence
The following planning-time state defines this milestone:
- On 2026-09-10, the project owner requested a separate future milestone to
integrate the living-hedge samples generated and approved by Milestone 023.
The approved review source contains six intact variants, four impact stages,
one breakthrough frame, three permanent breach variants, and topology
examples, but remains outside runtime assets at planning time.
- Runtime SVG derivation, browser integration, tests, resource measurements,
physical-device verification, and owner acceptance are deferred to this
milestone. No implementation was performed while creating the plan.
- 2026-09-11 implementation evidence: the local `web/hedges.svg` runtime
sprite contains the approved intact, impact, breakthrough, and breach
symbols. Player and observer maps derive a bounded canonical hedge-edge list
only from their current projections; a full 32 by 32 projection is bounded
to 2,112 edge elements. The renderer uses deterministic edge hashes and one
restartable breakthrough timer, with immediate reduced-motion settlement.
- 2026-09-11 verification: `bash scripts/run_host_tests.sh` passed. `node
--test test/web/test_player_app.js test/web/test_hedge_svg.js` passed all 26
browser tests. `python3 scripts/verify_web_assets.py` passed with a 29,912 /
1,572,864 byte compressed payload.
- 2026-09-11 skipped check: `pio run` could not acquire
`/home/sasa/.platformio/platforms.lock` because the global PlatformIO home
is read-only. Firmware size verification, physical-device visual testing,
and project-owner mobile and observer acceptance remain required. Milestone
024 therefore remains `IN_PROGRESS`.
- 2026-09-11 user-run verification: `./scripts/run_host_tests.sh` passed all
host and bundled player browser checks; `node --test
test/web/test_player_app.js test/web/test_hedge_svg.js` passed all 26 tests;
and `python3 ./scripts/verify_web_assets.py` confirmed deterministic assets
at 29,912 / 1,572,864 bytes.
- 2026-09-11 physical-device diagnostic: host `192.168.1.103/24` reached the
connected ESP at `192.168.1.50` with two ICMP replies and no packet loss, but
`curl --noproxy '*' http://192.168.1.50/health` was refused on TCP port 80.
The device is reachable but its HTTP server is not listening; no flash or
reset was performed. Physical visual acceptance remains pending.
- 2026-09-11 physical-device repair and verification: boot logs identified
`ESP_ERR_HTTPD_HANDLERS_FULL` after adding the hedge sprite route. The
bounded URI handler capacity was raised from 13 to 14. A writable temporary
PlatformIO home built and uploaded the application and LittleFS image through
`/dev/ttyACM0` to the ESP32-C6FH4; every upload hash was verified. Firmware
uses 1,029,600 / 2,097,152 factory bytes (49.1% flash) and 59,940 / 327,680
bytes RAM (18.3%); LittleFS uses 2,031,616 / 2,031,616 bytes. After reboot,
`GET /health` returned `200` with `{"status":"serving","healthy":true,`
`"version":"0.14.0","errorCode":0}`, while GET requests for `/` and
`/hedges.svg` both returned `200` (3,378 and 1,106 bytes respectively).
Project-owner visual acceptance of the mobile and observer hedge rendering
remains required before the milestone can become `COMPLETE`.
- 2026-09-11 project-owner mobile review rejected the first runtime hedge
presentation because foliage obscured the wall boundaries and made open
routes substantially harder to understand than the former green strokes.
The corrective contract limits foliage to 20% of a cell, adds a continuous
high-contrast spine only to closed edges, and raises the contrast of the
inset cell floor. Repeat physical-device visual acceptance remains required.
- 2026-09-11 corrective verification: a local rendered maze preview confirmed
that the continuous spine restores exact closed-edge continuity while opened
edges remain uninterrupted passages. `node --test
test/web/test_player_app.js test/web/test_hedge_svg.js` passed all 26 tests,
`bash scripts/run_host_tests.sh` passed, and web-asset reproducibility passed
at 30,012 / 1,572,864 compressed bytes. A clean PlatformIO build passed with
firmware at 1,029,600 / 2,097,152 bytes and RAM at 59,940 / 327,680 bytes;
`pio run -t buildfs` also passed for the 2,031,616-byte LittleFS image.
- 2026-09-11 deployment was not attempted because no `/dev/ttyACM*` or
`/dev/ttyUSB*` device was present and the ESP HTTP endpoint at
`192.168.1.50:80` was unreachable from the host. The already-open browser tab
still shows its previously loaded assets. Upload and repeat project-owner
mobile visual acceptance remain required, so Milestone 024 stays
`IN_PROGRESS`.
- 2026-09-11 repeat project-owner review rejected the first readability
correction: its added bright spine and emphasized floor insets produced a
confusing rectangular grid, while the player still appeared to stand on a
hedge. Browser geometry inspection found two root causes: rotating a
horizontal SVG wrapper into a vertical edge left its center displaced by
half a cell on both axes, and SVG instances had no `160 x 40` view box, so
source-coordinate foliage overflowed far beyond its owning cell edge. The
next correction removes the spine and floor emphasis, restores the quiet cell
surface, constrains every SVG to one edge, and aligns vertical wrapper centers
with authoritative boundaries. Repeat physical-device visual acceptance
remains required.
- 2026-09-11 second corrective verification: a rendered 7 by 7 maze at the
minimum gameplay cell scale showed each `160 x 40` hedge constrained to one
edge, vertical and horizontal centers aligned, the player wholly inside its
cell, and continuous open-floor routes without the rejected rectangular
overlay. `bash scripts/run_host_tests.sh` passed, including all bundled
browser checks, and web-asset reproducibility passed at 29,979 / 1,572,864
compressed bytes. A clean PlatformIO build passed with firmware at
1,029,600 / 2,097,152 bytes and RAM at 59,940 / 327,680 bytes; the configured
2,031,616-byte LittleFS image also built successfully.
- 2026-09-11 the corrected image could not be uploaded from this environment:
no `/dev/ttyACM*` or `/dev/ttyUSB*` device was present and the ESP HTTP
endpoint remained unreachable from the host. The physical page still needs
the new filesystem image and repeat project-owner visual acceptance, so
Milestone 024 remains `IN_PROGRESS`.