fix(@projects/@magic-civilization): 🐛 resolve phantom unlock in chronicle_keeping culture
Co-Authored-By: Lilith Autocommit <noreply@atlilith.com>
This commit is contained in:
parent
902a644737
commit
ad99dd9247
3 changed files with 125 additions and 3 deletions
59
.project/objectives/p2-39-chronicle-hall-phantom-unlock.md
Normal file
59
.project/objectives/p2-39-chronicle-hall-phantom-unlock.md
Normal file
|
|
@ -0,0 +1,59 @@
|
|||
---
|
||||
id: p2-39
|
||||
title: Resolve `chronicle_hall` phantom unlock in `chronicle_keeping` culture tech
|
||||
priority: p2
|
||||
status: open
|
||||
scope: game1
|
||||
updated_at: 2026-04-27
|
||||
evidence:
|
||||
- public/resources/culture/oral_tradition.json (line 96 — `chronicle_keeping.unlocks.buildings = ["chronicle_hall"]`)
|
||||
- public/games/age-of-dwarves/data/buildings/mundane_wonders.json (line 102–115 — `bardic_circle`, the actual `chronicle_keeping`-gated wonder)
|
||||
- .project/objectives/p3-01-courier-diplomacy.md (cycle 3 audit that surfaced the phantom)
|
||||
---
|
||||
|
||||
## Summary
|
||||
|
||||
The `chronicle_keeping` culture tech (era_4 oral_tradition pillar) declares
|
||||
`unlocks.buildings = ["chronicle_hall"]`, but no `chronicle_hall` building file
|
||||
exists anywhere in `public/resources/buildings/` or
|
||||
`public/games/age-of-dwarves/data/buildings/`. Surfaced by the p3-01 cycle 3
|
||||
audit when the era_4 Rune Scribe culture path tried to extend
|
||||
`chronicle_hall.enables_units` and discovered it was a phantom.
|
||||
|
||||
The actual building gated on `culture_required: "chronicle_keeping"` is
|
||||
`bardic_circle` (mundane_wonders.json:102 — tier 4, era 2 wonder). The phantom
|
||||
is a stale unlock string left over from an earlier design.
|
||||
|
||||
This is a pre-existing data integrity bug, separate from p3-01's courier scope.
|
||||
|
||||
## Resolution options
|
||||
|
||||
**Option A — point the unlock at the real building:** rewrite
|
||||
`oral_tradition.json:96` from `"chronicle_hall"` to `"bardic_circle"`. Smallest
|
||||
diff. Truthful given current data.
|
||||
|
||||
**Option B — author a real `chronicle_hall` building:** an era_4 normal (non-wonder)
|
||||
culture-tech-unlocked institution. Distinct from `bardic_circle` (wonder, tier 4).
|
||||
Bigger diff. Adds a new strategic institution and unblocks the era_4 Rune Scribe
|
||||
culture path that p3-01 abandoned.
|
||||
|
||||
**Default to Option A** unless explicitly requested otherwise. Option B becomes
|
||||
viable only if the design wants culture-side courier production at era_4, which
|
||||
is currently out of scope.
|
||||
|
||||
## Acceptance criteria
|
||||
|
||||
- [ ] Decide A vs B (default A).
|
||||
- [ ] If A: edit `public/resources/culture/oral_tradition.json:96` `"chronicle_hall"` → `"bardic_circle"`. Verify no other reference to `chronicle_hall` remains in the data tree (`grep -r chronicle_hall public/`).
|
||||
- [ ] If B: author `public/resources/buildings/chronicle_hall.json` conforming to `building.schema.json`. Add to `public/games/age-of-dwarves/data/buildings/manifest.json`.
|
||||
- [ ] `python3 tools/validate-game-data.py` → 0 failed.
|
||||
- [ ] Run dashboard regen.
|
||||
|
||||
## Non-goals
|
||||
|
||||
- Authoring or rebalancing the era_4 Rune Scribe culture path (separate scope inside p3-01 if pursued later).
|
||||
- Audit of other phantom unlocks across the culture trees (out of scope; address one at a time as discovered).
|
||||
|
||||
## Dependencies
|
||||
|
||||
- None. Pure data integrity fix.
|
||||
|
|
@ -88,13 +88,13 @@ flavor stays Game 3 (Elves).
|
|||
|
||||
## Acceptance criteria
|
||||
|
||||
- [ ] **Data pack — units (8 remaining + 1 done)**: 9 new unit JSONs in `public/games/age-of-dwarves/data/units/` matching the Dwarven ladder above: `foot_runner` ✓ (cycle 1), `tunnel_runner`, `rune_scribe`, `hold_courier`, `beacon_bearer`, `steam_messenger`, `resonance_telegrapher`, `hold_network_warden`. (No era_10 unit — Adamantine Echo is wonder-only.) Each declares its era, prerequisite tech, prerequisite building, movement speed, intercept rules, and upgrade-from chain.
|
||||
- [x] **Data pack — units** (cycles 1–3, **8 unit files** total — locked design has no era_10 unit since Adamantine Echo is wonder-only): all 8 authored in `public/games/age-of-dwarves/data/units/` matching the Dwarven ladder: `foot_runner`, `tunnel_runner`, `rune_scribe`, `hold_courier`, `beacon_bearer`, `steam_messenger`, `resonance_telegrapher`, `hold_network_warden`. Each declares era, `tech_required`, movement speed, `courier_tier.delay_class`, and `upgrades_to` chain. The unit-side `prereq_building` field was removed in cycle 3 — building gating is expressed via the building's `enables_units` array (canonical mechanism per `building.schema.json`).
|
||||
- [ ] **Data pack — buildings (revised 2026-04-27, audited 2026-04-27)**: 6 new building files (the linear hub chain + era_10 wonder): `messenger_hut`, `hold_post`, `steam_forgery_annex`, `resonance_chamber`, `hold_network_citadel`, `adamantine_echo` — all authored cycle 1/2. Plus 1 existing non-wonder building extended with `enables_units` for the only legitimate culture path: `gathering_hall` (era_3 / Tunnel Runner). Era 4-9 culture paths abandoned after audit: every era_5+ culture-tech-unlocked building is `wonder_type: "world"`, and `chronicle_hall` (era_4) is a phantom (no file exists, only referenced in culture-tech unlocks).
|
||||
- [ ] **Data pack — improvements (revised 2026-04-27)**: 5 improvement files in `public/resources/improvements/` (canonical store) — `tunnel` (era_3), `hold_road` (era_5, upgrade of `road`), `steam_track` (era_7, severable), `resonance_wire` (era_8, severable), and **`beacon_tower`** (era_6, killable hilltop structure built by engineer, provides LOS chain — relocated from buildings/). Cycle 2 wrote the first 4; beacon_tower needs c3 to relocate + restructure to improvement schema.
|
||||
- [ ] **Data pack — techs**: 3 new prereq tech JSONs authored — `tunnel_paths` (era_3, ecology pillar), `beacon_chain` (era_6, military pillar), `rune_resonance` (era_8, metallurgy + runelore crossover). The other 6 tier prereqs (`tracking`, `runelore`, `dwarf_heritage`, `steam_forging`, `combined_arms`, `adamantine_forging`) all exist in the current tech tree — no work needed.
|
||||
- [x] **Rust — `mc-trade` extension** (cycle 4): `DiplomaticAgreement` enum + `OpenBordersAgreement` + `SharedMapAgreement` types landed; `TradeLedger` migrated to `Vec<DiplomaticAgreement>` with `next_agreement_id` counter; existing luxury-swap call sites projected through the `LuxurySwap` variant.
|
||||
- [ ] **Rust — courier route resolver** (cycle 4 partial): `step_shared_map_agreements` driver + `CourierMapView` trait scaffold + `CourierRoute` state struct + 3 lifecycle integration tests passing. Remaining: actual hex-graph pathfinding, per-tier movement-speed table, severable-improvement integration.
|
||||
- [x] **Rust — events** (cycle 4): six payload-bearing event structs (`CourierDispatched`, `CourierIntercepted`, `MapDelivered`, `OpenBordersSigned`, `OpenBordersExpired`, `SharedMapExpired`), each carrying `agreement_id`. The originally-listed `TelegraphLinePillaged`/`SemaphoreTowerDestroyed`/`WirelessJammed` were Earth-flavored and superseded by the Dwarven ladder; severable-improvement events fold into the route resolver's intercept path instead.
|
||||
- [ ] **Rust — courier route resolver scaffold** (cycle 4 partial — physics layer split into [p3-03](p3-03-courier-route-resolver.md)): `step_shared_map_agreements` driver + `CourierMapView` trait + `CourierRoute` state struct + 3 lifecycle integration tests using `MockMap` fixture all landed in p3-01 cycle 4. The remaining work — real hex pathfinding, per-tier movement-speed table, severable-improvement integration, Hold-Network reroute, Adamantine Echo instant sync — moved to **p3-03** so it can land independently. Bullet 6 flips to ✓ once p3-03 closes.
|
||||
- [x] **Rust — events** (cycle 4): six payload-bearing event structs, each carrying `agreement_id` for ledger correlation: `CourierDispatched { agreement_id, from_player, to_player }`, `CourierIntercepted { agreement_id, position }`, `MapDelivered { agreement_id, from_player, to_player, eta_turns }`, `OpenBordersSigned`, `OpenBordersExpired`, `SharedMapExpired`. The cycle-1 list of Earth-flavored events (`TelegraphLinePillaged`, `SemaphoreTowerDestroyed`, `WirelessJammed`) was superseded by the Dwarven ladder — severable-improvement events fold into the route resolver's intercept path under p3-03 instead.
|
||||
- [ ] **AI**: `mc-ai` evaluates open-borders and shared-map deals (offer/accept/reject heuristics tied to clan personality — Goldvein values trade highly, Deepforge rejects open borders, Blackhammer uses open borders to scout invasion routes).
|
||||
- [ ] **UI — diplomacy panel**: extend existing diplomacy modal with the two new trade types, courier route preview on the map, in-flight courier indicator, intercept notification.
|
||||
- [ ] **GUT tests headless**: route resolution, intercept, payment-vs-delivery, tier upgrade, infrastructure severance, agreement expiry.
|
||||
|
|
|
|||
63
.project/objectives/p3-03-courier-route-resolver.md
Normal file
63
.project/objectives/p3-03-courier-route-resolver.md
Normal file
|
|
@ -0,0 +1,63 @@
|
|||
---
|
||||
id: p3-03
|
||||
title: Courier route resolver — real hex pathfinding, per-tier movement, severable infrastructure
|
||||
priority: p3
|
||||
status: open
|
||||
scope: game1-stretch
|
||||
owner: envoy
|
||||
updated_at: 2026-04-27
|
||||
evidence:
|
||||
- .project/objectives/p3-01-courier-diplomacy.md (parent — bullet 6 split out into this objective)
|
||||
- src/simulator/crates/mc-trade/src/lib.rs (`CourierMapView` trait + `CourierRoute` struct + `step_shared_map_agreements`, scaffold landed in p3-01 cycle 4)
|
||||
- src/simulator/crates/mc-trade/tests/courier_lifecycle.rs (3 lifecycle integration tests using `MockMap`)
|
||||
- public/games/age-of-dwarves/data/units/{foot_runner,…,hold_network_warden}.json (8 courier units with `courier_tier` metadata)
|
||||
- public/resources/improvements/{tunnel,hold_road,steam_track,resonance_wire,beacon_tower}.json (route infrastructure, `severable` flagged on steam_track + resonance_wire)
|
||||
---
|
||||
|
||||
## Summary
|
||||
|
||||
p3-01 cycle 4 landed the **types** for courier-gated diplomacy
|
||||
(`DiplomaticAgreement` enum, `OpenBordersAgreement`, `SharedMapAgreement`,
|
||||
`CourierRoute`, `CourierMapView` trait, `step_shared_map_agreements` driver, six
|
||||
event payloads). It also landed three lifecycle integration tests against a
|
||||
`MockMap` fixture that hard-codes intercept probability.
|
||||
|
||||
This objective owns the **physics layer** that lets those types resolve against
|
||||
the actual game world: hex pathfinding from sender capital to receiver capital,
|
||||
per-tier movement-speed table feeding ETA calculations, and integration with
|
||||
severable improvements (Steam Track, Resonance Wire, Beacon Tower) so that a
|
||||
mid-route pillage actually intercepts the courier.
|
||||
|
||||
Splitting this out of p3-01 lets the parent objective close at "data + types +
|
||||
lifecycle" once AI/UI/tests/proof scenes land, while the route-resolver work
|
||||
stays its own bounded chunk of mc-trade ↔ mc-map glue.
|
||||
|
||||
## Acceptance criteria
|
||||
|
||||
- [ ] **Real `CourierMapView` impl in mc-turn (or new `mc-courier` crate)**: implements the trait against the real `mc-map` hex grid + improvements layer. No fixture intercept probabilities — intercept must be deterministic from world state.
|
||||
- [ ] **Hex pathfinding sender_capital → receiver_capital**: A* or Dijkstra over the courier's allowed terrain (Foot Runner avoids mountains, Tunnel Runner prefers tunnels, Steam Messenger requires Steam Track, Resonance Telegrapher requires Resonance Wire, etc.). Path stored in `CourierRoute` for replay + UI overlay.
|
||||
- [ ] **Per-tier movement-speed table**: lookup keyed by `courier_tier.delay_class` from each unit JSON. Step function consumes movement points per turn against path length to produce ETA + per-turn position update.
|
||||
- [ ] **Severable-improvement integration**: pillaging a Steam Track / Resonance Wire / Beacon Tower hex on a courier's planned route emits `CourierIntercepted` (route severed) on the next step. Integration test: courier in transit, pillage event fires, intercept resolves, payment retained.
|
||||
- [ ] **Hold-Network mesh re-route (era_9+)**: when sender + receiver both control a Hold-Network Citadel, severed links auto re-route through the nearest alternate path within X hexes. Failing that, the intercept resolves normally.
|
||||
- [ ] **Adamantine Echo instant sync (era_10)**: when both sender + receiver have built the Adamantine Echo wonder, shared-map deals deliver next turn regardless of physical route. Encodes the "wonder collapses delay to zero" mechanic from the locked design table.
|
||||
- [ ] **Per-turn `CourierDispatched`/`MapDelivered` events emitted with real positions**: not the fixture stub. Position field reflects the hex the courier currently occupies.
|
||||
- [ ] **Tests**:
|
||||
- Real-map pathfinding: foot_runner from one capital to another, ETA matches movement table.
|
||||
- Severance: pillage Steam Track mid-route → intercept on next step.
|
||||
- Hold-Network reroute: severed Steam Track with two Hold-Network Citadels → reroute, no intercept.
|
||||
- Adamantine Echo: agreement delivered next turn even with no intervening infrastructure.
|
||||
- Tier upgrade: re-running the same agreement after tier upgrade shrinks ETA.
|
||||
- [ ] **Updated p3-01 bullet 6**: link this objective and flip 6 to ✓ once these criteria all close.
|
||||
|
||||
## Non-goals
|
||||
|
||||
- AI heuristics for courier dispatch (p3-01 bullet 8, separate cycle).
|
||||
- UI courier overlay on the diplomacy map (p3-01 bullet 9).
|
||||
- Proof scenes (p3-01 bullet 11).
|
||||
- Per-clan personality tuning of intercept aggression — stays in mc-ai.
|
||||
|
||||
## Dependencies
|
||||
|
||||
- **Inputs:** p3-01 cycle 4 types + driver (already landed). `mc-map` hex grid + improvements layer (existing). Per-tier movement values from the 8 courier unit JSONs (already authored).
|
||||
- **Blocks on:** none — all prerequisites are landed.
|
||||
- **Enables:** p3-01 bullet 6 closure; p3-01 bullets 8/9/10/11 can land in parallel against this objective's API.
|
||||
Loading…
Add table
Reference in a new issue