Phoenix
Demon of Rebirth
Unit #102
| HP | PWR | CP | Speed | Range | Tier |
|---|---|---|---|---|---|
| 7 (+1) | 3 (+1) | — | Fast | Local | B |
Abilities
Passive
q: After Phoenix dies, play the Familiar Purifying Flame Readied in Any Lane and Fuse the demon cards on Phoenix under Purifying Flame. (Fused Demons have both names.)
Engine Implementation
def _phoenix_death_trigger(
state: GameState, event: GameEvent, demon: DemonInstance, depth: int
) -> GameState | None:
"""#102 Phoenix — Death trigger: After Phoenix dies, deploy Purifying Flame.
Fires on FATALLY_WOUNDED when Phoenix (unit_id="102") IS the dying target.
Phoenix IS fatally_wounded — this is expected (trigger fires before resolution).
Effect:
1. Deploy Purifying Flame (102_1) READIED in Phoenix's lane (or any available lane).
2. If Phoenix has a fused_bottom card, transfer it to Purifying Flame
(Purifying Flame inherits Phoenix's bottom card as its own fused_bottom).
Purifying Flame is in FUSIBLE_FAMILIARS — it can accept bottom cards.
"""
from engine.operations import deploy_familiar
from engine.data_loader import FAMILIARS
from engine.constants import DemonState
import copy as _copy
# Only fire if Phoenix itself is the dying demon
if event.target is None:
return None
if event.target.instance_id != demon.instance_id:
return None
# Phoenix IS fatally_wounded here — allowed for this trigger
# (effect applies to Purifying Flame, not Phoenix acting)
PURIFYING_FLAME_ID = "102_1"
owner = demon.owner
phoenix_lane = demon.lane
# Check if Purifying Flame is available in the familiar_deck
if PURIFYING_FLAME_ID not in state.players[owner].familiar_deck:
return None # Purifying Flame not available (already in play)
# Re-fetch Phoenix to get current fused_bottom before death
phoenix_current = next(
(d for d in state.demons if d.instance_id == demon.instance_id), None
)
phoenix_fused_bottom = phoenix_current.fused_bottom if phoenix_current else None
# Deploy Purifying Flame (returns state with Purifying Flame READIED on field)
state = deploy_familiar(state, owner, PURIFYING_FLAME_ID, phoenix_lane)
# If Phoenix had a fused_bottom, transfer it to Purifying Flame
if phoenix_fused_bottom is not None:
new_state = _copy.deepcopy(state)
# Find Purifying Flame in the new state (last deployed demon)
flame = next(
(d for d in reversed(new_state.demons) if d.unit_id == PURIFYING_FLAME_ID),
None,
)
if flame is not None:
from engine.data_loader import UNITS
# Apply the inherited bottom card fusion stats
flame_data = FAMILIARS[PURIFYING_FLAME_ID]
if phoenix_fused_bottom in UNITS:
bottom_data = UNITS[phoenix_fused_bottom]
flame.current_hp = (flame_data.hp or 0) + (bottom_data.fhp or 0)
flame.fused_bottom = phoenix_fused_bottom
flame.is_fused = True
# Purifying Flame deploys READIED (per card text: "play Readied")
flame.state = DemonState.READIED
return new_state
return state
register_trigger("102", 0, _phoenix_death_trigger)
Passive
Phoenix is always worth 0 CP, regardless of other modifiers_
Engine Implementation
def _phoenix_cp_override(state, demon) -> dict:
"""Signal that Phoenix is always worth 0 CP via cp_override_zero key."""
return {"cp_override_zero": 1}
register_passive("102", 1, _phoenix_cp_override)
Cover — 1 AP
h: Cover: 1 AP - b, 1x: e: When an Enemy action targets a Local Allied Demon, if Phoenix is a Valid target, you may change 1 target to Phoenix.
Engine Implementation
def _phoenix_cover(
state: GameState, demon: DemonInstance, targets, choices, rng
) -> GameState:
"""#102 Phoenix — Cover
Start of Turn, 1 AP, (ready), 1x: Status: When an Enemy action targets a Local
Allied Demon, if Phoenix is a Valid target, you may change 1 target to Phoenix.
Applies "cover_active" status marker to Phoenix (value=1).
Action resolution system checks this marker and allows target redirection.
Status expires end of current main phase.
"""
from engine.status_effects import apply_status
state = apply_status(state, demon, demon, "cover_active", 1)
return state
register_ability("102", 2, _phoenix_cover)