73 lines
3.5 KiB
Markdown
73 lines
3.5 KiB
Markdown
# Player browser application
|
|
|
|
Milestone 008 provides the responsive player-facing browser application. The
|
|
browser remains a renderer and input device: it sends movement and key-drop
|
|
intentions, and it never calculates a legal move, inventory change, timer,
|
|
visibility region, compass result, or match result.
|
|
|
|
## Local assets
|
|
|
|
The application consists of `index.html`, `player.css`, `player.js`, and the
|
|
locally authored `icons.svg` sprite. The deterministic asset build compresses
|
|
each file with gzip for LittleFS. There are no remote fonts, frameworks,
|
|
analytics, icon services, or runtime network dependencies beyond the local ESP.
|
|
|
|
## Input contract
|
|
|
|
Arrow keys and WASD map to `north`, `east`, `south`, and `west` move intentions.
|
|
Touch swipes use the same four strings after a 28 CSS-pixel threshold. Phone
|
|
layouts hide the direction pad and retain swipes; tablet and desktop layouts
|
|
show the direction pad and also accept swipes. The persistent `OK` control
|
|
sends `drop_key` and exposes the accessible label `Сбросить ключ`.
|
|
|
|
The centered player avatar is also the touch movement handle. Its transparent
|
|
target is 96 by 96 CSS pixels while the visible avatar can deflect at most 28
|
|
CSS pixels. A 12-pixel dead zone and diagonal hysteresis resolve only cardinal
|
|
intentions. Drag displacement selects a monotonically bounded local cadence
|
|
from 360 ms to 170 ms, which remains slower than the authoritative 150 ms
|
|
cooldown. The browser keeps one sent move in flight and coalesces all later
|
|
drag changes into one latest intention; release discards that unsent intention.
|
|
The deflection is local input feedback only. The maze redraws only after a
|
|
server-authoritative projection and the browser never predicts a cell change.
|
|
|
|
Commands use the version-one protocol envelope and contain intention data only:
|
|
|
|
```json
|
|
{"v":1,"type":"move","seq":7,"requestId":"move-7","payload":{"direction":"west"}}
|
|
```
|
|
|
|
```json
|
|
{"v":1,"type":"drop_key","seq":8,"requestId":"drop_key-8","payload":{}}
|
|
```
|
|
|
|
## Projection handling
|
|
|
|
View chunks are grouped by authoritative view sequence and rendered only after
|
|
all chunks arrive. Each completed view replaces the previous maze DOM in full.
|
|
The client does not merge a new view with previously visible cells, infer
|
|
missing passages, or retain an explored map. Maze dimensions, cells, objects,
|
|
player position, opponent visibility, inventory, vision duration, compass hint,
|
|
phase, and result all come from the server projection.
|
|
|
|
The session token is the only game-related value saved in browser storage. On
|
|
reload, the client sends that token in a `restore` intention and waits for a
|
|
fresh role-appropriate server projection. Position, inventory, effects, hints,
|
|
maze cells, and results are never restored from browser storage.
|
|
|
|
## Presentation states
|
|
|
|
Name selection, lobby, countdown, active play, pause, and match result use the
|
|
shared dark retro-arcade visual system. The fixed player status identifies the
|
|
player and labels inventory, remaining boosted-vision moves, compass direction,
|
|
and match phase. Modal overlays distinguish countdown, pause, and results.
|
|
Rejected movement produces a local wall-bump animation without revealing any
|
|
additional maze state. All player-facing copy and browser-generated errors are
|
|
Russian; protocol identifiers remain English.
|
|
|
|
Sound and supported vibration are enabled after the first pointer or keyboard
|
|
interaction. Both are progressive enhancements: unsupported devices continue
|
|
without an error.
|
|
|
|
Observer presentation and its read-only interaction boundary are documented in
|
|
`OBSERVER_UI.md`.
|