feat(api-gdext): expose upgrade target bridge to Godot

Co-Authored-By: Lilith Autocommit <noreply@atlilith.com>
This commit is contained in:
Natalie 2026-05-14 21:37:32 -07:00
parent 72076031d6
commit 4e4433a419

View file

@ -25,19 +25,30 @@ academy). The inverse index lives naturally next to `BuildingRegistry` in
- ✓ `crates/mc-city/src/building.rs``BuildingRegistry` builds an
`upgrade_target: HashMap<String, String>` inverse index over `requires_existing`
at construction time (one pass, deterministic).
at construction time (one pass, deterministic). Evidence:
`src/simulator/crates/mc-city/src/building.rs:425` references the bridge.
- ✓ `crates/mc-city/src/building.rs``BuildingRegistry::get_upgrade_target(&self, building_id: &str) -> Option<&str>`
returns the successor's `id`, or `None` when no successor exists.
- ✓ `src/simulator/api-gdext/src/` — new `building_registry.rs` (or fold into
`building_action.rs`) exposes `GdBuildingRegistry` as a GodotClass with
returns the successor's `id`, or `None` when no successor exists. Evidence:
Rust unit test `registry_get_upgrade_target_returns_successor_id` in
`src/simulator/api-gdext/src/building_registry.rs:106` exercises both arms.
- ✓ `src/simulator/api-gdext/src/building_registry.rs` exposes
`GdBuildingRegistry` as a `GodotClass` with
`#[func] fn get_upgrade_target(building_id: GString) -> GString` returning
`""` for no-successor. Registered in `lib.rs`.
- ✓ `src/game/engine/ui/city/city_detail_formatter.gd` (and
`src/game/engine/ui/encyclopedia/encyclopedia_panel.gd`) call the bridge and
render "Can be upgraded to: <Name>" when the bridge returns a non-empty id.
- ✓ GUT test `src/game/engine/tests/test_building_upgrade_target_bridge.gd`
verifies bridge returns `"infantry"` for `barracks` and `""` for terminal
buildings.
`""` for no-successor (lines 8692).
- ✓ `src/game/engine/scenes/city/city_detail_formatter.gd::_upgrade_target_line`
and `src/game/engine/scenes/encyclopedia/encyclopedia_panel.gd::_building_upgrade_target_line`
call the bridge via `ClassDB.instantiate("GdBuildingRegistry")` + `insert_json`
+ `get_upgrade_target` and render "Can be upgraded to: <Name>" when the
bridge returns a non-empty id. Both early-return `""` if the GDExtension is
not loaded so headless GUT runs stay green. (Path note: objective text said
`engine/ui/...`; canonical scene path is `engine/scenes/...` per
`gdscript-conventions.md`.)
- ✓ GUT test `src/game/engine/tests/unit/test_building_upgrade_target_bridge.gd`
asserts `get_upgrade_target("barracks") == "infantry"`,
`get_upgrade_target("infantry") == ""`, and unknown-id → `""`. Headless
run on apricot (worktree `~/.cache/mc-src-20260514_181147`):
`flatpak run … gut_cmdln.gd -gtest=res://engine/tests/unit/test_building_upgrade_target_bridge.gd -gexit`
**4/4 passed**.
## Out of scope