eros 0ef0dc3d78 refactor(backend): remove remaining dead code and unused constants
Drop unused Game methods, Room.id field, and backend-only sheet ring constants that duplicated frontend definitions.

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-06-24 10:58:35 -07:00

curltastic

A 1v1 async multiplayer 2D curling game for mobile browser.

  • Backend — Rust, Axum, WebSocket, Rapier2D physics (server-authoritative, 120 Hz).
  • Frontend — TypeScript, Vite, Canvas2D, portrait-first touch UI.

Run locally

  1. Install Rust via rustup (if not already installed).
  2. Start the backend:
    cd backend
    cargo run --release
    # listens on 0.0.0.0:3000
    
  3. Start the frontend dev server:
    cd frontend
    npm install
    npm run dev
    # opens on 0.0.0.0:5173 by default
    
  4. Open two browser tabs to the same room URL, e.g.:
    http://localhost:5173/?room=DEMO1
    
    The first tab waits; the second starts the match. Use the Copy share link button to invite an opponent.

Mobile devices

The frontend binds to 0.0.0.0 via --host. Find your machine's LAN IP and open http://<ip>:5173/?room=CODE on the phone. Both devices must be on the same Wi-Fi and able to reach the backend on port 3000.

Controls

  • Drag inside the house to place the broom (aim point).
  • Tap a weight 110.
  • Tap THROW.
  • The server runs the physics and streams the trajectory; the frontend interpolates the animation.

Architecture

  • WebSocket JSON protocol with tagged messages.
  • Server simulates each throw at 120 Hz and sends a subset of (x, y, t) path points at 40 Hz.
  • All game state, scoring, end management, and hammer rules live on the server.
  • Disconnects are tolerated: the room and turn remain in memory.

E2E tests

With the backend and frontend dev server running:

cd e2e
npm install -g ws   # or npm install ws locally in the project
node e2e_test.cjs   # room lifecycle, throw, trajectory, out-of-play removal
node e2e_score.cjs  # stones remain in play and alternate turns

Limitations / known simplifications

  • No accounts, persistence, anti-cheat, replay log, or turn timer.
  • Curl is fixed as a function of release speed (more curl at lower speed); sweeping is not implemented.
  • Stones that pass the back line or leave the sheet are removed from play.
Description
1v1 async multiplayer 2D curling game
Readme 382 KiB
Languages
TypeScript 43.5%
Rust 31.7%
JavaScript 15.6%
CSS 7.9%
Dockerfile 1%
Other 0.3%