docs(@projects/@magic-civilization): 📝 p3-18 — P5b done (UI embark, GUT-verified); feature complete in sim + UI

Embark + transport now work in both the headless sim (authoritative) and the
rendered UI, verified at unit / integration / GUT levels (732 GUT passing).
Remaining: P6-full headless 1v1-to-game_over demo (confirmatory over P6-core),
vestigial-FFI trim (cosmetic), transport refinements (deferred, documented).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Natalie 2026-06-25 07:03:10 -04:00
parent b02274f920
commit c141a86b77

View file

@ -99,18 +99,21 @@ two-tier Civ model on the existing tree (`public/resources/techs/naval.json`):
entries + emit cases (`unit_panel.gd`) and the signal connections + handlers
(`world_map.gd`) that P3b orphaned. No dangling refs; no GUT test referenced them.
Auto-embark is the only embark model across Rust **and** the GDScript UI.
- [ ] **P5b — rendered-movement embark (functionally required for UI play).** The
rendered game moves via `world_map.gd → PathfinderScript.find_path` (GDScript
`pathfinder.gd`), so embark works **headless only** today. State is hybrid
(GDScript `GameState`/`Player.researched_techs` + a Rust `GdGameState` bridge). To
stay single-source (no re-hardcoding tech ids in GDScript — that would undo P1b),
add a `GdGameState` `#[func]` returning the Rust-computed `EmbarkLevel` (via
`TechWeb::embark_level`), thread it into `pathfinder.gd::_is_passable`/`find_path`/
`find_path_with_fog` + the `world_map.gd` callers; also drop the vestigial embark
inputs from `legal_actions_for`/`can_invoke`. **Rail-1 alternative (preferred
long-term):** route rendered movement through the Rust pathfinder — larger,
overlaps the standing `pathfinder.gd` port debt. *(Dylib-gated: `build-gdext.sh`
works — gdext crate is `magic-civ-physics-gdext`, `cargo check` green in ~38s — + GUT.)*
- [x] **P5b — rendered-movement embark (UI).** ✅ Embark now works in the rendered
UI, not just headless. Single-source: `GdTechWeb.embark_level(researched)`
`#[func]` (`c90ba8719`) returns the Rust-computed level (data-driven
`TechWeb::embark_level`); `KnowledgeWeb` + `TechWeb` pass it through;
`pathfinder.gd` (`find_path`/`movement_range`/`find_path_with_fog` + `_is_passable`)
gained a defaulted `embark_level` and a thin single-tier water gate;
`world_map.gd::_current_embark_level()` feeds the active player's level into all
four pathfinder call sites (`981996529`). Built + deployed the dylib
(`build-gdext.sh aarch64-apple-darwin`, 1m46s) and verified headless: GUT **732
passing / 0 failed**, incl. `test_pathfinder_embark.gd` (`18aad5cdf`) — land
blocked at water without embark, fords with it, naval unaffected. The precise
coast-vs-ocean tier stays authoritative in the Rust sim (UI gate is single-tier
to avoid hardcoding the biome→tier map in GDScript). *Minor remaining:* trim the
vestigial embark inputs from `legal_actions_for`/`can_invoke` + their GDScript
callers (cosmetic; another dylib+GUT cycle).
- [ ] **P6 — end-to-end (full demo).** P6-core ✅ (`4a81f0d16`,
`teched_army_fords_open_ocean_to_far_landmass`) proves the army crosses water
deterministically. P6-full (a headless 1v1 to a decisive `game_over` by crossing