Web game: each user owns a restaurant, places furniture on a grid, prestige scales with decor, and logging in runs an offline-style order simulation to earn soft currency.
Overview — restaurant + parking lot + train station (left) + airport (back) + the catalog sidebar:
Interior — full set of furniture (kitchen zone, tables, red sofas, L-sofa, TV + arcade machine, aquariums, ceiling fans), with the train pulled up at the platform and the plane parked on the runway behind:
Front side — restaurant entrance, the 4-row × 10-stall numbered parking lot with cars driving on the right-hand lane, and pedestrians walking the perimeter:
docker compose up -dcd backend
python3 -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt -r requirements-dev.txt
alembic upgrade head # includes restaurants.operation_mode (edit | ready); idempotent if column already exists
uvicorn app.main:app --reload --host 127.0.0.1 --port 8000If you skipped Alembic, restart uvicorn once: startup runs a small patch that adds restaurants.operation_mode when the column is missing (avoids MySQL 1054 Unknown column).
cd frontend
npm install
npm run devOpen http://localhost:5173.
By default in dev, the frontend calls the API through the Vite proxy at /api → http://127.0.0.1:8000, so you usually do not need VITE_API_BASE. This avoids Failed to fetch when you open the dev server from another device on your LAN (npm run dev -- --host): 127.0.0.1 in that browser would point at the wrong machine if you forced VITE_API_BASE=http://127.0.0.1:8000.
If the proxy target is not 127.0.0.1:8000, set VITE_DEV_PROXY_TARGET (see frontend/.env.example). To bypass the proxy, set VITE_API_BASE (for example http://127.0.0.1:8000).
-
Place: choose an item in the sidebar → click a grid cell (Place mode).
-
Move: Move mode → click a piece (or “Pick up” in the list) → click a cell to put it down.
-
Stash: Stash mode → click a piece or use “Stash” in the list to remove it from the floor.
-
Rotate: Rotate mode → click a cone arrow on a piece to face its front toward that direction (collision-checked server-side via
POST /me/restaurant/rotate). -
Edit / Ready:
POST /me/restaurant/modewith{ "mode": "edit" | "ready" }. Ready opens the floor: layout APIs are blocked; simple guest loop sits on chairs only; each finished meal callsPOST /me/restaurant/customer_meal(server pays $5–$15 in soft cents). Edit closes and unlocks layout again. -
Prestige: sum of
base_decorfor placed catalog items (MVP). -
Income: calling
GET /me/restaurantruns offline order simulation and writes the ledger (MVP). -
Furniture definitions (frontend): edit
frontend/src/game/furniture/fixtures.ts(ids must match the backend catalog). Optional GLBs live underfrontend/public/models/. -
IPv4 API URL: prefer
http://127.0.0.1:8000overhttp://localhost:8000if you hit port conflicts / IPv6 issues.
backend/: FastAPIfrontend/: Vite + React + Three


