Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 28 additions & 0 deletions crates/engine/src/game/engine_replacement.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1651,6 +1651,34 @@ pub(super) fn handle_copy_target_choice(
"Mismatched liminal entry resume".to_string(),
));
}
// CR 614.12a: "If a replacement effect that modifies how a permanent enters the
// battlefield requires a choice, that choice is made before the permanent enters the
// battlefield." The choice has just been made, so the `CopyTargetChoice` that asked for it
// is spent and cannot be this action's outcome β€” every branch below either installs a
// genuine new pause (which overwrites `waiting_for`) or completes. MEASURED, not assumed:
// instrumenting all 9 exits of this branch over the full suite gives 16 entries β†’ 16 exits,
// of which the 4 that carry a genuine pause (`NamedChoice`, `ReplacementChoice`) are
// byte-identical with and without this statement; only the 12 that returned the spent
// prompt now return `Priority`. No path that owed a pause returns one less.
//
// CR 603.3: "Once an ability has triggered, its controller puts it on the stack as an
// object that's not a card the next time a player would receive priority." Leaving the
// answered prompt resident made both liminal tails echo it via
// `if !Priority { return waiting_for }`, so the action never settled, `apply_action`
// skipped `run_post_action_pipeline`, and the CR 603.6a entry pair flushed by
// `finish_copy_target_choice_entry` never reached a priority boundary to be scanned β€”
// board ETB observers saw nothing, and the driver re-answered the spent prompt.
//
// Placed above the Token/Meld split because both sub-branches share that echo tail β€” the
// exit histogram covers both (11 Token, 1 Meld).
//
// Mirrors three existing clears, none of which is this handler's Aura tail: this handler's
// own non-liminal tail below, `handle_persist_chosen_attribute_choice` (which is where the
// Aura completion clear lives), and `effects::token::continue_liminal_copy_token_batch`,
// which opens by setting `Priority` exactly like this.
state.waiting_for = WaitingFor::Priority {
player: state.active_player,
};
let mut ability = copy_effect_for_source(state, source_id)
.map(|effect_def| {
build_resolved_from_def_with_targets(
Expand Down
Loading
Loading