Files
vela-snake/README.md
T

104 lines
5.7 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# SNAKE — Xiaomi Watch S4
Textured Snake on a **368px circular arena**, centered on the round 466px
screen. **32px tiles** (60% larger than 0.7) occupy 89 legal cells of an 11×11
bounding grid; every tile corner stays inside the actual circle. The square
board frame is gone. Directional sprite artwork and user icon are preserved. Package identity: `com.ilias.snake`.
**Version 0.8 (versionCode 8): locally tested and release-built; the new features
still need an on-watch check.** Earlier versions rendered and played on the
user's Watch S4 41mm. Node tests and numeric layout checks are not device tests.
## Play
- **Swipe** to steer. A two-turn queue accepts rapid corners, consumes one turn
per tick, and rejects duplicate directions and reversals against the last
queued direction. Excess inputs are ignored, not allowed to replace a turn.
- **Tap the board, snake or apple** to pause. Tap **RESUME** (or an exposed part
of the board) to resume. Pausing clears queued turns.
- In the pause or game-over panel, select **CLASSIC** (the circular boundary ends the run) or
**WRAP** (cross the circular boundary to appear at the opposite legal end
of the **same row or column**). Changing mode starts
a fresh, paused game; tap RESUME to begin. Selecting the current mode does not
reset the run. The current mode is shown below the board.
- Both modes end on self-collision. Moving into the vacating tail is legal.
- **PLAY AGAIN** is a large 216×56px retry target. Retry keeps the selected mode,
resets score/speed/queued turns, and starts playing. Filling the board displays
**YOU WIN** at 89 occupied cells (86 points) and hides the apple safely.
- Leaving the page pauses it and stops the timer. Returning requires an explicit
resume; game-over never resumes automatically. The system back action remains
untouched. No crown, rotary, side-button or back interception APIs are used.
## Score, speed and persistence
Each apple is one point. The always-visible header shows score and best. One
best score is shared across Classic and Wrap, saved through documented
[`@system.storage`](https://iot.mi.com/vela/quickapp/en/features/data/storage.html)
under `snake.best`. Mode is session-only; a newly created page defaults to Classic.
The movement interval starts at **300ms**, decreases by **10ms per apple**, and
never goes below **120ms**. Only one movement timer runs; none runs while hidden,
paused, finished or destroyed. Old timer callbacks are invalidated.
Storage reads merge with the in-memory maximum; writes wait for the initial
read and are serialized/coalesced so slow callbacks cannot overwrite a newer
record. The coordinator survives page recreation within the module lifetime.
Old 0.7 records through 253 remain valid and are never reduced to the new
86-point maximum. Invalid saved values are ignored. Errors/exceptions do not interrupt gameplay:
failed reads/writes retry on later apples or page-show activity, without a retry
loop. A failed/uncompleted write or immediate app termination may lose the
unsaved record. Storage persistence still needs verification on the watch.
## Lightweight rendering
Directional PNG tiles use only `left`/`top` positioning, no transforms. Existing
20px sprite art is nearest-neighbor enlarged to native 32px assets (crisp pixel
art, not new high-resolution detail). The board is a newly generated circular
PNG with transparent corners and a subtle legal-cell checker pattern. Wrapped
texture connections handle each varying row/column length. All rows/columns
have at least three cells, avoiding ambiguous one-/two-cell seams.
Food scans only 89 legal cells, including a nearly full board. HUD/footer
rectangles never overlap legal play tiles; text/overlay fit the watch chord.
`tests/preview-0.8-static.png` is a static composition of actual geometry/art,
with a legal-cell overlay—not a runtime screenshot.
## Build and test
```bash
npm ci
npm test
npm run release
```
`npm test` runs the original core, piece and page tests, 14 upgrade
regressions, the numeric layout suite, and deterministic randomized property tests. Upgrade coverage includes rapid
swipes, lifecycle/timer races, storage failures and async ordering, mode changes,
all four Wrap edges, seam textures, full-board victory and bounded food spawning.
New behaviors were exercised through failing-then-passing test cycles.
Release output: `dist/com.ilias.snake.release.0.8.rpk`. The locked
`aiot-toolkit` 2.0.5 uses the existing `sign/private.pem` and `sign/certificate.pem`;
do not regenerate or commit those keys. Release uses plain JS (not JSC/protobuf),
matching the previously working toolchain. The dependency lock is unchanged;
`npm ci` currently reports 14 development-toolchain audit findings (3 low,
11 high). No forced toolkit upgrade was applied.
## Files
- `src/pages/index/index.ux`: round-screen UI, swipe queue, game/lifecycle state.
- `src/common/snake.js`: movement, collision, Wrap piece classification, food.
- `src/common/best.js`: asynchronous storage coordinator.
- `src/common/tex/`: native 32px sprite artwork and circular board.
- `tests/{snake,pieces,page,upgrade,layout,properties,round,art,round-history}.cjs`: Node regression suites, including history-based circular seam orientation checks.
Install the signed RPK through AstroBox. Source/releases live at
https://gitea.oimcloud.myaddr.tools/codex-bot/vela-snake — publication is a
separate step after review; a local build is not evidence of a published release.
## Earlier versions
- 0.2/0.3: board played on watch; designWidth 480→466 fixed undersizing.
- 0.6: directional textured tiles and preserved user-supplied icon.
- 0.7: queued swipes, live/persisted records, capped acceleration, pause/resume,
lifecycle safety, retry/win panels and selectable Classic/Wrap.