Skip to content

feat(parser): grant Replicate at a self-mana-cost (Hatchery Sliver #5323)#5459

Merged
matthewevans merged 1 commit into
phase-rs:mainfrom
shin-core:pr-hatchery-sliver-replicate-grant-5323
Jul 9, 2026
Merged

feat(parser): grant Replicate at a self-mana-cost (Hatchery Sliver #5323)#5459
matthewevans merged 1 commit into
phase-rs:mainfrom
shin-core:pr-hatchery-sliver-replicate-grant-5323

Conversation

@shin-core

Copy link
Copy Markdown
Contributor

Summary

Fixes #5323. Hatchery Sliver"Each Sliver spell you cast has replicate. The replicate cost is equal to its mana cost." — strict-failed (Unimplemented static_structure); the whole line was dropped, so it granted no replicate.

#5436 added the table-driven alt-cost-keyword grant recognizer (parse_granted_self_cost_keyword) for Blitz (Henzie "Toolbox" Torre) but excluded Replicate, noting it "needs separate runtime work (granted replicate is card-build-synthesized)."

That note is now outdated — the runtime for dynamically-granted Replicate already exists on main:

  • effective_replicate_additional_cost_instances reads granted Replicate via effective_spell_keyword_instances (which includes CastWithKeyword grants), surfacing it as a repeatable additional cost (CR 702.56a); and
  • the dynamically_granted_replicate seam in game/triggers.rs synthesizes the per-instance copy trigger for CastWithKeyword-granted Replicate.

So this reduces to one table entry — add ("replicate", Keyword::Replicate) to parse_granted_self_cost_keyword, mirroring Blitz. Hatchery now lowers to CastWithKeyword { Replicate(SelfManaCost) } over a Sliver-spell filter, with zero engine changes.

Tests

  • Parser (static_grant_replicate_hatchery_sliver): Hatchery lowers to CastWithKeyword { Replicate(SelfManaCost) } with a Sliver subtype filter + ControllerRef::You (mirrors the granted-Blitz test).
  • Runtime (dynamically_granted_replicate_enqueues_copy_trigger): a granted-Replicate Sliver spell (no printed Replicate, one paid instance) fires its CopySpell trigger via the existing seam — empirically proving the grant functions end-to-end. This seam previously had no dedicated test, so this also closes a coverage gap.

Verification

  • cargo check -p engine — clean
  • cargo clippy -p engine — clean
  • Suites pass: static-parser (1074), casting (777), triggers (360) — zero failures.

CR 702.56a (Replicate) + CR 611.2f (cast-time keyword snapshot) + CR 601.2f (self-referential granted cost).

🤖 Generated with Claude Code

…ase-rs#5323)

Hatchery Sliver — "Each Sliver spell you cast has replicate. The replicate
cost is equal to its mana cost." — strict-failed (Unimplemented
static_structure): the whole line was dropped, so it granted no replicate.

phase-rs#5436 added the table-driven alt-cost-keyword grant recognizer
(`parse_granted_self_cost_keyword`) for Blitz (Henzie "Toolbox" Torre) but
excluded Replicate, noting it "needs separate runtime work (granted replicate
is card-build-synthesized)". That note is now outdated — the runtime for
dynamically-granted Replicate already exists:
  - `effective_replicate_additional_cost_instances` reads granted Replicate
    via `effective_spell_keyword_instances` (includes CastWithKeyword grants),
    surfacing it as a repeatable additional cost (CR 702.56a); and
  - the `dynamically_granted_replicate` seam in `game/triggers.rs` synthesizes
    the per-instance copy trigger for CastWithKeyword-granted Replicate.

So this reduces to one table entry: add `("replicate", Keyword::Replicate)`
to `parse_granted_self_cost_keyword`, mirroring Blitz. Hatchery now lowers to
`CastWithKeyword { Replicate(SelfManaCost) }` over a Sliver-spell filter, with
zero engine changes.

Tests:
  - parser: Hatchery lowers to CastWithKeyword { Replicate(SelfManaCost) } with
    a Sliver subtype filter (mirrors the granted-Blitz test).
  - runtime: `dynamically_granted_replicate_enqueues_copy_trigger` proves the
    granted Replicate fires its CopySpell trigger end-to-end via the existing
    seam (this seam previously had no dedicated test).

CR 702.56a + CR 611.2f + CR 601.2f.

Closes phase-rs#5323

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@shin-core shin-core requested a review from matthewevans as a code owner July 9, 2026 20:27

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Code Review

This pull request extends the static keyword grant parser to support the 'replicate' keyword (e.g., for Hatchery Sliver) alongside 'blitz', mapping it to Keyword::Replicate(ManaCost::SelfManaCost). A comprehensive unit test has been added to verify correct parsing and targeting. No review comments were provided, and the implementation is clean and idiomatic, so I have no feedback to provide.

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.

@github-actions

github-actions Bot commented Jul 9, 2026

Copy link
Copy Markdown

Parse changes introduced by this PR · 3 card(s), 4 signature(s) (baseline: main c3e81b28d95c)

3 card(s) · ability/static_structure · removed: static_structure

Examples: Djinn Illuminatus, Hatchery Sliver, Ian Chesterton

1 card(s) · static/CastWithKeyword(Replicate(SelfManaCost)) · added: CastWithKeyword(Replicate(SelfManaCost)) (affects=you control Saga)

Examples: Ian Chesterton

1 card(s) · static/CastWithKeyword(Replicate(SelfManaCost)) · added: CastWithKeyword(Replicate(SelfManaCost)) (affects=you control Sliver)

Examples: Hatchery Sliver

1 card(s) · static/CastWithKeyword(Replicate(SelfManaCost)) · added: CastWithKeyword(Replicate(SelfManaCost)) (affects=you control instant or you control sorcery)

Examples: Djinn Illuminatus

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

@matthewevans matthewevans self-assigned this Jul 9, 2026

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

Maintainer review: approved. Parser change extends the existing self-cost keyword grant seam; parse-diff matches the claimed Hatchery Sliver / Djinn Illuminatus / Ian Chesterton coverage; runtime granted-Replicate cost and trigger paths are already covered.

@matthewevans matthewevans added enhancement New feature or request quality For high-quality minimal to no-churn PRs labels Jul 9, 2026
@matthewevans matthewevans added this pull request to the merge queue Jul 9, 2026
@matthewevans matthewevans removed their assignment Jul 9, 2026
@matthewevans

Copy link
Copy Markdown
Member

Thank you @shin-core! Nice work! Swing by the Discord if you're ever up to it :)

Merged via the queue into phase-rs:main with commit 55600a9 Jul 9, 2026
13 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request quality For high-quality minimal to no-churn PRs

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Hatchery Sliver — This sliver gives other slivers replicate.

2 participants