dreamstack/examples/game-viewer.ds
enzotar f7f7363230 feat: snake game streaming via relay
game-snake.html — Full canvas Snake game:
- 20x20 grid with gradient snake (eyes, body fade)
- Keyboard (WASD/arrows) + button controls
- Wall wrapping, self-collision detection
- Speed increases on food eat (200ms → 80ms min)
- Game over screen with restart
- Streams every frame via DreamStack relay (0x31 SignalDiff)
- Periodic auto-sync (0x30 every 50 frames)
- Graceful fallback when relay unavailable

game-viewer.ds — DreamStack receiver:
- Connects to ws://localhost:9100/stream/snake
- Shows live score, length, speed, position
- PLAYING/GAME OVER status badge

game-snake.ds — DreamStack source (simplified)
game-reaction.ds — Reaction game (bonus)
2026-02-26 20:46:53 -08:00

36 lines
1.2 KiB
Text

-- DreamStack Snake Viewer (Receiver)
-- Watches the snake game live via streaming relay.
--
-- Run with:
-- Tab 1: cargo run -p ds-stream (relay on :9100)
-- Tab 2: open examples/game-snake.html (player)
-- Tab 3: open this build in browser (viewer)
import { Card } from "../registry/components/card"
import { Badge } from "../registry/components/badge"
-- Connect to the snake game stream
let game = stream from "ws://localhost:9100/stream/snake"
view viewer = column [
text "👁️ Snake Spectator" { variant: "title" }
text "Watching the snake game live via relay" { variant: "subtitle" }
row [
Badge { label: "LIVE 🔴", variant: "error" }
Badge { label: "Score: {game.score}", variant: "success" }
Badge { label: "Length: {game.length}", variant: "info" }
Badge { label: "Speed: {game.speed}ms", variant: "warning" }
]
Card { title: "Game State" } [
text "🐍 Head: ({game.headX}, {game.headY})" { variant: "title" }
text "🍎 Food: ({game.foodX}, {game.foodY})"
text "Direction: ({game.dirX}, {game.dirY})"
when game.alive ->
Badge { label: "PLAYING", variant: "success" }
else ->
Badge { label: "GAME OVER", variant: "error" }
]
]