# AGENTS.md – Stellar Absorber Game Plan **Project:** Space‑themed “hole.io” style web game where the player controls a black hole that consumes stellar objects (dust → meteorites → planets → stars) to grow, unlocking evolution paths and mission‑based modes. **Stack:** React frontend, Matter.js physics, Node/Express API for persistence, all packaged in a single Docker container. **Host:** Built and tested on Unraid, source stored in Gitea. --- ## 1. Vision \& Scope - **Solo, mission‑driven gameplay** with progression from tiny black hole to massive singularity. - **Evolution system:** player choices (e.g., favor speed vs. mass) unlock different visual skins and abilities. - **Persistence:** player profile, high scores, unlocked evolutions stored server‑side (SQLite) and synced across sessions. - **Extensible design:** modular object types, mission scripts, and UI layers enable future maps, multiplayer, or leaderboards. - **Polished performance:** target 60 FPS on desktop/tablet browsers using Matter.js (shown to sustain ~43 FPS in React benchmarks).[^1] - **Observability:** structured logging, health‑check endpoint, and optional metrics for dashboard integration. --- ## 2. Technical Decisions | Area | Choice | Rationale | | :-- | :-- | :-- | | **Frontend** | React 18 + TypeScript + Vite | Familiar to the developer, fast rebuilds, excellent ecosystem. | | **Physics** | Matter.js (via `matter-js` npm package) | Proven React integration patterns[^2][^3], good performance, active community. | | **Rendering** | HTML5 Canvas (via Matter.js Render) + CSS overlay for UI | Keeps the bundle lightweight; avoids heavy 3D engines for 2‑D gameplay. | | **Backend** | Node.js + Express (tiny API) | Provides REST endpoints for player data, mission logs, and health checks; easy to Dockerize. | | **Database** | SQLite (via `better-sqlite3`) | Zero‑ops, file‑based persistence fits the single‑container goal. | | **Container** | Multi‑stage Docker build: `node:20-alpine` for build, `nginx:alpine` for serving static files + separate Node API service (or single process with `pm2`). | Follows Docker best practices for HTML5 games[^4]. | | **CI/CD** | GitHub Actions (or Gitea Actions) → build → test → push Docker image to private registry → Unraid pulls \& redeploys. | Aligns with the user’s pull‑build‑test workflow on Unraid. | | **Testing** | Jest + React Testing Library for unit/component tests; end‑to‑end with Cypress (optional). | Ensures stability as the codebase grows. | | **Logging** | `pino` (structured JSON logs) + health‑check endpoint (`/healthz`). | Logs can be forwarded to Loki or inspected directly; supports debugging in Unraid. | | **Docs** | Markdown in `/docs`, enforced via `markdownlint` CI rule; README with setup, architecture, API reference. | Guides future contributors and keeps documentation updated. | | **Styling** | Tailwind CSS (via PostCSS) for rapid UI iteration; dark‑mode friendly. | Consistent, utility‑first approach suits rapid prototyping. | --- ## 3. Folder Structure ``` / (repo root) ├── /client # React Vite app │ ├── src/ │ │ ├── components/ # UI (HUD, menus, evolution tree) │ │ ├── game/ # Matter.js world, systems, object factories │ │ ├── hooks/ # custom React‑Matter bridges │ │ ├── styles/ # Tailwind config, global CSS │ │ ├── utils/ # constants, math helpers │ │ └── main.tsx │ ├── index.html │ ├── vite.config.ts │ └── tsconfig.json ├── /server # Node/Express API │ ├── src/ │ │ ├── routes/ # /api/player, /api/missions, /healthz │ │ ├── services/ # data access (SQLite), mission logic │ │ ├── middleware/ # logger, error handler │ │ └── server.ts │ ├── package.json │ └── tsconfig.json ├── /docker │ ├── Dockerfile.client │ ├── Dockerfile.server │ └── docker-compose.yml # optional for local dev ├── /docs │ ├── architecture.md │ ├── api-reference.md │ └── contribution-guide.md ├── /tests │ ├── unit/ │ └── e2e/ ├── .gitignore ├── README.md └── package.json # workspace root (if using monorepo tools like turborepo) ``` --- ## 4. Roadmap (Milestones) | Milestone | Goal | Success Criteria | | :-- | :-- | :-- | | **M0 – Setup** | Repo initialized, Dockerfile written, basic “Hello World” served via Nginx. | `docker compose up` serves static page; health‑check returns 200. | | **M1 – Core Loop** | Matter.js world with draggable black hole; consumable dust particles increase mass and radius. | Player can move hole, absorb particles, see growth; FPS ≥ 50 on dev machine. | | **M2 – Object Hierarchy** | Define tiers: dust → meteorite → asteroid → planet → star. Each tier has size, mass, visual sprite. | Consuming correct tier upgrades mass appropriately; visual change evident. | | **M3 – Persistence Layer** | SQLite schema for player profile (XP, mass, unlocked evolutions). API endpoints to save/load. | Reloading browser retains progress; API returns JSON with correct fields. | | **M4 – Evolution System** | Skill tree UI where spent XP unlocks paths (e.g., “Swift Vortex” ↑ speed, “Graviton Boost” ↑ pull radius). | UI reflects unlocked nodes; gameplay stats adjust accordingly. | | **M5 – Mission Mode** | Scripted missions (e.g., “Reach 1000 mass in 2 min”, “Consume 5 stars”). Completion grants XP and new skins. | Mission UI shows objectives; rewards granted on success. | | **M6 – Polish \& Logging** | Add particle effects, sound, responsive UI scaling, structured logs (`pino`). | Visual polish; logs contain request IDs, timestamps, and error stacks. | | **M7 – Docs \& CI** | Write contribution guide, enforce lint/markdown rules in CI, automate Docker image push to Gitea registry. | Green CI badge; new contributors can run `make dev` and read docs. | | **M8 – Release** | Tag v1.0.0, publish Docker image to private registry, document Unraid deployment steps. | Unraid pulls image, runs container, game accessible via browser on LAN. | --- ## 5. Docker Implementation **Multi‑stage build (client)** ```dockerfile # ---- Build ---- FROM node:20-alpine AS builder WORKDIR /app COPY client/package*.json client/ RUN npm ci COPY client/ . RUN npm run build # outputs to /app/dist # ---- Runtime ---- FROM nginx:alpine COPY --from=builder /app/dist /usr/share/nginx/html EXPOSE 80 ``` **Server (Node API)** ```dockerfile FROM node:20-alpine WORKDIR /app COPY server/package*.json server/ RUN npm ci COPY server/ . EXPOSE 3000 ENV NODE_ENV=production CMD ["node", "dist/server.js"] ``` **docker‑compose.yml (local dev)** ```yaml version: "3.8" services: client: build: context: . dockerfile: docker/Dockerfile.client ports: ["8080:80"] volumes: - ./client:/app - /app/node_modules server: build: context: . dockerfile: docker/Dockerfile.server ports: ["3000:3000"] volumes: - ./server:/app - /app/node_modules environment: - DATABASE_PATH=/data/game.sqlite volumes: - data-volume:/data volumes: data-volume: ``` *Health‑check* added to `server` service: `curl -f http://localhost:3000/healthz || exit 1`. --- ## 6. API Design (Persistence \& Dashboard) | Endpoint | Method | Description | | :-- | :-- | :-- | | `/api/player` | GET | Retrieve player profile (id, mass, xp, unlocked evolutions). | | `/api/player` | POST | Save profile (upsert). Body: `{mass, xp, evolutions:[]}`. | | `/api/missions` | GET | List available missions with completion status. | | `/api/missions/:id/complete` | POST | Mark mission as successful; returns reward XP. | | `/api/logs` | GET | Stream recent server logs (for external dashboard). | | `/healthz` | GET | Returns `{status:"ok"}`; used by orchestrators. | All responses JSON‑encoded; errors follow `{error:"message"}` with appropriate HTTP status. --- ## 7. Development Workflow 1. **Clone from Gitea** ```bash git clone https://git.alwisp.com/jason/stellar.git cd stellar ``` 2. **Local dev** (hot reload) ```bash make dev # runs client (vite) + server (nodemon) with concurrent logs ``` 3. **Testing** ```bash make test # jest + react testing library make e2e # cypress (optional) ``` 4. **Build Docker images** ```bash make docker-build # builds client & server images, tags with git SHA ``` 5. **Push to Gitea Registry** ```bash make docker-push # requires GITEA_TOKEN env var ``` 6. **Deploy on Unraid** - Pull image via Docker tab or SSH: `docker pull git.alwisp.com/jason/stellar:` - Run with `docker run -d -p 80:80 -p 3000:3000 -v /mnt/user/appdata/stellar:/data ` --- ## 8. Documentation \& Maintenance - **README.md**: Quick start, architecture overview, deployment checklist. - **/docs/**: Detailed guides (API, evolution tree, adding new object types). - **linting**: `eslint` (React), `stylelint` (Tailwind), `markdownlint` (docs). Enforced in CI via `make lint`. - **versioning**: SemVer tags; changelog auto‑generated from conventional commits. - **issue template**: Bug report, feature request, and question templates in `.github/ISSUE_TEMPLATE/`. --- ## 9. Success Metrics - **Performance**: ≥ 55 FPS average on mid‑tier laptop Chrome/Firefox (measured via `stats.js` overlay). - **Reliability**: Zero unhandled promise rejections in production logs over 48 h run. - **User Retention**: Mission completion rate > 70 % for players who reach mass ≥ 500 (instrumented via `/api/missions`). - **Operational**: Docker image size < 150 MB (client) and < 120 MB (server); startup < 5 s on Unraid. --- ### Next Steps Answer any clarifying questions about the above plan, then proceed to create the repository skeleton and initial commit. Once the base is approved, we will iterate through the milestones outlined in the roadmap. *Prepared for Jason Stedwell – Senior Software \& Game Dev.*