Targeting
Every action that touches a participant accepts a target:. When omitted, the strategy's
targets.default_enemy or targets.default_ally is used, depending on what the spell does.
Selectors
| Selector | Picks |
|---|---|
first | The first live enemy in turn order |
boss | The first live boss, falling back to the first live enemy |
lowest_health | The live enemy with the least health |
highest_health | The live enemy with the most health |
most_pips | The live enemy with the most pips |
random | A random live enemy |
self | You |
lowest_health_ally | The most hurt participant on your team — which can be you |
minion | The first minion on your team |
p1, p2, … | The participant owned by that client alias |
Three behaviours that are not obvious from the table:
boss is not a filter, it is a preference. In a fight with no boss it quietly targets the
first live enemy. A phase that should only run against bosses needs
when: { boss_present: true } — the target alone will not hold the line.
An unrecognised selector does not fail. Anything the runner does not know — a typo, a
plausible-sounding invention like weakest — falls through to the first live enemy. The loader
never checks target strings; only the schema does, in your editor. This is the strongest single
argument for wiring the schema up.
self is not always honoured. If the matched card cannot be aimed at its caster, the card
is still cast, just without an explicit target. Only alias targets cause the action to be
skipped when they cannot resolve.
target: is ignored entirely for AOE spells and for anything that does not take a target, so
you can leave it off those actions.
Defaults
targets:
default_enemy: boss
default_ally: lowest_health_ally
default_enemy accepts first, boss, lowest_health, highest_health, most_pips,
random. default_ally accepts self, lowest_health_ally, minion, or a client alias.
Setting default_ally: p2 in a support strategy means every buff lands on the hitter without
repeating target: p2 on every action:
targets:
default_ally: p2
default_enemy: boss
phases:
main:
actions:
- blade: { school: fire } # goes to p2
- trap: { school: fire } # goes to boss
Client aliases
p1, p2, p3, … refer to the aliases assigned when clients are hooked by the console's
hook command. As a target selector, an alias resolves to that client's participant in the
current duel and targets it directly.
The alias-to-participant table is populated by the console and by nothing else. On the desktop
app's trainer it is empty, so every action with an alias target is skipped, every round,
with no error. A targets: { default_ally: p2 } block does the same thing to every
ally-targeting action in the file.
If your strategy has to run in the desktop app, express the same idea with self,
lowest_health_ally, or a per-member targets default, and give each character its own member.
Full comparison: which host is running
it.
If the alias is not in the fight, the action is skipped rather than hitting the wrong
participant. That is the behaviour you want — a support strategy that buffs p1 should do
nothing when p1 is not in this duel, not blade a random monster. It is also the only selector
that behaves this way; every other one has a fallback.
Aliases only resolve for ally-facing cards. The card being aimed must be one the game
allows you to cast on yourself or a teammate. Pointing an alias at an attack — cast: { type: damage, target: p1 } — never resolves, and the action is skipped every round. Use boss,
first, or lowest_health for damage.
Alias targeting works with cast, blade, trap, shield, and heal, subject to that rule.
- blade: { school: fire, target: p1, enchant: required }
- trap: { school: fire, target: boss }
- heal: { school: life, target: p2 }
Matching targets to spells
The runner does not stop you aiming a heal at the boss. Nothing validates that the target makes sense for the spell, because "sensible" depends on the card.
| Spell kind | Sensible targets |
|---|---|
| Enemy damage | boss, first, lowest_health, most_pips |
| AOE damage | Any — target: is ignored outright for AOE spells |
| Heal | lowest_health_ally, self, p1 |
| Self-buff | self |
| Buff for your hitter | p1, p2 |
| Trap / debuff | boss, lowest_health |
| Shield | self, lowest_health_ally, an alias |
lowest_health targets an enemy; lowest_health_ally targets an ally. Confusing the two
produces a strategy that heals the monster you are trying to kill.
lowest_health_ally ranks over your whole team, and you are on your team — so on a solo
character it is always you, and in a group it picks you whenever you are the most hurt. That is
usually the right behaviour for a heal, but it is not the same as "somebody else".
Picking an enemy selector
boss for anything with a boss. Concentrating damage is almost always right, and
boss_present: true lets you scope a whole phase to boss fights.
lowest_health to finish things off. Killing a monster removes a whole attack per round,
so clearing the nearly-dead one beats spreading damage.
most_pips against enemies building toward something large. Interrupting the one about to
cast beats hitting the one that just spent its pips.
first when order does not matter and you want determinism.
random rarely. It makes behaviour hard to reproduce when you are debugging a strategy.
Group play
A two-character setup where p1 hits and p2 supports. This whole pattern is console-only, because it turns on alias targeting:
# p2's strategy
name: support-fire
clients: [p2]
targets:
default_ally: p1
default_enemy: boss
enchant:
blade: { prefer: sharpen }
trap: { prefer: potent }
fallback: pass
phases:
main:
priority: 75
actions:
- blade: { school: fire, target: p1, enchant: required }
when:
no_blade: { target: p1, school: fire, enchanted: true }
- trap: { name: Feint, target: boss, enchant: required }
when:
no_trap: { target: boss, enchanted: true }
- heal: { school: life, target: lowest_health_ally }
when:
any_ally_health_below: 40
- pass
The guards mean each buff is applied once and reapplied only if it comes off. pass at the
end keeps the support character from wasting pips on chip damage when the board is already
set.
Scoping a strategy to clients
clients: at the top level restricts which clients may run the strategy at all. This is
different from target:, which chooses who a spell lands on.
name: leader-fire
clients: [p1]
phases:
main:
actions:
- cast: { type: damage, school: fire, target: boss }
name: grouped-support
clients: [p2, p3]
phases:
main:
actions:
- blade: { school: balance }
Aliases must match p<number> — wizard-1 is a load error. They are lowercased and
deduplicated during validation. Omit clients: entirely and the strategy applies to every
hooked client.
Clients not listed are left completely alone, not passed. So running leader-fire with
clients: [p1] means p2 does nothing at all rather than passing every round.
Like alias targeting, this is enforced by the console only. The desktop app's trainer runs a
strategy against whichever client its automation step names and never reads clients:.
For several characters that need genuinely different behaviour, one file with a members:
block is usually better than several files. See Teams.