Scaffold project and author 14-phase roadmap

Browser co-op kitchen game: FastAPI + native WebSockets, server-authoritative
20 Hz simulation, in-memory anonymous lobbies, data-driven YAML levels, Canvas 2D
vanilla ES-module client with locally authored SVG art and no external CDNs.

.agents/PLAN.md records the LOCKED decisions; .agents/user_stories/ holds the 12
flow contracts; .agents/phases/todo/ breaks them into 14 sequential, test-gated
phases (71 task files), each leaving the app launchable and the suite green.

LLM-Generated: true
This commit is contained in:
2026-10-05 17:05:56 -04:00
commit f84c6ebaef
105 changed files with 5752 additions and 0 deletions
+90
View File
@@ -0,0 +1,90 @@
# Undercooked
A cooperative, **in-browser**, Overcooked-style kitchen game: 1–4 players share one
kitchen over WebSockets, cook orders against the clock, and climb a campaign of
levels that get progressively harder. Lobbies are **anonymous** — no accounts, no
email, no password: you create a room, share the 5-character code, play.
> Working title. "Overcooked" is a trademark of Ghost Town Games/Studio MDG; this
> project is an independent homage with its own art, code, and content.
## Status
Roadmap authored, implementation pending. This repository currently contains the
project scaffold and the `.agents/` phased-execution plan. Execute phases with the
`phased-execution` skill (`auto-phase.sh`), starting at
`.agents/phases/todo/01_runnable_service_scaffold/`.
## Quickstart (development)
Requires [`uv`](https://docs.astral.sh/uv/), Python ≥ 3.12, and `podman`/`docker`
for container builds. **There is no database** — all live game state is in memory.
```bash
uv sync --extra dev
uv run undercooked # http://127.0.0.1:8000
uv run undercooked --reload # dev reload
uv run undercooked-levels validate # check every level file loads and is solvable
```
Run the checks:
```bash
uv run ruff check .
uv run pyright
uv run pytest -m "not e2e" # unit + integration
uv run playwright install chromium # once, before the first e2e run
uv run pytest -m e2e # browser suites (app must be running)
bash .agents/validate.sh # the full pipeline gate
```
## Container
```bash
podman build -t undercooked -f Containerfile .
podman run --rm -p 8000:8000 undercooked
# or
podman compose up -d
```
## Configuration
All settings come from the environment (a local `.env` is loaded automatically;
never commit it — see `.env.example`).
| Variable | Default | Meaning |
|---|---|---|
| `UNDERCOOKED_HOST` | `127.0.0.1` | Bind address |
| `UNDERCOOKED_PORT` | `8000` | Bind port |
| `UNDERCOOKED_TICK_HZ` | `20` | Server simulation rate |
| `UNDERCOOKED_SNAPSHOT_HZ` | `20` | Snapshot broadcast rate to players |
| `UNDERCOOKED_MAX_PLAYERS` | `4` | Players per room |
| `UNDERCOOKED_MAX_ROOMS` | `200` | Concurrent rooms before new rooms are refused |
| `UNDERCOOKED_LEVELS_DIR` | `levels/` | Directory of level YAML files |
| `UNDERCOOKED_LOBBY_IDLE_TIMEOUT_S` | `900` | Close empty/idle lobbies |
| `UNDERCOOKED_GUEST_IDLE_TIMEOUT_S` | `45` | Drop a disconnected player's seat after this |
| `UNDERCOOKED_MAX_MESSAGE_BYTES` | `4096` | Hard cap on inbound WS frame size |
| `UNDERCOOKED_MAX_INPUTS_PER_S` | `40` | Per-connection inbound message rate limit |
| `UNDERCOOKED_SIM_LATENCY_MS` | `0` | Injected server-side downlink latency (netcode tests) |
| `DEBUGPY` | `0` | `1` = open a debugpy listener on `DEBUGPY_PORT` at startup |
| `DEBUGPY_PORT` | `5678` | debugpy listen port |
## Layout
```
src/undercooked/ server: FastAPI app, rooms, WebSocket protocol, simulation
levels/ data-driven level definitions (YAML) + recipes
app/static/ browser client: ES modules, Canvas 2D renderer, own SVG art
tests/ unit/, server/, integration/, sim/, e2e/ (one Playwright suite per story)
docs/PROTOCOL.md wire protocol contract (versioned)
.agents/ PLAN.md, user_stories/, phases/ — the phased-execution plan
```
**No external CDNs.** Every byte of JS, CSS, font, and image is served by this app
from `app/static/`. A test enforces it.
## Contributing
Read [AGENTS.md](AGENTS.md) first: it points at `.agents/PLAN.md` (LOCKED decisions)
and the phase protocol. Code changes land by executing phase task files, not by
editing ad hoc.