Summary
Combat log messages in both the replay viewer and the live ActivityFeed are too vague to understand what's happening. Messages like "resolved a choice", "started Selection", and "played Rage (powered)" give no useful information about the actual game decisions.
Problem Statement
Two root causes:
1. Rust GameEvent lacks detail
ChoiceResolved has choice_index (integer) but no description of what was chosen (e.g., "Gain 1 Red mana")
CardPlayed doesn't include the effect value (e.g., Attack 4, Block 3)
- Many combat actions emit zero events and fall through to the generic
ActionTaken fallback: DeclareBlock, EndCombatPhase, ResolveAttack, AssignDamageToHero, AssignDamageToUnit, BuySpell, LearnAdvancedAction, SelectReward
2. Narration layer can't show what it doesn't have
narrateRustEvent.ts renders ChoiceResolved as "resolved a choice (Rage)" — useless
- Block declarations, damage assignments, and site interactions are invisible
- The older TS engine narration was richer in some areas (e.g., unit activation included ability used)
Current Behavior
— Ranged Siege Phase —
Krang played Concentration
Krang resolved a choice (Concentration)
Krang started Selection
— Block Phase —
Krang played Determination
Krang resolved a choice (Determination)
— Assign Damage Phase —
— Attack Phase —
Krang played Rage (powered)
Krang started Selection
Krang played Swiftness → Attack 1
Expected Behavior
— Ranged Siege Phase —
Krang played Concentration (basic) — gain 1 mana token
Krang chose: Gain 1 Red mana
Krang skipped Ranged/Siege
— Block Phase —
Krang played Determination (basic) — Block 3
Krang chose: 3 Physical Block
Krang played Ruthless Coercion → Block 3
Krang blocked Orc War Beasts (3 attack fully blocked)
— Assign Damage Phase —
No unblocked damage
— Attack Phase —
Krang played Rage (powered by Red) — Attack 4
Krang played Swiftness → Attack 1
Krang attacked Orc War Beasts: 5 attack vs 5 armor — DEFEATED (+3 fame)
Affected Files
Rust (event generation):
engine-rs/crates/mk-types/src/events.rs — GameEvent enum needs richer variants
engine-rs/crates/mk-engine/src/action_pipeline/mod.rs — event emission, delta detection, ActionTaken fallback
Client (narration):
packages/shared/src/events/narrateRustEvent.ts — primary narration layer
packages/shared/src/events/narrateEvent.ts — legacy TS narration (reference for richer messages)
Replay viewer:
packages/python-sdk/src/mage_knight_sdk/viewer/ndjson_index.py — _summarize_events()
packages/python-sdk/src/mage_knight_sdk/viewer/static/index.html — formatAction()
Acceptance Criteria
Summary
Combat log messages in both the replay viewer and the live ActivityFeed are too vague to understand what's happening. Messages like "resolved a choice", "started Selection", and "played Rage (powered)" give no useful information about the actual game decisions.
Problem Statement
Two root causes:
1. Rust
GameEventlacks detailChoiceResolvedhaschoice_index(integer) but no description of what was chosen (e.g., "Gain 1 Red mana")CardPlayeddoesn't include the effect value (e.g., Attack 4, Block 3)ActionTakenfallback:DeclareBlock,EndCombatPhase,ResolveAttack,AssignDamageToHero,AssignDamageToUnit,BuySpell,LearnAdvancedAction,SelectReward2. Narration layer can't show what it doesn't have
narrateRustEvent.tsrendersChoiceResolvedas "resolved a choice (Rage)" — uselessCurrent Behavior
Expected Behavior
Affected Files
Rust (event generation):
engine-rs/crates/mk-types/src/events.rs—GameEventenum needs richer variantsengine-rs/crates/mk-engine/src/action_pipeline/mod.rs— event emission, delta detection,ActionTakenfallbackClient (narration):
packages/shared/src/events/narrateRustEvent.ts— primary narration layerpackages/shared/src/events/narrateEvent.ts— legacy TS narration (reference for richer messages)Replay viewer:
packages/python-sdk/src/mage_knight_sdk/viewer/ndjson_index.py—_summarize_events()packages/python-sdk/src/mage_knight_sdk/viewer/static/index.html—formatAction()Acceptance Criteria
ChoiceResolvedevents include a human-readable description of the chosen optionCardPlayedevents include the effect value (Attack N, Block N, Move N, Influence N)ActionTakenfallback (block declarations, damage assignments, attack resolution)EnemyDefeatedincludes fame gainednarrateRustEvent.tsupdated to render all new event data