refactor(engine): migrate mana-ability and costs.rs cost movers onto zone_pipeline#6024
Conversation
…zone_pipeline Plan 03 step 6 cost tranche PR2. The remaining raw cost zone-movers (mana_abilities.rs self-exile + selected-exile, and the costs.rs pay_ability_cost_inner remainder) now route through zone_pipeline with the typed PendingCostMoveResume::ManaAbilityPayment continuation: - ManaAbilityCostCursor is the payment program counter (remaining cost legs, per-list cursors, deferred cost events collected exactly once per CR 603.2/603.3b, CR 605.3c excluded_sources, typed parent stack for nested costed mana sources). - AssistState gains PaymentStarted/Paid checkpoints (CR 702.132a + CR 601.2h) so helpers are never double-charged across a pause. - Replacement dispatcher resumes the parked cursor on both the delivered and prevented/substituted paths before draining the ordinary effect rider (CR 601.2h + CR 605.3b + CR 616.1). - Interactive activation-cost legs are removed one-per-payment, including battlefield-exile legs; no-target activations route through the serialized residual dispatcher (CR 601.2c + CR 602.2b). - The transitional ActivationCostMoveHandling enum from #5857 is dissolved. - ~3,900 lines of synthetic-redirect witnesses in tests/integration/cost_zone_pipeline.rs; zone-authority baseline regenerated (60 hits / 41 rows, three migrated rows removed).
There was a problem hiding this comment.
Code Review
This pull request refactors the MTG game engine to support robust pausing and resuming of mana-ability cost payments when interrupted by replacement choices (CR 601.2h, CR 602.2b, CR 605.3b, CR 616.1). It introduces serialized cursors (ManaAbilityCostCursor) and parent tracking (ManaAbilityCostParent) to preserve the exact unpaid cost suffix and state of in-progress payments, preventing them from being treated as failed or completed. It also ensures that Assist contributions are cancellable only before helper payment starts, and filters out private cost continuation state for unauthorized multiplayer viewers. The review comments correctly identify several new or modified rules-touching functions and doc comments across casting.rs, casting_costs.rs, and mana_abilities.rs that are missing mandatory CR annotations, violating repository style rule R6. All comments are valid and should be addressed by adding the suggested CR annotations.
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
| /// Removes the one non-self exile leg paid by the interactive activation-cost | ||
| /// handler. Later exile legs remain in the residual for their own choice. |
There was a problem hiding this comment.
[MEDIUM] Missing mandatory CR annotation.
Why it matters: Every rules-touching line of engine code must carry a comment of the form CR <number>: <description> to ensure strict fidelity to the MTG Comprehensive Rules.
Suggested fix: Add CR 601.2h + CR 602.2b annotation to the doc comment.
| /// Removes the one non-self exile leg paid by the interactive activation-cost | |
| /// handler. Later exile legs remain in the residual for their own choice. | |
| /// CR 601.2h + CR 602.2b: Removes the one non-self exile leg paid by the interactive activation-cost | |
| /// handler. Later exile legs remain in the residual for their own choice. |
References
- Every rules-touching line of engine code must carry a comment of the form CR : . (link)
| /// Removes the one discard leg paid by the interactive activation cost handler. | ||
| /// This keeps a later mana-leg pause from replaying either a chosen hand discard | ||
| /// or the source-card discard that already left its activation zone. |
There was a problem hiding this comment.
[MEDIUM] Missing mandatory CR annotation.
Why it matters: Every rules-touching line of engine code must carry a comment of the form CR <number>: <description> to ensure strict fidelity to the MTG Comprehensive Rules.
Suggested fix: Add CR 601.2h + CR 602.2b annotation to the doc comment.
| /// Removes the one discard leg paid by the interactive activation cost handler. | |
| /// This keeps a later mana-leg pause from replaying either a chosen hand discard | |
| /// or the source-card discard that already left its activation zone. | |
| /// CR 601.2h + CR 602.2b: Removes the one discard leg paid by the interactive activation cost handler. | |
| /// This keeps a later mana-leg pause from replaying either a chosen hand discard | |
| /// or the source-card discard that already left its activation zone. |
References
- Every rules-touching line of engine code must carry a comment of the form CR : . (link)
| /// Removes the one non-self sacrifice leg paid by the interactive activation | ||
| /// cost handler. Later sacrifice legs stay in the residual for later choices. |
There was a problem hiding this comment.
[MEDIUM] Missing mandatory CR annotation.
Why it matters: Every rules-touching line of engine code must carry a comment of the form CR <number>: <description> to ensure strict fidelity to the MTG Comprehensive Rules.
Suggested fix: Add CR 601.2h + CR 602.2b annotation to the doc comment.
| /// Removes the one non-self sacrifice leg paid by the interactive activation | |
| /// cost handler. Later sacrifice legs stay in the residual for later choices. | |
| /// CR 601.2h + CR 602.2b: Removes the one non-self sacrifice leg paid by the interactive activation | |
| /// cost handler. Later sacrifice legs stay in the residual for later choices. |
References
- Every rules-touching line of engine code must carry a comment of the form CR : . (link)
| /// Removes the one `UnattachFrom` leg paid by its interactive cost handler. | ||
| /// Later unattach legs stay in the residual so each one can acquire its own | ||
| /// selection before the activation reaches the stack. |
There was a problem hiding this comment.
[MEDIUM] Missing mandatory CR annotation.
Why it matters: Every rules-touching line of engine code must carry a comment of the form CR <number>: <description> to ensure strict fidelity to the MTG Comprehensive Rules.
Suggested fix: Add CR 601.2h + CR 602.2b annotation to the doc comment.
| /// Removes the one `UnattachFrom` leg paid by its interactive cost handler. | |
| /// Later unattach legs stay in the residual so each one can acquire its own | |
| /// selection before the activation reaches the stack. | |
| /// CR 601.2h + CR 602.2b: Removes the one UnattachFrom leg paid by its interactive cost handler. | |
| /// Later unattach legs stay in the residual so each one can acquire its own | |
| /// selection before the activation reaches the stack. |
References
- Every rules-touching line of engine code must carry a comment of the form CR : . (link)
| /// Complete an activation at a cost-payment boundary. | ||
| /// | ||
| /// The caller owns the exact `PendingCast` that accumulated targets, mode labels, | ||
| /// distributions, and already-paid interactive cost legs. Preserve that root if | ||
| /// its remaining cost contains a real mana leg: a mana-source cost move can pause | ||
| /// before the activation reaches the stack. |
There was a problem hiding this comment.
[MEDIUM] Missing mandatory CR annotation.
Why it matters: Every rules-touching line of engine code must carry a comment of the form CR <number>: <description> to ensure strict fidelity to the MTG Comprehensive Rules.
Suggested fix: Add CR 601.2h + CR 602.2b annotation to the doc comment.
| /// Complete an activation at a cost-payment boundary. | |
| /// | |
| /// The caller owns the exact `PendingCast` that accumulated targets, mode labels, | |
| /// distributions, and already-paid interactive cost legs. Preserve that root if | |
| /// its remaining cost contains a real mana leg: a mana-source cost move can pause | |
| /// before the activation reaches the stack. | |
| /// CR 601.2h + CR 602.2b: Complete an activation at a cost-payment boundary. | |
| /// | |
| /// The caller owns the exact PendingCast that accumulated targets, mode labels, | |
| /// distributions, and already-paid interactive cost legs. Preserve that root if | |
| /// its remaining cost contains a real mana leg: a mana-source cost move can pause | |
| /// before the activation reaches the stack. |
References
- Every rules-touching line of engine code must carry a comment of the form CR : . (link)
| /// full chain via `resolve_ability_chain` so nested effects (DealDamage on | ||
| /// controller, GainLife, etc.) route through the standard effect handlers. | ||
| fn resolve_mana_ability_sub_chain( | ||
| #[allow(clippy::too_many_arguments)] |
There was a problem hiding this comment.
[MEDIUM] Missing mandatory CR annotation.
Why it matters: Every rules-touching line of engine code must carry a comment of the form CR <number>: <description> to ensure strict fidelity to the MTG Comprehensive Rules.
Suggested fix: Add CR 605.3b annotation to the function.
| #[allow(clippy::too_many_arguments)] | |
| /// CR 605.3b: Pay selected exile cost for a mana ability. | |
| fn pay_selected_mana_ability_exile_cost( |
References
- Every rules-touching line of engine code must carry a comment of the form CR : . (link)
| Ok(ManaAbilityPaymentProgress::Complete) | ||
| } | ||
|
|
||
| fn pay_mana_ability_cost_component( |
There was a problem hiding this comment.
[MEDIUM] Missing mandatory CR annotation.
Why it matters: Every rules-touching line of engine code must carry a comment of the form CR <number>: <description> to ensure strict fidelity to the MTG Comprehensive Rules.
Suggested fix: Add CR 605.3b annotation to the function.
| fn pay_mana_ability_cost_component( | |
| /// CR 605.3b: Pay individual components of a mana ability's cost. | |
| fn pay_mana_ability_cost_component( |
References
- Every rules-touching line of engine code must carry a comment of the form CR : . (link)
| } | ||
| } | ||
|
|
||
| fn finish_mana_ability_cost_payment( |
There was a problem hiding this comment.
[MEDIUM] Missing mandatory CR annotation.
Why it matters: Every rules-touching line of engine code must carry a comment of the form CR <number>: <description> to ensure strict fidelity to the MTG Comprehensive Rules.
Suggested fix: Add CR 605.3b annotation to the function.
| fn finish_mana_ability_cost_payment( | |
| /// CR 605.3b: Finish mana ability cost payment and produce mana. | |
| fn finish_mana_ability_cost_payment( |
References
- Every rules-touching line of engine code must carry a comment of the form CR : . (link)
| cursor.current_action_deferred_start = 0; | ||
| } | ||
|
|
||
| fn resume_mana_ability_root( |
There was a problem hiding this comment.
[MEDIUM] Missing mandatory CR annotation.
Why it matters: Every rules-touching line of engine code must carry a comment of the form CR <number>: <description> to ensure strict fidelity to the MTG Comprehensive Rules.
Suggested fix: Add CR 601.2h + CR 602.2b + CR 605.3b + CR 616.1 annotation to the function.
| fn resume_mana_ability_root( | |
| /// CR 601.2h + CR 602.2b + CR 605.3b + CR 616.1: Resume the mana ability root after a cost move settles. | |
| fn resume_mana_ability_root( |
References
- Every rules-touching line of engine code must carry a comment of the form CR : . (link)
| } | ||
| } | ||
|
|
||
| fn continue_mana_ability_cost_payment( |
There was a problem hiding this comment.
[MEDIUM] Missing mandatory CR annotation.
Why it matters: Every rules-touching line of engine code must carry a comment of the form CR <number>: <description> to ensure strict fidelity to the MTG Comprehensive Rules.
Suggested fix: Add CR 605.3b annotation to the function.
| fn continue_mana_ability_cost_payment( | |
| /// CR 605.3b: Continue mana ability cost payment. | |
| fn continue_mana_ability_cost_payment( |
References
- Every rules-touching line of engine code must carry a comment of the form CR : . (link)
Parse changes introduced by this PR✓ No card-parse changes detected. |
Plan 03 step 6 cost tranche PR2. The remaining raw cost zone-movers
(mana_abilities.rs self-exile + selected-exile, and the costs.rs
pay_ability_cost_inner remainder) now route through zone_pipeline with
the typed PendingCostMoveResume::ManaAbilityPayment continuation:
legs, per-list cursors, deferred cost events collected exactly once
per CR 603.2/603.3b, CR 605.3c excluded_sources, typed parent stack
for nested costed mana sources).
CR 601.2h) so helpers are never double-charged across a pause.
delivered and prevented/substituted paths before draining the
ordinary effect rider (CR 601.2h + CR 605.3b + CR 616.1).
including battlefield-exile legs; no-target activations route
through the serialized residual dispatcher (CR 601.2c + CR 602.2b).
dissolved.
tests/integration/cost_zone_pipeline.rs; zone-authority baseline
regenerated (60 hits / 41 rows, three migrated rows removed).