docs(@projects/@magic-civilization): 📝 p3-18 — P5a done, P6-core done; scope P5b (rendered-movement embark, single-source via bridge)

P5a (dead GDScript embark UI) and P6-core (ford integration proof) landed. P5b
(rendered UI embark) scoped: the rendered state is hybrid (GDScript GameState/Player
+ Rust GdGameState bridge); the single-source path is a GdGameState #[func]
exposing the Rust-computed EmbarkLevel, threaded into pathfinder.gd — dylib-gated
(build-gdext.sh works) + GUT. P6-full demo is confirmatory over the integration proof.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Natalie 2026-06-25 06:36:19 -04:00
parent d3b5b12612
commit 307219e039

View file

@ -94,21 +94,28 @@ two-tier Civ model on the existing tree (`public/resources/techs/naval.json`):
target-selection changes that touch 1UPT assumptions (rare for a tier-9 hull;
the prune already handles hull-death). AI does not yet load units onto transports
(negligible value — tier-9 hull the AI rarely builds; embark covers crossing).
- [ ] **P5 — GDScript pathfinder mirror + FFI trim. FUNCTIONALLY REQUIRED.** The
rendered game moves units via `world_map.gd → PathfinderScript.find_path`
(`pathfinder.gd`), NOT the Rust pathfinder — so embark currently works **headless
only** (GdPlayerApi → Rust `process_one_move`), and a human playing the UI cannot
embark until this lands. Either plumb the owner's `EmbarkLevel` into
`pathfinder.gd::_is_passable`/`find_path`/`find_path_with_fog` + their callers,
or (Rail-1 preferred) route world_map movement through the Rust pathfinder. Also
drop the vestigial embark inputs from `legal_actions_for`/`can_invoke` + GDScript
callers. *(Feasible locally — the gdext crate is `magic-civ-physics-gdext` and
`cargo check -p magic-civ-physics-gdext` is green in ~38s; the earlier "cargo
resolver panic" was a wrong `-p gdextension-api` (that name is a crates.io godot
dep, not our crate). Build the dylib via `build-gdext.sh`; GUT verifies.)*
- [ ] **P6 — end-to-end.** A headless 1v1 (both sides driven) reaches a decisive
`game_over` by crossing water to capture the enemy capital — the demo that
motivated this objective.
- [x] **P5a — remove dead GDScript explicit-embark UI.** ✅ (`bb6eb6ee5`) Deleted
the dangling `embark_pressed`/`disembark_pressed` signals, ACTION_SIGNAL_MAP
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.)*
- [ ] **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
water to take the enemy capital) remains — needs the dylib rebuilt + a naval-tech
scenario; confirmatory over the integration proof.
## Code sites