3.9 KiB
3.9 KiB
| id | title | priority | status | scope | category | owner | created | updated_at | blocked_by | follow_ups | |||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| p3-05e | Civic modifier propagation — apply civic effects to per-city yields | p3 | partial | game1 | civics | unassigned | 2026-05-03 | 2026-05-14 |
|
Context
With the three axis catalogs (p3-05b/c/d) and CivicState (p3-05a) in place, this objective wires civic modifiers into the per-city yield computation in mc-economy and mc-city. Modifier semantics are documented in public/games/age-of-dwarves/docs/civics/CIVICS.md — additive vs multiplicative, per-yield vs global, application order.
Acceptance
- ✓
mc-civics::resolve_modifiers(state: &CivicState, &CivicCatalog) -> ResolvedModifiersreturns a typed modifier bundle merging the three active civics. Anarchy axes contribute zero modifiers. Evidence:src/simulator/crates/mc-civics/src/lib.rs(new crate added to workspaceCargo.toml);ResolvedModifiersis a typed struct (18 fields covering every modifier key in the 15 catalog JSONs);axis_choice_idreturnsNonefor the anarchy sentinel. - ✓
mc-economy::city_yield::computeconsumesResolvedModifiers(passed by reference, not global mutable state); applies in documented order: base → additive → multiplicative. Evidence:src/simulator/crates/mc-economy/src/city_yield.rs::compute(base: CityYield, mods: &ResolvedModifiers) -> CityYield; module docstring documents the three-step order;test_application_order_additive_before_multiplicativeexercises it. - ❌
mc-city::specialist::contributionconsumesResolvedModifiers.specialist_xp_rate(from Labor axis) when crediting XP perp2-56b. Deferred —specialist_xp_ratefield is present onResolvedModifiersand is multiplied correctly across axes (testtest_partial_anarchy_keeps_other_axescoversinequality_amplifierwith the same code path); wiring it into the existingmc-city::specialistsite is a small follow-up that drags p2-56b semantics into this ticket and was out of scope for the time budget. - ✓
cargo test -p mc-civics test_modifier_resolution_anarchy_zeroandcargo test -p mc-economy test_civic_modifier_changes_yieldgreen. Evidence:cargo test -p mc-civics test_modifier_resolution_anarchy_zero→1 passed;cargo test -p mc-economy test_civic_modifier_changes_yield→1 passed(this session). - ✓ Headless parity test: switching from
mercantile_marketstoplanned_economymeasurably shifts per-city gold yield in the documented direction. Evidence:mc-economy/src/city_yield.rs::test_civic_modifier_changes_yieldbuilds bothCivicStates, resolves modifiers, and assertsmercantile gold (120) > planned gold (95)from base 100 (mercantile +20%, planned -5%). Test runs undercargo test— no display server required.
Status notes
- The catalog reference doc
public/games/age-of-dwarves/docs/civics/CIVICS.mdnamed in the original context does not exist;CIVIC_OVERVIEW.mdexists but does not document additive-vs-multiplicative semantics. Convention is now documented in themc-civicslib docstring (key-suffix table). Authoring the design doc is a follow-up, not a Rust-side blocker. - Bullet 3 (
mc-city::specialist) is the only open item. K = 4 / N = 5 → statuspartial.
Source-of-truth rails
- Rust crate:
mc-civicsowns resolution;mc-economy/mc-cityconsume typed bundle. No GDScript shadow modifier table. - JSON path: civic JSONs from
p3-05b/c/dare the only source of modifier values; no hardcoded constants. - mc-core wrapper:
ResolvedModifierstyped struct (per-yield fields), not a stringly-typedHashMap<String, f32>.
Out of scope
- Anarchy duration / switch UX —
p3-06. - Inequality cascade —
p3-07a/b. - AI civic-choice scoring — separate AI ticket.
References
public/games/age-of-dwarves/docs/civics/CIVICS.md- Parents:
p3-05a,p3-05b,p3-05c,p3-05d - Sibling:
p3-06