# Progress ## Phase 1 — Repository Setup - [x] **Step 1.1 — Create the monorepo.** pnpm workspace with `apps/web`, `apps/server`, `packages/sim`, `packages/schema`, `packages/content` (all `@deadhead/*`), strict `tsconfig.base.json` extended by each package. `pnpm install` + `pnpm typecheck` pass. Repo moved to `C:\Projects\Deadhead Space Freight Tycoon` (G: is exFAT, no symlinks). - [x] **Step 1.2 — Linting and formatting.** ESLint 10 + typescript-eslint + Prettier at the root (`pnpm lint`, `pnpm format`). Purity rule bans `Math.random`, `Date.now` and argument-less `new Date()` in `packages/sim` and `packages/content`; verified it fails on a planted `Math.random()`. - [x] **Step 1.3 — Test runner.** Vitest 5 with one project per workspace package (`pnpm test`). Trivial smoke test in `packages/sim/test/smoke.test.ts`; 1 passing. - [x] **Step 1.4 — Continuous integration.** Repo pushed to Gitea; `.gitea/workflows/ci.yml` runs install, typecheck, lint and test on every push (runner `homelab-runner`). Run #1 failed because Prettier scanned the runner's in-workspace `.pnpm-store/`; ignored it, and run #2 is green. - [x] **Step 1.5 — Local Postgres.** `docker compose up -d` starts Postgres 18 with `deadhead` (dev) and `deadhead_test` databases; connected to both with psql. `.env.example` lists the server's env vars. ## Phase 2 — Content Package - [x] **Step 2.1 — Content schemas.** Zod 4 schemas in `packages/content/src/schemas.ts` for Location, ShipModel, CargoType, Skill and GameConfig, with inferred types. Tests check that each schema accepts a valid example and rejects it with any one field missing. - [x] **Step 2.2 — The five locations.** `src/data/locations.ts`: Earth, Moon, Mars, Ceres Station, Jupiter Cloud Platform. Earth and Moon start discovered; Earth has the highest launch multiplier. - [x] **Step 2.3 — The three ship models.** `src/data/ships.ts`: Courier, Freighter, Bulk Hauler, all atmospheric. Speed, capacity and price orderings tested; range rules are checked in Step 3.7. - [x] **Step 2.4 — Cargo types and skills.** `src/data/cargo.ts`: Standard, Heavy, High-Value, Dangerous; skills Long Haul, Heavy Cargo, Expensive Cargo, Dangerous Cargo (max level 5). The location test now checks cargo ids against the real data. - [x] **Step 2.5 — Default game config.** `src/data/config.ts`. Courier + Earth bay ≈ 21 tutorial runs with the placeholder average payout. Money values rescaled ×10 so tutorial runs pay meaningful amounts; epoch moved from `.env.example` into GameConfig. - [x] **Step 2.6 — Single content bundle.** `content` in `src/bundle.ts` holds all data plus `location`, `shipModel`, `cargoType` and `skill` lookups that return `undefined` for unknown ids. ## Phase 3 — Simulation Package - [x] **Step 3.1 — Game clock conversion.** `src/clock.ts`: `realToGame` / `gameToReal` using the config epoch and compression; times are Unix-ms numbers. - [x] **Step 3.2 — Seeded RNG.** `src/rng.ts`: `createRng(seed)` (mulberry32) with `next`, `int`, `pick`; `deriveSeed(parent, label)` for child seeds. - [x] **Step 3.3 — Location positions.** `src/positions.ts`: heliocentric ecliptic positions (million km) from `astronomy-engine` for Earth, Mars and Jupiter; Moon = Earth + fixed offset; Ceres on a circular orbit. - [x] **Step 3.4 — Route distance.** `src/distance.ts`: `routeDistance(from, to, gameTime)`, straight-line million km. - [x] **Step 3.5 — Travel time.** `src/travel.ts`: `travelTimeGameHours(ship, distance)` = cruise time + overhead. - [x] **Step 3.6 — Fuel cost.** `src/fuel.ts`: `fuelCost(ship, origin, distance)` = distance × cost per million km × origin launch multiplier. - [ ] Step 3.7 — Range and landing eligibility - [ ] Step 3.8 — Contract model and payout - [ ] Step 3.9 — Contract board generation - [ ] Step 3.10 — Tutorial contract board - [ ] Step 3.11 — Pilot eligibility - [ ] Step 3.12 — Dispatch validation - [ ] Step 3.13 — Dispatch record creation - [ ] Step 3.14 — Reposition dispatch - [ ] Step 3.15 — In-flight position and progress - [ ] Step 3.16 — XP and leveling - [ ] Step 3.17 — Dispatch resolution - [ ] Step 3.18 — Sim package public API and coverage