The table speaks plainer, and keeps its whimsy

Wording throughout the app, the server's messages and the engine's
refusals trades its stacked dashes for sentences, while the maze still
trusts you to honor its curses, the gallery still listens, and the
clockwork still learns its best tricks from the humans at the table.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Eric WagonerandClaude Opus 5.5 committed 2026-10-11 11:29:07 -04:00
1 parent ad23c83b8a
commit c64ff70ed4
25 files changed
+415 -414

No files matched your search

+3 -3
View File
@@ -21,8 +21,8 @@ function nameOf(id: string | null): string {
export function receiptFor(batch: readonly GameEvent[], e: GameEvent): Receipt | null {
if (e.type === "attackMissed") {
const why =
e.because === "invisible" ? `${e.defender} is invisible; the die sent it astray.`
: e.because === "shrink" ? `${e.defender} is shrunk; the die said miss.`
e.because === "invisible" ? `${e.defender} is invisible, and the die sent it astray.`
: e.because === "shrink" ? `${e.defender} is shrunk, and the die said miss.`
: `${e.defender} outran it.`;
return { title: `${nameOf(e.attackCardId)} misses ${e.defender}`, lines: [why] };
}
@@ -91,7 +91,7 @@ export function receiptFor(batch: readonly GameEvent[], e: GameEvent): Receipt |
const soak = x.soaks?.map((s) => `${s.what} soaks ${s.amount}`).join(", ");
lines.push(`${x.player}: ${x.lifeAfter + x.amount} → ${x.lifeAfter} life${soak ? ` (${soak})` : ""}`);
} else if (x.type === "damageImmune") {
lines.push(`${x.player} takes nothing — ${x.because}`);
lines.push(`${x.player} takes nothing (${x.because})`);
} else if (x.type === "lifeGained") {
lines.push(`${x.player}: ${x.lifeAfter - x.amount} → ${x.lifeAfter} life, reversed`);
} else if (x.type === "stonesDestroyed") {