Files
undercooked/README.md
T
ducoterra f84c6ebaef 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
2026-10-05 17:05:56 -04:00

91 lines
3.6 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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.