A real-time multiplayer web game. The backend is FastAPI and WebSockets; the frontend is Next.js with the App Router, TypeScript, and Tailwind CSS.
Lobby and game state currently live in the backend process. PostgreSQL and Redis clients are optional infrastructure placeholders and are not used by gameplay. Run exactly one backend instance. Deploying a new version, restarting the backend, or allowing a free service to sleep will remove active lobbies and games.
- uv
- Node.js 20.9 or newer and npm
Set up and run the backend:
cd backend
cp .env.example .env
uv sync --locked
uv run appIn a second terminal, set up and run the frontend:
cd frontend
cp .env.local.example .env.local
npm ci
npm run devOpen http://localhost:3000. The landing page calls the backend at
http://localhost:8000/health and displays the result.
curl http://localhost:8000/healthSuccessful checks return {"status":"ok"}. Dependency failures return HTTP 503 without
exposing connection details.
Deploy the backend first as a Python Web Service:
- Root directory:
backend - Build command:
pip install uv && uv sync --locked --no-dev - Start command:
uv run app - Health-check path:
/health - Instance count:
1 - Environment variable:
CORS_ORIGINS=https://YOUR-FRONTEND.onrender.com
Deploy the frontend as a Node Web Service:
- Root directory:
frontend - Build command:
npm ci && npm run build - Start command:
npm start -- -H 0.0.0.0 -p $PORT - Environment variable:
NEXT_PUBLIC_API_URL=https://YOUR-BACKEND.onrender.com
After Render assigns the frontend URL, update the backend's CORS_ORIGINS to that exact origin
without a trailing slash and redeploy the backend. The frontend automatically converts the
HTTPS backend URL to wss:// for WebSocket connections.
cd backend
uv run pytest
uv run ruff check .
uv run ruff format --check .
cd ../frontend
npm run lint
npm run format:check
npm run build