magicciv/.project/objectives/p2-09-guide-web-deploy.md
Natalie c88e136469 fix(@projects): 🐛 update deployment and guide workflows
Co-Authored-By: Lilith Autocommit <noreply@atlilith.com>
2026-06-10 03:38:03 -07:00

7.1 KiB

id title priority status scope owner updated_at evidence
p2-09 Player guide web app — builds clean from source p2 done game1 2026-04-17
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_spellsunlocks: 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.