Skip to content

Fix Necromancy ETB reanimation (#640)#5778

Merged
matthewevans merged 1 commit into
phase-rs:mainfrom
rykerwilliams:fix/necromancy-etb-reanimation
Jul 14, 2026
Merged

Fix Necromancy ETB reanimation (#640)#5778
matthewevans merged 1 commit into
phase-rs:mainfrom
rykerwilliams:fix/necromancy-etb-reanimation

Conversation

@rykerwilliams

Copy link
Copy Markdown
Contributor

Summary

Necromancy's ETB ability ("it becomes an Aura with "...". Put target creature card from a graveyard onto the battlefield under your control and attach this enchantment to it...") was parsing via the Animate Dead-class combinator (try_parse_reanimator_aura_etb_effect), which only handles the quoted keyword-adoption clause and silently dropped the entire targeted-reanimation sentence — no TargetFilter, no zone reference, no reanimation effect node anywhere in the AST. This is exactly why #640 reports zero targetable creatures: no target-bearing effect was ever built.

Root cause: Necromancy is printed as a plain Enchantment (no Enchant keyword line), unlike Animate Dead which is cast as an Aura and targets at cast time via its printed Enchant restriction. Necromancy's reanimation target is a genuine CR 603.3d stack target chosen when its own ETB triggered ability goes on the stack — a structurally different shape that needed its own recognizer, not a parameter tweak to the existing one.

Fix

  • Added try_parse_reanimator_aura_grant_etb_effect + parse_reanimator_aura_grant_etb_shape, a new whole-body, fail-closed nom recognizer for the "grant" sub-class (plain Enchantment ETB grants Aura-hood + targets its own reanimation), wired into oracle_trigger.rs's dispatch chain alongside the existing Animate Dead arm.
  • Generalized the shared reanimator-Aura chain builder (build_reanimator_aura_etb_chainbuild_aura_attach_chain), parameterized by a new parser-internal EnchantGrantShape enum (Swap for Animate Dead's existing RemoveKeyword+AddKeyword behavior, GrantOnly for Necromancy's AddSubtype+AddKeyword — since Necromancy has no prior Aura subtype/Enchant restriction to swap) and a root_target: TargetFilter parameter (Animate Dead keeps its existing AttachedTo reference; Necromancy gets a genuinely-parsed target).
  • Corrected several 701.17a (Mill) → 701.21a (Sacrifice) CR mis-citations found in the touched functions.

A confirmed 5-card class shares a similar "becomes an Aura with X, [producer effect], attach self to result" template (Necromancy, Last Voyage of the Uncharted, Cloudform, Lightform, Rageform). This PR scopes to Necromancy; the other 4 use an unquoted restriction clause and different producer/sacrifice phrasing, so they correctly stay Unimplemented and are tracked separately for a future follow-up.

CR references

  • CR 603.3d (triggered ability targets chosen when put on the stack)
  • CR 608.2b (fizzle on illegal target)
  • CR 608.2c (follow the reanimation instruction)
  • CR 613.1d (Layer 4 type-changing — AddSubtype)
  • CR 613.1f (Layer 6 ability-granting — AddKeyword)
  • CR 701.3a/b (Attach)
  • CR 701.21a (Sacrifice — corrects prior 701.17a Mill mis-citations)
  • CR 704.5m (unattached Aura → graveyard SBA)

Verification

  • cargo fmt --all — clean
  • cargo clippy --all-targets -- -D warnings — clean
  • New tests (parser shape test, parse_target building-block regression test, 4 runtime pipeline tests covering full reanimation+attach+SBA-survival, cross-controller reanimation, delayed sacrifice, and CR 608.2b fizzle) — all pass
  • Existing Animate Dead/Dance of the Dead test suite (10 tests) — all pass unmodified, confirming the shared builder's generalization is behavior-preserving
  • cargo semantic-audit/cargo coverage — not run locally (cold MTGJSON download didn't complete in this worktree); relying on CI for corpus-level signal

Closes #640

@gemini-code-assist

Copy link
Copy Markdown
Contributor

Warning

You have reached your daily quota limit. Please wait up to 24 hours and I will start processing your requests again!

rykerwilliams added a commit to rykerwilliams/phase that referenced this pull request Jul 14, 2026
@github-actions

github-actions Bot commented Jul 14, 2026

Copy link
Copy Markdown

Parse changes introduced by this PR · 1 card(s), 2 signature(s) (baseline: main f2a7bafdc173)

1 card(s) · ability/ChangeZone · added: ChangeZone (enters_under=You, from=graveyard, target=in graveyard creature, to=battlefield)

Examples: Necromancy

1 card(s) · ability/remove all Enchantment subtypes, add subtype Aura, grant ability · removed: remove all Enchantment subtypes, add subtype Aura, grant ability (affects=self, duration=permanent, grants=add subtype Aura, grants=grant ability, grants=remov…

Examples: Necromancy

@matthewevans matthewevans self-assigned this Jul 14, 2026
@matthewevans
matthewevans force-pushed the fix/necromancy-etb-reanimation branch from 6d4944f to 03b00f5 Compare July 14, 2026 04:04
@matthewevans matthewevans added the bug Bug fix label Jul 14, 2026
@matthewevans
matthewevans force-pushed the fix/necromancy-etb-reanimation branch from 03b00f5 to 74eb0e4 Compare July 14, 2026 04:20
…ture (phase-rs#640)

Necromancy's ETB ability was parsing to an empty Continuous static via the
Animate Dead-class combinator, which only handles the "becomes an Aura"
keyword-adoption clause and silently dropped the entire targeted reanimation
sentence. Adds a new whole-body recognizer for the "grant" sub-class (plain
Enchantment ETB grants Aura-hood and targets its own reanimation, as opposed
to Animate Dead's cast-time Enchant-keyword targeting), generalizing the
shared reanimator-Aura chain builder to cover both shapes via a parser-internal
EnchantGrantShape selector.

Also corrects several 701.17a (Mill) -> 701.21a (Sacrifice) CR mis-citations
found in the touched functions.

Closes phase-rs#640
@matthewevans
matthewevans force-pushed the fix/necromancy-etb-reanimation branch from 74eb0e4 to 16134f5 Compare July 14, 2026 04:39

@matthewevans matthewevans left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approved — Necromancy now uses its ETB trigger's real graveyard-creature target.

✅ Clean

  • The change extends the existing reanimator-Aura parser seam and parameterizes the shared chain for the printed-Aura and grant-Aura shapes.
  • The runtime tests exercise the parser, trigger, zone change, attachment, delayed sacrifice, cross-controller target, and fizzle paths; each would fail if the new dispatch were removed.
  • The Oracle text and sacrifice citation were independently checked against Scryfall and the current Comprehensive Rules.

Recommendation: approved for the merge queue.

@matthewevans
matthewevans added this pull request to the merge queue Jul 14, 2026
@matthewevans matthewevans removed their assignment Jul 14, 2026
Merged via the queue into phase-rs:main with commit 353801d Jul 14, 2026
13 checks passed
rykerwilliams added a commit to rykerwilliams/phase that referenced this pull request Jul 14, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Bug fix

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Necromancy aura does nothing — When I cast Necromancy it gets cast but I can't target any creature in a graveyard.

2 participants