The clockwork minds the pit, the curse, and the shadow (GDCN)
Kestrel's archmage berserker dug a pit at the far mouth of a warp, then tried to walk through that mouth seven times: each stride landed on its own pit with a thornbush beyond, the maze bounced it back and charged the stride, and on the seventh it rolled the 1 and fell in. Cursed with SLOW DEATH at seven life, it kept drawing two cards a turn at a point apiece, raised a SHADOW that drinks a point a turn, and bled to death in three turns. The path search now refuses a pit it cannot leap beyond — the same test the maze applies — whether the pit is a waypoint or the goal. Under SLOW DEATH the end-of-turn draw keeps four life in hand and draws nothing when it cannot; while bleeding, or at six life or less, no SHADOW is raised. Three tests pin them. The chronicle tells the bounce as what it was: "leaps the pit — nothing to land on beyond it — and teeters back", not a blind blunder into a wall; and the shadow's last drink no longer trails a zero-damage line. Brain and chronicle changes only, ungated; 83 ledgers replay. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Jm2auWk6RP71CjaAb4FMoG
This commit is contained in:
co-authored by
Claude Fable 5.1
parent
b92016db51
commit
0750fe3f21
@@ -51,6 +51,9 @@ export function humanize(e: GameEvent): string | null {
|
||||
if (e.fullyStopped) return `The attack is completely stopped.`;
|
||||
return null; // the damaged event tells the story
|
||||
case "damaged": {
|
||||
// The shadow's last drink is told by its own line; the bookkeeping
|
||||
// blow that follows it has nothing to add.
|
||||
if (e.amount === 0 && e.source === "shadow upkeep") return null;
|
||||
const soak = e.soaks?.map((s) => `${s.what} soaks ${s.amount}`).join(", ");
|
||||
return `${e.player} takes ${e.amount} damage (${e.source}${soak ? ` — ${soak}` : ""}) — ${e.lifeAfter} life left.`;
|
||||
}
|
||||
@@ -126,7 +129,9 @@ export function humanize(e: GameEvent): string | null {
|
||||
case "cardDisplayed": return `${e.player} displays ${cardDef(e.card.cardId).name}.`;
|
||||
case "lifeTraded": return `${e.player} burns ${e.points} life for speed!`;
|
||||
case "castAroundCorner": return `The spell bends around the corner!`;
|
||||
case "moveBumped": return `${e.player} blunders into a wall!`;
|
||||
case "moveBumped": return e.why === "pit"
|
||||
? `${e.player} leaps the pit — nothing to land on beyond it — and teeters back.`
|
||||
: `${e.player} blunders into a wall!`;
|
||||
case "attackMisdirected": return e.newTarget
|
||||
? `${e.attacker}'s blind attack veers off — and hits ${e.newTarget}!`
|
||||
: `${e.attacker}'s blind attack flies off into the darkness.`;
|
||||
|
||||
Reference in New Issue
Block a user