feat(player): add mobile directional pad controls
This commit is contained in:
@@ -1561,7 +1561,7 @@ controlled measurement criteria:
|
||||
|
||||
## Milestone 017 — Avatar-centered drag steering and latency remediation
|
||||
|
||||
**Status:** `IN_PROGRESS`
|
||||
**Status:** `COMPLETE`
|
||||
|
||||
### Objective
|
||||
|
||||
@@ -1678,12 +1678,6 @@ map moves below it; displacement controls speed; approximately 100 ms is ideal,
|
||||
2,097,152 application bytes. `/home/sasa/.platformio/penv/bin/pio run -e
|
||||
esp32-c6-devkitm-1 --target buildfs` passed and reported a fixed LittleFS
|
||||
image of 2,031,616 of 2,031,616 bytes.
|
||||
- `docs/M017_LATENCY_REPORT.md` records the M016 baseline, the browser backlog
|
||||
remediation, the required isolated-LAN deployment setup, and the controlled
|
||||
before-and-after retest procedure. The physical mobile usability observation,
|
||||
isolated-network 200-sample runs, and maximum-session diagnostics are still
|
||||
required for acceptance criteria 6, 7, 9, and 10. Milestone 017 remains
|
||||
`IN_PROGRESS`; Milestone 018 has not been started.
|
||||
- On 2026-09-09, an edge-projection correction translated the received maze so
|
||||
the authoritative `self` cell remains below the centered avatar. Drag
|
||||
displacement now starts at pointer-down, preventing a touch near the
|
||||
@@ -1693,3 +1687,256 @@ map moves below it; displacement controls speed; approximately 100 ms is ideal,
|
||||
25,346 of 1,572,864 allowed compressed bytes). Firmware and filesystem
|
||||
rebuilds passed with 58,868 of 327,680 RAM bytes, 1,027,966 of 2,097,152
|
||||
application bytes, and a 2,031,616-byte LittleFS image.
|
||||
|
||||
## Milestone 018 — Mobile directional controls and viewport refinement
|
||||
|
||||
**Status:** `IN_PROGRESS`
|
||||
|
||||
### Objective
|
||||
|
||||
Add a familiar, always-visible four-direction control cluster to the mobile
|
||||
player view and refine the compact layout so a player can move without covering
|
||||
the centered avatar or the most useful part of the maze with their finger.
|
||||
|
||||
### Scope
|
||||
|
||||
- Before implementation, reconcile `MVP.md`, `ARCHITECTURE.md`, and
|
||||
`docs/UI_STYLE.md` with the project owner's decision to show directional
|
||||
buttons during normal phone play. This explicitly supersedes the current
|
||||
phone-specific rule that hides the directional-button cluster.
|
||||
- Present four separate up, down, left, and right buttons as a conventional
|
||||
cross-shaped directional pad in the lower-right control zone. Keep the
|
||||
center of the cross inactive so diagonal input cannot be implied.
|
||||
- Give every direction a large, distinct touch target, Russian accessible
|
||||
label, and visible normal, pressed, disabled, and pending states. Prevent
|
||||
browser scrolling, text selection, double-tap zoom, and stuck input during
|
||||
normal button use.
|
||||
- Send exactly one of the four existing orthogonal movement intentions from
|
||||
each button interaction. Reuse the bounded latest-intent flow and server
|
||||
cooldown; the browser must not predict movement or create a second movement
|
||||
authority path.
|
||||
- Retain avatar drag, directional swipe, and keyboard movement as optional
|
||||
equivalent inputs. Directional buttons become the obvious default touch
|
||||
control without removing the alternatives completed in earlier milestones.
|
||||
- Rebalance the compact player HUD, maze viewport, key-drop action, secondary
|
||||
controls, and transient notices so the map remains dominant and the player,
|
||||
nearby maze cells, and important feedback remain visible while a thumb rests
|
||||
on the directional pad.
|
||||
- Keep the directional pad and key-drop action in separate lower-screen zones,
|
||||
respect display safe areas and handed reach, and avoid overlap between
|
||||
movement, drop-key, mute, reduced-motion, onboarding, or connection controls.
|
||||
- Eliminate page-level scrolling and accidental overflow in supported portrait
|
||||
and landscape player layouts, including the live approximately `412 x 915`
|
||||
phone viewport as well as the canonical `412 x 916` validation viewport.
|
||||
- Preserve Russian player-facing copy, observer read-only behavior,
|
||||
hidden-state protection, local assets, reduced-motion behavior, and the
|
||||
existing firmware and LittleFS budgets.
|
||||
|
||||
### Deliverables
|
||||
|
||||
- Updated mobile-control and responsive-layout contracts in `MVP.md`,
|
||||
`ARCHITECTURE.md`, and `docs/UI_STYLE.md`.
|
||||
- Responsive four-button directional pad integrated with the existing bounded
|
||||
movement-intent path.
|
||||
- Refined compact HUD, maze, key-drop, utility-control, and notice layout for
|
||||
portrait and landscape mobile play.
|
||||
- Russian accessible names and complete visual interaction states for all four
|
||||
direction buttons.
|
||||
- Deterministic browser tests and representative mobile-browser visual and
|
||||
touch verification evidence.
|
||||
|
||||
### Acceptance criteria
|
||||
|
||||
1. At `412 x 915` and `412 x 916` CSS pixels in portrait orientation, all four
|
||||
directional buttons, the key-drop action, essential player status, and the
|
||||
maze are visible without page-level horizontal or vertical scrolling.
|
||||
2. The directional buttons form an immediately recognizable cross with a
|
||||
non-interactive center. Each visible button has a touch target of at least
|
||||
`48 x 48` CSS pixels, remains inside the display safe area, and does not
|
||||
overlap another control at any supported viewport.
|
||||
3. A thumb operating any directional button does not cover the centered player
|
||||
avatar. The current cell and enough adjacent maze context to understand the
|
||||
next orthogonal move remain visible during button use.
|
||||
4. Pressing or holding up, down, left, or right produces only the matching
|
||||
existing cardinal movement intention through the bounded latest-intent
|
||||
flow. Release, cancellation, pause, disconnect, blur, hidden-document
|
||||
events, and lost pointer capture stop or clear button-generated intent.
|
||||
5. Button input obeys the authoritative movement cooldown, never predicts a
|
||||
successful move, and remains behaviorally equivalent to avatar drag, swipe,
|
||||
and keyboard input for accepted and rejected movement.
|
||||
6. Normal, pressed, disabled, and pending states are visually distinct without
|
||||
relying on color alone. The buttons expose the Russian accessible labels
|
||||
`Двигаться вверх`, `Двигаться вниз`, `Двигаться влево`, and
|
||||
`Двигаться вправо`.
|
||||
7. Button use does not cause page scrolling, text selection, double-tap zoom,
|
||||
a context menu, diagonal commands, duplicate command streams, or movement
|
||||
that continues after release.
|
||||
8. The refined HUD and overlays keep the map as the dominant screen region;
|
||||
key-drop, mute, reduced-motion, onboarding, connection state, errors, and
|
||||
transient notices remain reachable and do not obscure one another in
|
||||
portrait or landscape orientation.
|
||||
9. Browser tests cover all four directions, tap and hold behavior, pointer and
|
||||
touch cancellation, reset paths, cooldown and latest-intent bounds,
|
||||
coexistence with drag/swipe/keyboard input, accessibility labels, safe-area
|
||||
layout, control overlap, and zero page overflow at supported viewports.
|
||||
10. 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 player projection or observer-authority contract changes.
|
||||
11. The project owner confirms on a representative mobile browser that the
|
||||
four buttons are comfortable and familiar, the central play area stays
|
||||
readable while moving, every essential control fits on screen, and normal
|
||||
play no longer requires dragging the avatar, or explicitly approves a
|
||||
documented evidence deviation.
|
||||
|
||||
### Evidence
|
||||
|
||||
Implementation and automated validation are in progress. The following
|
||||
planning-time observation motivates the milestone:
|
||||
|
||||
- On 2026-09-10, the project owner reported that dragging the centered player
|
||||
is unfamiliar and uncomfortable because the finger hides useful maze space,
|
||||
and requested visible up, down, left, and right buttons plus a better-fitting
|
||||
mobile layout. Read-only inspection of the live player page at approximately
|
||||
`412 x 915` CSS pixels found a `96 x 96` centered avatar drag target, four
|
||||
directional buttons present but hidden, and a document height of 923 CSS
|
||||
pixels, slightly exceeding the 915 CSS-pixel viewport. Implementation and
|
||||
completion verification are deferred until Milestone 017 is `COMPLETE`.
|
||||
- On 2026-09-10, `MVP.md`, `ARCHITECTURE.md`, and `docs/UI_STYLE.md` were
|
||||
reconciled to make the four-button lower-right directional pad the primary
|
||||
phone control while preserving avatar drag, swipe, and keyboard alternatives.
|
||||
The inactive centre prevents diagonal input. Each button is 62 by 62 CSS
|
||||
pixels on compact phones (and at least 52 by 52 CSS pixels in compact
|
||||
landscape), has Russian accessible text, and uses pointer capture plus a
|
||||
170 ms bounded hold repeat through the existing latest-intent flow. The
|
||||
compact application viewport is explicitly clipped to `100dvh` to prevent
|
||||
page scrolling; the lower-left key action, lower-right pad, top-right utility
|
||||
controls, and raised notices occupy separate zones.
|
||||
- On 2026-09-10, `node --test test/web/test_player_app.js` passed all 20
|
||||
browser tests. `bash scripts/run_host_tests.sh` passed all host tests and
|
||||
deterministic web-asset verification
|
||||
(`ecf9429fd873e27df67774616ec68684df19d88cce6913d53b0764b53e8e95cd`,
|
||||
25,939 of 1,572,864 allowed compressed bytes). `/home/sasa/.platformio/penv/bin/pio
|
||||
run -e esp32-c6-devkitm-1` passed with 58,868 of 327,680 RAM bytes and
|
||||
1,027,966 of 2,097,152 application bytes. The matching `--target buildfs`
|
||||
command passed and produced the fixed 2,031,616-byte LittleFS image.
|
||||
- A representative physical mobile-browser touch/layout confirmation remains
|
||||
required for acceptance criterion 11. Milestone 018 remains `IN_PROGRESS`;
|
||||
Milestone 019 has not been started.
|
||||
|
||||
## Milestone 019 — Reference-derived SVG icon system
|
||||
|
||||
**Status:** `NOT_STARTED`
|
||||
|
||||
### Objective
|
||||
|
||||
Replace the current player and gameplay pictograms with a coherent local SVG
|
||||
set derived from the project owner's supplied visual reference, and establish
|
||||
yellow and blue as the two unmistakable player identities across players,
|
||||
matching keys, and matching exits.
|
||||
|
||||
### Scope
|
||||
|
||||
- Before changing application markup, styling, or rendering, manually recreate
|
||||
the supplied raster-reference silhouettes as clean, editable SVG artwork.
|
||||
Do not embed, trace at runtime, or ship the raster reference itself.
|
||||
- Create SVG symbols for the six supplied concepts: running player, key,
|
||||
closed arched exit, vision crystal, opened arched exit with outward arrow,
|
||||
and blocked-movement spikes.
|
||||
- Treat the reference as visual direction rather than a source of product
|
||||
requirements. Map its artwork only to existing maze32 gameplay states; the
|
||||
spikes communicate a rejected move or wall collision and must not introduce
|
||||
a trap, damage, or any other new mechanic.
|
||||
- Review and approve the standalone SVG set before using it to replace icons in
|
||||
the browser application. Keep source paths understandable, view boxes
|
||||
consistent, silhouettes legible at gameplay sizes, and all colors controlled
|
||||
through project-owned CSS or explicit documented SVG tokens.
|
||||
- Reconcile `MVP.md`, `ARCHITECTURE.md`, `docs/UI_STYLE.md`, and supporting UI
|
||||
documentation before implementation. Replace the current blue/pink identity
|
||||
contract with Player 1 yellow and Player 2 blue across every player, key,
|
||||
exit, status, map, onboarding, result, and observer presentation.
|
||||
- Give each player's matching key and exit the same yellow or blue ownership
|
||||
identity as its owner. Preserve different silhouettes and state treatments
|
||||
for players, keys, closed exits, and opened exits so meaning never depends on
|
||||
color alone.
|
||||
- Replace the applicable current pictograms in the player HUD, maze, key-drop
|
||||
control, onboarding, transient feedback, results, and observer view with the
|
||||
approved SVG symbols. Retain or restyle icons not represented by the supplied
|
||||
sample only as needed to keep the complete icon family visually coherent.
|
||||
- Preserve Russian accessible labels, icon-first comprehension, reduced-motion
|
||||
behavior, server authority, hidden-state rules, offline operation, and the
|
||||
existing compressed-asset and Flash budgets.
|
||||
- Verify that yellow remains distinguishable from warning states and blue from
|
||||
pause states by pairing semantic colors with shape, outline, animation, or
|
||||
labels, as appropriate.
|
||||
|
||||
### Deliverables
|
||||
|
||||
- A project-owned, editable SVG source set for the player, key, closed exit,
|
||||
vision crystal, opened exit, and blocked-movement symbols.
|
||||
- A documented mapping from each reference-derived SVG symbol and yellow/blue
|
||||
variant to existing maze32 entities and UI states.
|
||||
- Updated color and icon contracts in `MVP.md`, `ARCHITECTURE.md`,
|
||||
`docs/UI_STYLE.md`, and affected supporting UI documentation.
|
||||
- Replacement icons in player, observer, onboarding, HUD, feedback, and result
|
||||
presentations without embedded raster images or external dependencies.
|
||||
- Deterministic SVG validation, browser tests, asset-budget checks, and
|
||||
representative mobile and desktop visual-verification evidence.
|
||||
|
||||
### Acceptance criteria
|
||||
|
||||
1. Before application icon replacement begins, the six reference-derived SVG
|
||||
sources exist as editable vector paths, pass XML validation, have consistent
|
||||
documented view boxes, contain no embedded raster data, and are approved by
|
||||
the project owner against the supplied visual reference.
|
||||
2. The running figure, key, closed arched exit, faceted vision crystal, opened
|
||||
arched exit with outward arrow, and spikes remain recognizable at every
|
||||
rendered application size without relying on accompanying text.
|
||||
3. Player 1 is yellow and Player 2 is blue in every player and observer view.
|
||||
Each player's key and exit carry the matching ownership color consistently,
|
||||
including ground, inventory, closed, opened, onboarding, and result states.
|
||||
4. Player, key, closed exit, and opened exit remain distinguishable by both
|
||||
silhouette and state treatment in monochrome inspection; color is never the
|
||||
only way to identify object type, ownership, or exit state.
|
||||
5. The spikes appear only as blocked-movement or wall-collision feedback. No
|
||||
trap object, damage rule, hidden-state field, protocol message, or server
|
||||
state is added.
|
||||
6. Yellow player identity cannot be confused with warnings, and blue player
|
||||
identity cannot be confused with pause state: each conflicting semantic role
|
||||
has an additional icon, outline, pattern, motion, or Russian label.
|
||||
7. All applicable current player, key, exit, vision-artifact, and
|
||||
blocked-movement pictograms are replaced across the maze, HUD, key-drop
|
||||
action, onboarding, transient feedback, results, and observer presentation;
|
||||
no obsolete duplicate icon remains visible in a reachable state.
|
||||
8. SVG symbols render without clipping, distortion, unexpected inherited
|
||||
color, or loss of contrast at the canonical `412 x 916` player viewport,
|
||||
compact landscape, representative tablet and desktop player viewports, and
|
||||
observer viewports of `1024 x 768` or larger.
|
||||
9. Player-facing accessible labels remain in Russian, the icon-first onboarding
|
||||
remains understandable, reduced motion preserves all state information, and
|
||||
the application loads every icon locally without an internet dependency.
|
||||
10. Automated checks validate SVG structure, required symbol identifiers,
|
||||
yellow/blue ownership mapping, all closed/open and carried/ground variants,
|
||||
absence of embedded raster content, blocked-feedback semantics, and the
|
||||
removal of obsolete reachable icons.
|
||||
11. All host and browser tests pass, the compressed web payload remains within
|
||||
the 1.5 MiB budget and LittleFS partition, and firmware remains within the
|
||||
factory partition without changing authoritative game or projection data.
|
||||
12. The project owner confirms on representative mobile and desktop browsers
|
||||
that the new icons match the supplied examples closely enough, yellow and
|
||||
blue ownership is immediately understandable, keys and doors are assigned
|
||||
to the correct player, and every icon is clear at normal gameplay size, or
|
||||
explicitly approves a documented evidence deviation.
|
||||
|
||||
### Evidence
|
||||
|
||||
Completion evidence is not yet available because SVG authoring and application
|
||||
replacement have not started. The following planning-time observation motivates
|
||||
the milestone but does not satisfy its acceptance criteria:
|
||||
|
||||
- On 2026-09-10, the project owner supplied a raster visual reference containing
|
||||
a yellow running figure, yellow key, red closed arched door, cyan faceted
|
||||
crystal, green opened arched door with an outward arrow, and red spikes. The
|
||||
owner requested that local SVG artwork be created from these examples before
|
||||
icon replacement, and selected yellow and blue as the two player colors.
|
||||
Implementation and completion verification are deferred until Milestone 018
|
||||
is `COMPLETE`.
|
||||
|
||||
Reference in New Issue
Block a user