Skip to main content

Actions

An action list is ordered, and the first action that resolves successfully wins. "Resolves" means the runner found a matching, castable card and a valid target.

Shorthand actions

actions:
- pass
- flee
- draw

These are the only three bare scalars. pass always resolves, which makes it a terminator — nothing after it in the phase, and no lower-priority phase, will run once it is reached.

Each also has a mapping form, which is the one to use when you want a guard on it:

actions:
- flee: true
when:
health_below: 15
- pass: true

The value must be true. pass: false does not disable the action — it decodes to an action with nothing set, which never resolves and silently falls through.

An unrecognised scalar is silently accepted

- pss parses without error into an empty action that can never resolve. The file loads, strategies validate passes, and the phase does nothing.

Only the mapping form is strictly validated — - cst: {} is a hard error. Until this is fixed, treat scalar actions as unchecked and confirm behaviour in a real fight.

cast

The general-purpose spell selector.

- cast:
type: damage
school: storm
aoe: true
min_pips: 4
enchant: required
target: boss
FieldValues
typedamage, heal, buff, debuff, charm, ward, aura, enchant, other
schoolAny school, or any
aoeboolean
nameCard name
enchantnone, required
enchantsOrdered enchant chain — see Enchants
targetAny target selector
min_pips / max_pipsPip cost bounds, inclusive
swapcharm/charms, ward/wards, ot/over_time

Fields are ANDed. Leaving one out means "don't care".

cast is the only action whose school: accepts any; on every other action any is treated as a literal school name and matches nothing.

Both pip bounds are ignored when set to 0, so max_pips: 0 does not mean "free spells only"; it means "no upper bound". To match only zero-pip cards, filter another way.

Only cards the game currently reports as castable are considered at all, so a spell you cannot afford this round is skipped before any filter is applied.

enchant: required means the action fails if no matching enchant card is available, and the runner moves to the next action. enchant: none casts the card plain. Omitting enchant leaves the card alone — the only thing that can still enchant it is the round-start enchant.auto pass, which touches damage spells only.

enchant: looks at the card, not the action

On a cast: action the enchant policy is chosen from the spell type of the card that matched. A cast: that picks up a blade is a charm, so it uses your enchant.support policy — not enchant.blade, which only applies to the blade: action. If no policy resolves at all, enchant: required fails the action every round. See Enchants → which policy applies.

swap

Narrows the match to cards carrying a swap effect for one hanging category:

- cast:
swap: charm
target: boss

swap: aura is a load error, not a filter that never matches — there is no swap-aura effect in the client. (Deimos accepts it and silently never matches.) An unknown category is also a load error. Cards that swap everything carry a different effect and are not matched by any category.

Naming a card

- cast: { name: 'Glowbug Squall', enchant: required }

Names are matched against the card's name and display name. Quote anything with spaces — YAML is forgiving until it is not.

Naming a specific card is the right move when you have one you actually want. Filters are for "whatever storm AOE I happen to have".

The support actions

blade, trap, shield, and heal are cast with a spell-type filter baked in. They pick the first castable card matching:

ActionMatches
bladeAny charm
trapA ward whose target type is an enemy
shieldA ward whose target type is self or an ally
healAny heal

That is a filter on what the card is, not on its name. blade: will happily pick a weakness-style debuff charm if that is the first charm in hand — narrow it with school:, or use cast: { name: ... } when you want a specific card.

Their school: matches the card's school by name — any of the eleven, including star, sun, moon, and shadow. What it does not accept is any: unlike cast:, there is no wildcard here, and school: any matches nothing at all. Omit school: instead.

blade

- blade:
school: storm
target: self

Fields: school, target, enchant.

Ally targeting works for support play:

- blade:
school: fire
target: p1
enchant: required

Combined with an enchant policy, this is how a support character puts sharpened blades on the hitter:

enchant:
blade:
prefer: sharpen

phases:
main:
actions:
- blade: { school: fire, target: p1, enchant: required }

trap

- trap:
school: storm
target: boss

Fields: school, name, target, enchant.

trap takes a name where blade does not, because named traps like Feint are common enough to need it:

- trap: { name: Feint, target: boss, enchant: required }

shield

- shield:
school: ice
target: p1

Fields: school, target, enchant.

heal

- heal:
school: life
target: lowest_health_ally

Fields: target, school, enchant.

lowest_health_ally is nearly always the right target. self when you specifically mean yourself.

wand_hit

- wand_hit:
target: first

Field: target.

A chip of damage from your equipment. Specifically: of the castable item cards in hand whose spell type is damage, it takes the one with the lowest pip cost. That is your wand attack in practice, but it is chosen by "item card" rather than by name, so a pet or jewel attack card can win instead.

It is not guaranteed to be free, and it does not resolve at all when no item damage card is in hand — which makes it a good last line in an execute phase but a bad substitute for pass.

summon_minion

- summon_minion: {}

No fields. The empty mapping is required — YAML needs a value.

It takes the first castable card whose target type is "friendly minion", so it depends on having a minion spell in hand rather than on any configuration.

discard

- discard:
type: enchant
- discard:
school: moon

Fields: type, school.

Unlike every other action, discard does not check whether the card is castable — the whole point is to throw away cards you cannot or will not play. That also means - discard: {} with no filters matches the very first card in hand, which is almost never what you want. Always give it a type: or a school:.

Discarding clears hand space for a better draw. Common on a hitter that keeps drawing utility cards it will never cast:

phases:
cleanup:
priority: 5
when:
all:
- pips_above: 5
- round_above: 3
actions:
- discard: { school: moon }

Low priority so it only runs when nothing better is available.

Per-action guards

Any action can carry a when: clause, evaluated before it tries to resolve a card.

actions:
- blade: { school: fire, target: p1 }
when:
no_blade: { target: p1, school: fire }

- cast: { type: damage, school: fire }
when:
has_blade: { target: p1, school: fire }

The when: is a sibling of the action key inside the same list item, not nested under it. Actions with no when: always run.

Guard targets default to self in the scalar and boolean forms. To check someone else, use the object form with an explicit target:. Full detail in Phases → per-action guards.

One key per action

Each action object holds exactly one action key.

# wrong
- cast: { type: damage }
blade: { school: fire }

# right
- cast: { type: damage }
- blade: { school: fire }

The first form parses — both fields are known to the decoder — and the schema rejects it, so your editor will flag it, but the loader will not. At runtime exactly one wins, by a fixed internal order:

pass → flee → draw → cast → blade → trap → shield → heal → wand_hit → summon_minion → discard

So - cast: {...} plus blade: {...} in one item always runs the cast and silently drops the blade. Deterministic, but not a feature.

Ordering

Most specific first:

actions:
# 1. the named card I actually want
- cast: { name: 'Glowbug Squall', enchant: required }
# 2. any enchanted storm AOE worth the pips
- cast: { type: damage, school: storm, aoe: true, min_pips: 4, enchant: required }
# 3. any storm damage at all
- cast: { type: damage, school: storm }
# 4. free chip damage
- wand_hit: { target: first }

Inverting that list gives you a strategy that wand-hits every round.