Skip to content

fix(parser): recognize "enter(s) the battlefield tapped" long-form external entry#4988

Open
jaso0n0818 wants to merge 1 commit into
phase-rs:mainfrom
jaso0n0818:fix-frozen-aether-enters-battlefield-tapped
Open

fix(parser): recognize "enter(s) the battlefield tapped" long-form external entry#4988
jaso0n0818 wants to merge 1 commit into
phase-rs:mainfrom
jaso0n0818:fix-frozen-aether-enters-battlefield-tapped

Conversation

@jaso0n0818

Copy link
Copy Markdown
Contributor

Summary

Fixes Frozen Aether (and any other card using the fully-spelled entry-event phrasing) falling through to Unimplemented.

Root cause: CR 614.1c ETB-tapped replacement effects with a controller-scoped type-phrase subject ("Artifacts, creatures, and lands your opponents control ...") are templated by WotC in two equivalent surface forms:

  • short: "... enter tapped" (Kismet, Authority of the Consuls, Imposing Sovereign) — already supported
  • long: "... enter the battlefield tapped" (Frozen Aether) — was NOT supported

Only the short form was recognized, so Frozen Aether's Oracle text fell through to Unimplemented. Two independent gates needed the long form added, each already having a short-form arm to mirror:

  • oracle_classifier::is_replacement_pattern — the plural-subject ends_with(" enter tapped") check had no " enter the battlefield tapped" counterpart, so the line never reached the replacement parser.
  • oracle_replacement::parse_external_entry_suffix — the suffix peeler that recovers the type-phrase subject only stripped " enter(s) tapped", not " enter(s) the battlefield tapped".

The "played by your opponents" and "unless"/"if you control" conditional variants already accepted both forms — this closes the last unconditional gap.

Changes

  • crates/engine/src/parser/oracle_classifier.rs: classify the long-form plural suffix as a replacement pattern.
  • crates/engine/src/parser/oracle_replacement.rs: peel the long-form suffix in parse_external_entry_suffix, mirroring the existing short-form arms. Added two parser tests exercising the long form for both the multi-type Or-filter shape (Frozen Aether) and the single-type shape (Imposing Sovereign), alongside the existing short-form regression tests.

Test plan

  • New parser tests: frozen_aether_enters_the_battlefield_tapped_long_form, single_type_enters_the_battlefield_tapped_long_form
  • Regression: authority_of_the_consuls_enters_tapped, blind_obedience_compound_or_filter, frozen_aether_comma_list, uphill_battle_played_by_opponents_enter_tapped, played_by_opponents_entry_covers_creature_and_land all still pass
  • clippy -D warnings clean
  • Full engine test suite green (14678 lib + 1721 integration tests, 0 failures)

Model: claude-sonnet-5 (Claude Code)

…ternal entry

CR 614.1c ETB-tapped replacement effects that key off a controller-scoped
type-phrase subject ("Artifacts, creatures, and lands your opponents
control ...") are templated by WotC in two equivalent surface forms: the
short "enter tapped" (Kismet, Authority of the Consuls, Imposing Sovereign)
and the fully-spelled "enter the battlefield tapped" (Frozen Aether). Only
the short form was recognized, so Frozen Aether's Oracle text fell through
to Unimplemented.

Two gates needed the long form added, mirroring the short-form arm already
present at each:
- `oracle_classifier::is_replacement_pattern` — the plural-subject
  `ends_with(" enter tapped")` check has no `" enter the battlefield
  tapped"` counterpart, so the line never reaches the replacement parser.
- `oracle_replacement::parse_external_entry_suffix` — the suffix peeler
  that recovers the type-phrase subject only strips " enter(s) tapped",
  not " enter(s) the battlefield tapped".

The "played by your opponents" and "unless"/"if you control" conditional
variants already accepted both forms; this closes the last unconditional
gap. Added two parser tests exercising the long form for both the
multi-type Or-filter shape (Frozen Aether) and the single-type shape
(Imposing Sovereign), alongside the existing short-form regression tests.

clippy -D warnings clean; full engine test green (14678 lib + 1721
integration, 0 failures).

Model: claude-sonnet-5 (Claude Code)
@jaso0n0818 jaso0n0818 requested a review from matthewevans as a code owner July 3, 2026 05:41
@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!

@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.

[MED] Parameterize the external-entry tapped suffix family instead of adding another pair of one-off suffix branches. Evidence: crates/engine/src/parser/oracle_replacement.rs:3457 already owns the external entry suffix peel and has the short-form enter tapped / enters tapped pair; this PR adds separate long-form enter the battlefield tapped / enters the battlefield tapped branches at crates/engine/src/parser/oracle_replacement.rs:3480 and crates/engine/src/parser/oracle_replacement.rs:3498. Why it matters: this is exactly the enter(s) [the battlefield] tapped structural axis, so duplicating branches makes the next templating variant another copy/paste site instead of one grammar. Suggested fix: factor the suffix peel into a small parameterized suffix matcher/table for the plain and played by your opponents external-entry cases, preserving the existing precedence but representing enter vs enters and short vs long form as data/alternatives.

[LOW] The current head fails the rustfmt gate. Evidence: CI Rust lint (fmt, clippy, parser gate) reports a cargo fmt --all -- --check diff in crates/engine/src/parser/oracle_replacement.rs around the new TargetFilter::Typed(TypedFilter::creature().controller(...)) assertion. Why it matters: this blocks the required Rust lint gate and is easy to avoid before review. Suggested fix: run cargo fmt --all and push the formatted result.

@matthewevans matthewevans added the bug Bug fix label Jul 3, 2026
@github-actions

github-actions Bot commented Jul 3, 2026

Copy link
Copy Markdown

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

1 card(s) · ability/effect_structure · removed: effect_structure

Examples: The Belligerent and Useless Island

1 card(s) · ability/replacement_structure · added: replacement_structure

Examples: The Belligerent and Useless Island

1 card(s) had Oracle-text changes (errata/reprint) — excluded as non-parser.

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.

2 participants