magicciv/src
Natalie fba5cdfdfb feat(gdext): scaffold live Rust-authoritative unit store (Rail-1 Phase 1)
Mirror the proven `presentation_cities` city store for units: a parallel
`presentation_units: Vec<Vec<mc_state::MapUnit>>` slot on GdGameState, owned
by a new `unit_slot` ops module that is the exact unit-side analogue of
`city_slot`.

- `api-gdext/src/unit_slot.rs`: bounds-safe `at/at_mut`, stable-u32-id
  `index_by_id/locate_by_id`, `spawn`, `move_unit`, `transfer_owner` (capture),
  `remove` (index-shift-safe), `take_damage/heal/set_hp`, posture setters
  (fortify/sentry/movement), `to_dict` projection, `to_json/load_from_json`
  serde round-trip. Pure holding + projection; turn/action logic stays in
  mc-turn / mc-player-api dispatch (no duplication of MapUnit mutation).
- GdGameState gains `presentation_units`, initialised parallel to
  `presentation_cities` (empty rows grow on demand) and folded into the save
  envelope at every site (init, serialize_full, load_from_json).
- SaveEnvelope gains `presentation_units` (#[serde(default)]); CURRENT_VERSION
  bumped v3 → v4. save_envelope.rs literals + version-lock test updated.
- `#[func]` delegators on GdGameState mirror the city_* surface (spawn_unit,
  move_unit_slot, transfer_unit, remove_unit, unit_take_damage/heal/set_hp,
  posture setters, unit_dict, unit_index_by_id/locate_by_id, unit_to_json/
  load_from_json).
- `GdUnit` per-instance wrapper for parity with GdCity (owned MapUnit,
  to_dict/to_json/field reads).

Tests: 7 unit_slot ops tests (spawn→locate, move, remove-shift-id-stable,
damage/heal clamp, posture, transfer between rows, json round-trip) + the
updated save_envelope suite, all green.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-27 16:10:27 -04:00
..
game feat(@projects/@magic-civilization): ⚔️ p3-26 B6b (3/3 boot) — FFI + harness boot the item combat table 2026-06-26 21:15:09 -04:00
packages
simulator feat(gdext): scaffold live Rust-authoritative unit store (Rail-1 Phase 1) 2026-06-27 16:10:27 -04:00