Players can choose their own name

An inline editor in the standfirst; the name is remembered in the
browser, applied to the current duel, and used for every duel after.
The opponent is drawn from the list avoiding the player's name.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
Eric Wagoner
2026-09-22 15:48:47 -04:00
co-authored by Claude Fable 5.1
parent d40734590b
commit 3716f49bbb
2 changed files with 103 additions and 7 deletions
+31 -3
View File
@@ -98,9 +98,21 @@ function blankSets(): Record<SetName, Record<Hand, HandDraft>> {
return { main: { left: blankDraft(), right: blankDraft() }, haste: { left: blankDraft(), right: blankDraft() } };
}
function pickNames(): { A: string; B: string } {
const pool = [...NAMES];
const a = pool.splice(Math.floor(Math.random() * pool.length), 1)[0];
const NAME_KEY = 'wh:name';
export const NAME_MAX = 24;
function readName(): string {
try {
return (localStorage.getItem(NAME_KEY) ?? '').trim().slice(0, NAME_MAX);
} catch {
return '';
}
}
/** The player's chosen name if they have one, and an opponent who is not called the same. */
function pickNames(player = readName()): { A: string; B: string } {
const pool = NAMES.filter((n) => n.toLowerCase() !== player.toLowerCase());
const a = player || pool.splice(Math.floor(Math.random() * pool.length), 1)[0];
const b = pool[Math.floor(Math.random() * pool.length)];
return { A: a, B: b };
}
@@ -227,6 +239,22 @@ export class Duel {
}
}
/** Rename the player for this duel and every duel after it. An empty name goes back to a drawn one. */
setName(raw: string): void {
const name = raw.trim().slice(0, NAME_MAX);
try {
if (name) localStorage.setItem(NAME_KEY, name);
else localStorage.removeItem(NAME_KEY);
} catch {
// The name still applies to this duel.
}
const next = name || pickNames('').A;
if (next.toLowerCase() === this.foe.name.toLowerCase()) {
this.state.wizards[FOE].name = pickNames(next).B;
}
this.state.wizards[YOU].name = next;
}
/** Write the duel and the half-written turn to local storage. Reads everything it saves, so an effect can track it. */
persist(): void {
const bundle: SavedDuel = {