The clockwork reads absorb's fine print

An automaton answered NO SPELL with an Absorb — which "has no effect
on duration-based spells." Afflictions sat outside the price table
and drew the phantom two-point default, tripping the point-soaking
rungs. An affliction's weight is now its duration, and the two
counters that touch only points — ABSORB and REVERSE — stand aside
for it, leaving the ones that genuinely bite durations: full shield,
remove curse, blunt, reflection, shieldstone numbers. Pinned: under
NO SPELL with both in hand, the bot blunts, never absorbs.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Eric Wagoner
2026-08-17 13:27:14 -04:00
co-authored by Claude Fable 5
parent adf463effa
commit ea3b9e5bd6
2 changed files with 25 additions and 9 deletions
+9 -4
View File
@@ -315,16 +315,19 @@ function respond(view: GameView, style: AutomatonStyle, tier: TierTraits): Comma
return { type: "pass" };
}
// An affliction's weight is its duration, not points it does not carry.
const incoming = stack.attackCard
? attackId === "stone-dead"
// NUMBER times the stones in the victim's hand — our hand.
? (stack.numberValue ?? 1) * view.yourHand.filter((c) => STONES.has(c.cardId)).length
: (atk ? atk.base + (atk.perNumber ? stack.numberValue ?? 1 : 0) : 2)
: affliction
? Math.max(2, stack.numberValue ?? 2)
: (atk ? atk.base + (atk.perNumber ? stack.numberValue ?? 1 : 0) : 2)
: 1;
if (stack.kind === "spell") {
// REVERSE turns the biggest blasts into a meal.
// REVERSE eats points; a pure duration offers it nothing.
const reverse = find("reverse");
if (reverse && incoming >= 4 - flinch) return { type: "counteract", instanceId: reverse.instanceId };
if (reverse && !affliction && incoming >= 4 - flinch) return { type: "counteract", instanceId: reverse.instanceId };
// ABSORB SPELL steals the good ones for later.
const absorbSpell = find("absorb-spell");
if (absorbSpell && incoming >= 3) return { type: "counteract", instanceId: absorbSpell.instanceId };
@@ -342,8 +345,10 @@ function respond(view: GameView, style: AutomatonStyle, tier: TierTraits): Comma
const half = find("reflection");
if (half && incoming >= 3) return { type: "counteract", instanceId: half.instanceId };
}
// ABSORB soaks points only ("no effect on duration-based spells");
// BLUNT and the stones work on durations too.
const absorb = find("absorb");
if (absorb && incoming >= 2 - flinch && incoming <= 3) return { type: "counteract", instanceId: absorb.instanceId };
if (absorb && !affliction && incoming >= 2 - flinch && incoming <= 3) return { type: "counteract", instanceId: absorb.instanceId };
const blunt = find("blunt");
if (blunt && incoming >= 2 - flinch) return { type: "counteract", instanceId: blunt.instanceId };
// The berserker shares its pain out of spite.