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

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, Python ≥ 3.12, and podman/docker for container builds. There is no database — all live game state is in memory.

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:

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

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 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.

S
Description
No description provided
Readme
1.2 MiB
Languages
Python 91.3%
JavaScript 7.7%
CSS 0.9%