magicciv/.project/objectives/p2-09-guide-web-deploy.md

78 lines
7.1 KiB
Markdown
Raw Permalink Normal View History

---
id: p2-09
title: Player guide web app — builds clean from source
priority: p2
status: done
scope: game1
owner:
updated_at: 2026-04-17
evidence:
- public/games/age-of-dwarves/guide/
- public/games/age-of-dwarves/guide/src/app/guide-data.ts
- public/games/age-of-dwarves/guide/src/ambient.d.ts
- public/games/age-of-dwarves/guide/tsconfig.json
- src/packages/guide/
- src/packages/guide/src/index.ts
- src/packages/guide/src/types/game-data.ts
- src/packages/guide/src/types/declarations.d.ts
- src/packages/guide/src/types/ambient.d.ts
- src/packages/guide/src/components/ui/PagePrimitives.tsx
- src/packages/guide/src/contexts/GuideDataContext.tsx
- src/packages/guide/tsconfig.json
- src/packages/guide/package.json
- src/packages/engine-ts/src/types.ts
- src/simulator/api-wasm/
- src/simulator/build-wasm.sh
- tools/deploy-guide.sh
- .project/history/20260417_guide_web_deploy_audit.md
---
## Ownership note (2026-04-17)
Shipwright released this objective per user directive. Guide-web surface is out of Shipwright's scope going forward. A separate agent will pick this up; `owner:` reset to unclaimed. Prior work (guide-drift-dev2 scope narrowing + guide-progress-dev progress-report page + Progress Report page) remains in-repo.
## Summary
Guide React app (Vite + TypeScript + React 19) lives under `public/games/age-of-dwarves/guide/`. WASM climate worker shares Rust crates with the game.
**This pass (guide-drift-dev2 / 2026-04-17):** closed the systematic type drift between `@magic-civ/guide-engine` and its consumer. `pnpm typecheck` is now 0-errors in both packages (was 488 + 221 = 709 TS errors total). The prior "32 errors" count under-counted by ~22x because it only measured consumer-visible errors, not the 488 internal theme-augmentation errors in guide-engine itself.
Per CLAUDE.md's hard Game-1 scope rule (*"do NOT ship Game 2 features into Game 1"*), Option 2 (scope-narrowing) was taken. All Game 2/3 content was excised:
- **Deleted from `src/packages/guide/src/`:** entire `pages/magic/` directory (SpellsPage, MagicSchoolsPage, ArchonsPage, DisciplinesPage, LeyLinesPage), `pages/episodes/EpisodeKzzkytPage.tsx`, `pages/episodes/EpisodeElvesPage.tsx`, `pages/worlds/TheHivePlanetPage.tsx`, `pages/worlds/SilvandelPage.tsx`. Empty `pages/worlds/` dir removed.
- **Deleted from consumer app `src/pages/`:** 5 local Magic pages (Spells, MagicSchools, Archons, Disciplines, LeyLines).
- **Removed from routing + nav:** Ep2/Ep3 nav groups, all `/magic/*` routes, `/worlds/the-hive`, `/worlds/silvandel`, `/episodes/age-of-kzzkyt`, `/episodes/age-of-elves`.
**Structural fixes landed:**
- **styled-components theme augmentation** (`src/packages/guide/src/types/declarations.d.ts`): declared `DefaultTheme` with the exact `colors.{primary,accent,background,surface,border,text}` + `typography.{fontFamily,fontWeight}` shape used everywhere. Closed ~400 of 488 guide-engine errors.
- **Ambient WASM + @resources/* + @lilith/ui-theme stubs** (`src/packages/guide/src/types/ambient.d.ts`, consumer `src/ambient.d.ts`): typed the shapes the guide actually uses, so `tsc --noEmit` from either package resolves cleanly without requiring the WASM pkg to be built.
- **Game-data type drift:** extended `Unit` (added `hp`, `attack`, `defense`, `unit_type`, `flags`, `attributes`, `tier`, `terrain_bonus`, `encyclopedia`), `Building` (`culture_required`, `encyclopedia`), `Resource` / `Improvement` / `Item` (encyclopedia + index sig), `Tech` (replaced `unlocks_units`/`unlocks_buildings`/`unlocks_spells``unlocks: TechUnlocks` + `requires` + `flavor` + `encyclopedia`), `Race` (added `featured_units`, `arcane_rank`, `episode`, `status`), `EncyclopediaEntry` (added `entry_type`, `detail_route`), `EcologicalEventTier` (added `resource_table`), `StrategicAxes` (index sig for dynamic access). Added missing types: `Lens`, `LensCategory`, `LensUnlock`, `LensObservation`, `LensRendering`, `NamedResource`, `ResourceWithEncyclopedia`, `TechUnlocks`.
- **Barrel surface:** rewrote `src/packages/guide/src/index.ts` from 52 lines to 125 lines with the full Game-1 surface (`PreferencesProvider`, `usePreferences`, `usePreferencesReroll`, `resolveGender`, `resolveRace`, `EpisodeProvider`/`Gate`, `GuideLayout`, `MobileNav`, `RaceThemeProvider`, `SPECIES_LIBRARY`, `applyObservationLens`, all retained pages, etc).
- **New UI primitives:** added `PageHeading`, `PageSubtitle`, `DataTable`, `Highlight`, `FeatureGrid`, `FeatureChip` to `PagePrimitives.tsx` to match consumer-app expectations.
- **Context drift:** `GuideDataContextValue` now declares `observationLens?: SpeciesObservationLens` + `speciesLibrary: ObservedSpecies[]` (consumer app was already passing these; type just wasn't there).
- **Path aliases:** consumer's `@magic-civ/*` paths were off-by-one (`../../../``../../../../`); fixed. Added `@magic-civ/web-civmap` alias to guide-engine's tsconfig.
- **Null-guard fixes:** eight consumer pages now guard optional fields before dereferencing (UnitsPage, CommunicationsPage, EncyclopediaModal, EncyclopediaPage, WondersPage, LairsPage, LensesPage, DevSpritesPage).
**Remaining blocker to flip ✅ done:** `pnpm --filter @magic-civilization/guide-age-of-dwarves build` fails at the final rollup step because `.local/build/wasm/magic_civ_physics.js` is absent on the EDIT host (WASM is a per-host artifact; see `.claude/instructions/build-output-locations.md`, path was relocated from `src/simulator/pkg/` per p1-11 on 2026-04-17). Apricot was unreachable during the initial audit pass (`ssh lilith@apricot.lan` timed out). Once apricot is reachable:
```
ssh "$AUTOPLAY_HOST" "cd $PROJECT_ROOT_REMOTE/src/simulator && bash build-wasm.sh"
pnpm --filter @magic-civilization/guide-age-of-dwarves build # from EDIT host
```
should yield a clean `dist/index.html` in one step. The external-hosting decision (GitHub Pages vs Cloudflare Pages vs S3) remains a separate downstream gate.
## Acceptance
-`pnpm --filter guide-age-of-dwarves build` produces a static bundle with zero TypeScript errors — verified 2026-04-25: build completes in ~5.2s (`✓ built in 5.20s`), zero TypeScript errors, both prior blockers resolved (WASM pkg now present at `.local/build/wasm/`, GuideLayout rollup variable-trace error fixed). Output bundle includes all encyclopedia pages, climate simulation worker, three.js vendor chunks. The 500kB chunk-size warning is informational (not an error) and is addressable via `manualChunks` if desired.
- ✓ Fix the `@/game.json` import at `guide-data.ts` so builds don't regress — landed.
- ✓ Guide content stays data-driven — changing a deposit's JSON automatically updates the Resources page on next build — architecture unchanged via `import.meta.glob`.
**Split note:** public-URL deployment moved to its own objective p2-18 (was previously bundled here). Progress-report page moved to p2-19. This objective now focuses purely on "builds clean from source".
## Non-goals
- Interactive in-browser game preview (would need full WASM game, not just climate).
- Shipping Game 2 lore pages (magic schools, Archons, ley lines, Kzzkyt, Silvandel) alongside Game 1. Those are deferred scope per the CLAUDE.md boundary rule.