# 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.