Skip to content

[Bug]: AI legal-target check ignores Protection/HexproofFrom (removal fizzles) #2200

Description

@dearsishs

Description

The AI's anti-self-harm policy and tactical gate decide whether an opponent creature is a legal target using a hand-rolled !has_keyword(Hexproof) && !has_keyword(Shroud) check. This ignores Protection(_), HexproofFrom(_), and the controller-relative nature of hexproof. The engine already exposes the CR-correct find_legal_targets, which the AI should use instead of duplicating targeting legality.

Steps to reproduce

  1. Give an opponent a creature with Protection(white) (or HexproofFrom(white)).
  2. Give the AI a white removal/bounce spell (e.g. Murder).
  3. Let the AI evaluate casting it.

Expected behavior

The AI recognizes there is no legal target (the protected creature can't be targeted, CR 702.11/702.16/702.18) and does not score the spell as a productive cast.

Actual behavior

The AI treats the protected creature as targetable, casts the spell, and it fizzles on resolution (CR 608.2b) — a wasted card and lost tempo.

Impact

Removal/bounce mis-targeting is a visible bad-play signature; it also duplicates targeting legality in the AI in violation of "the engine owns all logic".

Component

  • crates/phase-ai/src/policies/anti_self_harm.rs (has_targetable_opponent_creature, has_opponent_bounce_target, ETB-whiff detector)
  • crates/phase-ai/src/tactical_gate.rs (is_redundant_creature_only_removal)
  • crates/engine/src/game/targeting.rs (find_legal_targets — the CR-correct check to reuse)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions