mirror of
https://github.com/ThisTine/Showdown.git
synced 2026-08-18 23:18:48 +07:00
Showdown backend
Rust (axum + tokio). Implements ../PROTOCOL.md: WebSocket rooms that live
entirely in memory and a static file server for the built frontend — the whole
app is one binary plus a dist/ folder.
Run it
# build the frontend first so there is something to serve
cd ../frontend && npm run build && cd ../backend
cargo run # http://localhost:8080
PORT— listen port (default8080)STATIC_DIR— built frontend location (default../frontend/dist)
During frontend development you can instead run npm run dev with
VITE_WS=1 and Vite proxies /ws here.
How it stays small
- No database, by design. A
Roomis a deck, arevealedflag, a round counter and aVecof players — a few hundred bytes. All rooms sit in oneMutex<HashMap>. When the last socket of a room closes, the room is removed; restart the server and everything is gone, which is the point. - One task per socket, nothing else. Each connection is a single
tokio::select!loop (snapshots out, messages in, a 30s keepalive ping). No per-room goroutine-style actors, no background jobs, no timers per room. - Snapshots are serialized once per change (borrowed data, no clones) and
fanned out through a per-room
broadcastchannel with a small buffer.
Files
src/main.rs routes + static serving with SPA fallback (~40 lines)
src/room.rs room state and the game rules (vote/reveal/reset/deck)
src/ws.rs socket lifecycle: hello → select loop → disconnect cleanup
Rules enforced here (mirroring PROTOCOL.md): votes are hidden until reveal
and rejected after it; reveal needs at least one vote; reset/deck-change
start a fresh round; a refresh re-claims the same seat without losing the
vote; watchers (watch handshake — the TV view) receive everything and may
send nothing.