Tiamat
The Demon Without Reason
Unit #119
| HP | PWR | CP | Speed | Range | Tier |
|---|---|---|---|---|---|
| 12 (+6) | 2 | 3 (+2) | Slow | Any | D |
Abilities
Genetic Splicing — 1 AP
Genetic Splicing: 1 AP - a, 1x: Target Any Fused Demon and another Demon controlled by the same Evoker. Remove 1 demon card from the Fused Demon and Fuse it onto the other Demon (if that card can normally be Fused onto them.) You may either Ready or Exhaust the newly Fused Demon.
Engine Implementation
def _tiamat_genetic_splicing(
state: GameState, demon: DemonInstance, targets, choices, rng
) -> GameState:
"""#119 Tiamat — Genetic Splicing
Action, 1 AP, (exhaust), 1x: Target a Fused Demon and another Demon controlled by
the same Evoker. Remove 1 demon card from the Fused Demon and Fuse it onto the
other Demon (if eligible). May then Ready or Exhaust the newly Fused Demon.
targets[0] = the fused source demon (must be fused).
targets[1] = the destination demon (must not already be fused, unless Dantalion).
choices["new_state"] = "ready" or "exhaust" for the newly fused demon.
The bottom card from the source is transferred to the destination as its fused_bottom.
Source loses its fused status; destination gains fused status + HP bonus.
"""
from engine.data_loader import UNITS
from engine.constants import DemonState
if not targets or len(targets) < 2:
return state
source = targets[0] # The fused demon to extract from
dest = targets[1] # The demon to fuse onto
s_current = next(
(d for d in state.demons if d.instance_id == source.instance_id), None
)
d_current = next(
(d for d in state.demons if d.instance_id == dest.instance_id), None
)
if s_current is None or d_current is None:
return state
if not s_current.is_fused or s_current.fused_bottom is None:
return state # Source must be fused
if s_current.owner != d_current.owner:
return state # Must be same Evoker
# Parse fused_bottom IDs (supports multi-fusion comma-separated)
all_bottom_ids = [bid.strip() for bid in s_current.fused_bottom.split(",") if bid.strip()]
if not all_bottom_ids:
return state
# Player chooses which card to extract, or default to last one
if choices and "extract_id" in choices and choices["extract_id"] in all_bottom_ids:
bottom_id = choices["extract_id"]
else:
bottom_id = all_bottom_ids[-1]
# Genetic Splicing is a special action — bypasses the normal
# "cannot fuse onto already-fused" restriction. The card text says
# "Fuse it onto the other Demon" unconditionally. This allows creating
# multi-fusions (triple, quadruple) that wouldn't be possible with
# normal Demonic Fusion rules.
if d_current.is_familiar:
return state # Cannot fuse familiars (still applies)
new_state = copy.deepcopy(state)
s_in_new = next(
(d for d in new_state.demons if d.instance_id == source.instance_id), None
)
d_in_new = next(
(d for d in new_state.demons if d.instance_id == dest.instance_id), None
)
if s_in_new is None or d_in_new is None:
return state
# Remove extracted card from source's fused_bottom list
remaining_ids = [bid for bid in all_bottom_ids if bid != bottom_id]
if remaining_ids:
s_in_new.fused_bottom = ",".join(remaining_ids)
s_in_new.is_fused = True
else:
s_in_new.fused_bottom = None
s_in_new.is_fused = False
# Recalculate source HP from base + remaining fused cards
from engine.operations import _get_fused_stat
source_base = UNITS[s_in_new.unit_id].hp if s_in_new.unit_id in UNITS else s_in_new.current_hp
s_in_new.current_hp = source_base + _get_fused_stat(s_in_new, "fhp")
# Fuse extracted card onto destination (append if already fused)
bottom_data = UNITS.get(bottom_id)
if bottom_data is None:
return state
if d_in_new.fused_bottom:
d_in_new.fused_bottom += "," + bottom_id
else:
d_in_new.fused_bottom = bottom_id
d_in_new.is_fused = True
# Recalculate dest HP from base + all fused cards
dest_base = UNITS[d_in_new.unit_id].hp if d_in_new.unit_id in UNITS else d_in_new.current_hp
d_in_new.current_hp = dest_base + _get_fused_stat(d_in_new, "fhp")
# Apply ready/exhaust to newly fused demon
new_state_str = choices.get("new_state", "ready") if choices else "ready"
if new_state_str == "exhaust":
d_in_new.state = DemonState.EXHAUSTED
else:
d_in_new.state = DemonState.READIED
return new_state
register_ability("119", 0, _tiamat_genetic_splicing)
Reminder
(Removing the Demon card does not affect the originally Fused Demon's sustained damage, position, or exhaustion.)