The Peanut Gallery and table talk

A room's link without a seat is now a place in the gallery: a tokenless
view that withholds any gesture hidden from anyone at the table, counted
for the table and the lobby. Seated wizards can talk; each line is a
ledger line, shown in the rail and in the lobby, and the hall counts
what was said while you were away. The hall's pitch no longer says two
wizards.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0141G6xqLeNRYEtviLWSB5Up
This commit is contained in:
Eric Wagoner
2026-09-23 09:50:06 -04:00
co-authored by Claude Fable 5.1
parent 75c2dc9241
commit 8e7376d59a
19 changed files with 488 additions and 80 deletions
+13 -5
View File
@@ -2,7 +2,7 @@
import type { Duel } from '$lib/game/duel.svelte';
import { glyph } from '$lib/game/glyphs';
import { SPELL_BY_ID, type Hand } from '$lib/game/spells';
import type { HistoryEntry, WizardId } from '$lib/game/state';
import { hiddenFromViewer, type HistoryEntry, type WizardId } from '$lib/game/state';
let { duel }: { duel: Duel } = $props();
@@ -21,8 +21,8 @@
cells: Record<WizardId, Placed[]>;
}
/** You first, then the others in table order. */
const columns = $derived<WizardId[]>([duel.me, ...duel.others]);
/** You first, then the others in table order; the gallery sees the table as laid. */
const columns = $derived<WizardId[]>(duel.spectating ? duel.others : [duel.me, ...duel.others]);
function placed(who: WizardId, turn: number, phases: string[]): Placed[] {
const history = who === duel.me ? duel.you.history : duel.visible(who);
@@ -30,7 +30,7 @@
const out: Placed[] = [];
history.forEach((entry, index) => {
if (entry.turn === turn && phases.includes(entry.phase)) {
out.push({ entry, index, hidden: raw[index].hiddenFrom.includes(duel.me) });
out.push({ entry, index, hidden: hiddenFromViewer(raw[index].hiddenFrom, duel.me) });
}
});
return out;
@@ -110,7 +110,15 @@
{/each}
</tr>
{/each}
{#if drafting}
{#if drafting && duel.spectating}
<tr class="draft">
<td class="turn">{duel.turnNumber}</td>
{#each columns as who (who)}
<td class="cell foe"><span class="letter placeholder">?</span></td>
<td class="cell foe"><span class="letter placeholder">?</span></td>
{/each}
</tr>
{:else if drafting}
<tr class="draft" class:stopped={duel.timeStopped}>
<td class="turn">{duel.timeStopped ? '' : duel.turnNumber}{#if duel.timeStopped}<span class="rownote">time stop</span>{/if}</td>
{#each ['left', 'right'] as const as hand (hand)}