curltastic/README.md
Jason Dekarske dc62c4f55f docs: multi-client free team pick and shared watchers
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-07-10 23:16:07 -07:00

67 lines
2.7 KiB
Markdown

## 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](https://rustup.rs/) (if not already installed).
2. Start the backend:
```bash
cd backend
cargo run --release
# listens on 0.0.0.0:3000
```
3. Start the frontend dev server:
```bash
cd frontend
npm install
npm run dev
# opens on 0.0.0.0:5173 by default
```
4. Open one or more browser tabs to the same room URL, e.g.:
```
http://localhost:5173/?room=DEMO1
```
Use the team dropdown in the top-right to switch between Red and Yellow — this enables local pass-and-play on one device. Use the *Copy share link* button to invite an opponent on another device.
### 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`. The default view is zoomed in on the house; drag the sheet vertically to scroll up to the hog line.
### Controls
- Drag inside the house to place the broom (aim point).
- Use the team dropdown to choose which team's stone you are throwing.
- Use the left/right arrow buttons to select curl; the arrow points the direction the stone will curve.
- Tap **THROW**.
- The server runs the physics for every stone and streams their paths; the frontend interpolates the animation, so collisions animate smoothly for all stones.
- Drag anywhere outside the house (or when it's not your turn) to scroll up toward the hog line.
### 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:
```bash
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
node collision_trajectory_qa.cjs # verifies every stone gets a trajectory during a collision
```
### 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.