The family list knows the hall: about panels link to gamehall.kestrelsnest.social, and a new game gets a card there
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
9f1358496d
commit
0244cffb4b
@@ -1,5 +1,6 @@
|
|||||||
{
|
{
|
||||||
"family": "Kestrel's Hall",
|
"family": "Kestrel's Hall",
|
||||||
|
"hall": "https://gamehall.kestrelsnest.social",
|
||||||
"games": [
|
"games": [
|
||||||
{
|
{
|
||||||
"slug": "wizwar",
|
"slug": "wizwar",
|
||||||
|
|||||||
@@ -10,7 +10,7 @@
|
|||||||
import Card from "./Card.svelte";
|
import Card from "./Card.svelte";
|
||||||
import Help from "./Help.svelte";
|
import Help from "./Help.svelte";
|
||||||
import { HELP_TABS, type HelpTab } from "./help-state";
|
import { HELP_TABS, type HelpTab } from "./help-state";
|
||||||
import { otherGames, type FamilyGame } from "./family";
|
import { loadFamily, type FamilyGame } from "./family";
|
||||||
import { summarizeMissed } from "./catchup";
|
import { summarizeMissed } from "./catchup";
|
||||||
import Replay from "./Replay.svelte";
|
import Replay from "./Replay.svelte";
|
||||||
import FxGallery from "./FxGallery.svelte";
|
import FxGallery from "./FxGallery.svelte";
|
||||||
@@ -29,8 +29,12 @@
|
|||||||
let name = $state(prefs.wizardName);
|
let name = $state(prefs.wizardName);
|
||||||
/** The other games of Kestrel's Hall, for the front page. */
|
/** The other games of Kestrel's Hall, for the front page. */
|
||||||
let family = $state<FamilyGame[]>([]);
|
let family = $state<FamilyGame[]>([]);
|
||||||
|
let hall = $state("");
|
||||||
$effect(() => {
|
$effect(() => {
|
||||||
void otherGames("wizwar").then((g) => (family = g));
|
void loadFamily("wizwar").then((f) => {
|
||||||
|
family = f.games;
|
||||||
|
hall = f.hall;
|
||||||
|
});
|
||||||
});
|
});
|
||||||
let joinCode = $state("");
|
let joinCode = $state("");
|
||||||
let claimPhrase = $state("");
|
let claimPhrase = $state("");
|
||||||
@@ -2568,7 +2572,7 @@
|
|||||||
</a>
|
</a>
|
||||||
<a class="about-link clips-link" href="/clips">watch clips from the labyrinth</a>
|
<a class="about-link clips-link" href="/clips">watch clips from the labyrinth</a>
|
||||||
{#if family.length}
|
{#if family.length}
|
||||||
<p class="family-line">Also in Kestrel's Hall:
|
<p class="family-line">Also in {#if hall}<a href={hall}>Kestrel's Hall</a>{:else}Kestrel's Hall{/if}:
|
||||||
{#each family as g, i (g.slug)}{i > 0 ? ", " : " "}<a href={g.url} title={g.pitch}>{g.name}</a>{/each}</p>
|
{#each family as g, i (g.slug)}{i > 0 ? ", " : " "}<a href={g.url} title={g.pitch}>{g.name}</a>{/each}</p>
|
||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
// body, the card library with proper entries, the house rulings, the
|
// body, the card library with proper entries, the house rulings, the
|
||||||
// story of the table, and the tally. Every section and card has a link
|
// story of the table, and the tally. Every section and card has a link
|
||||||
// a player can send; the desk remembers where the reader was.
|
// a player can send; the desk remembers where the reader was.
|
||||||
import { otherGames, type FamilyGame } from "./family";
|
import { loadFamily, type FamilyGame } from "./family";
|
||||||
import { cardDef } from "@wizwar/engine";
|
import { cardDef } from "@wizwar/engine";
|
||||||
import { tick } from "svelte";
|
import { tick } from "svelte";
|
||||||
import Card from "./Card.svelte";
|
import Card from "./Card.svelte";
|
||||||
@@ -130,8 +130,12 @@
|
|||||||
});
|
});
|
||||||
/** The other games of Kestrel's Hall, for the about page. */
|
/** The other games of Kestrel's Hall, for the about page. */
|
||||||
let family = $state<FamilyGame[]>([]);
|
let family = $state<FamilyGame[]>([]);
|
||||||
|
let hall = $state("");
|
||||||
$effect(() => {
|
$effect(() => {
|
||||||
void otherGames("wizwar").then((g) => (family = g));
|
void loadFamily("wizwar").then((f) => {
|
||||||
|
family = f.games;
|
||||||
|
hall = f.hall;
|
||||||
|
});
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
@@ -318,7 +322,7 @@
|
|||||||
<a href="https://kestrelsnest.social" target="_blank" rel="noreferrer">kestrelsnest.social</a>.
|
<a href="https://kestrelsnest.social" target="_blank" rel="noreferrer">kestrelsnest.social</a>.
|
||||||
</p>
|
</p>
|
||||||
{#if family.length}
|
{#if family.length}
|
||||||
<h3>More games in Kestrel's Hall</h3>
|
<h3>More games in {#if hall}<a href={hall}>Kestrel's Hall</a>{:else}Kestrel's Hall{/if}</h3>
|
||||||
<ul class="family">
|
<ul class="family">
|
||||||
{#each family as g (g.slug)}
|
{#each family as g (g.slug)}
|
||||||
<li><a href={g.url}>{g.name}</a>: {g.pitch} <span class="family-note">{g.players} players; {g.origin}.</span></li>
|
<li><a href={g.url}>{g.name}</a>: {g.pitch} <span class="family-note">{g.players} players; {g.origin}.</span></li>
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
// The other games of Kestrel's Hall, from the family list the kit keeps
|
// The other games of Kestrel's Hall, from the family list the kit keeps
|
||||||
// (family.json, one copy shipped with every game), so a player who liked one
|
// (family.json, one copy shipped with every game), so a player who liked one
|
||||||
// table can find the next. This game is left out of its own list.
|
// table can find the next, and the hall's front door. This game is left out
|
||||||
|
// of its own list.
|
||||||
|
|
||||||
export interface FamilyGame {
|
export interface FamilyGame {
|
||||||
slug: string;
|
slug: string;
|
||||||
@@ -11,13 +12,19 @@ export interface FamilyGame {
|
|||||||
origin: string;
|
origin: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function otherGames(self: string): Promise<FamilyGame[]> {
|
/** The family list: the hall's front door and every game but this one. */
|
||||||
|
export interface Family {
|
||||||
|
hall: string;
|
||||||
|
games: FamilyGame[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function loadFamily(self: string): Promise<Family> {
|
||||||
try {
|
try {
|
||||||
const res = await fetch('/family.json', { cache: 'no-cache' });
|
const res = await fetch('/family.json', { cache: 'no-cache' });
|
||||||
if (!res.ok) return [];
|
if (!res.ok) return { hall: '', games: [] };
|
||||||
const data = (await res.json()) as { games?: FamilyGame[] };
|
const data = (await res.json()) as { hall?: string; games?: FamilyGame[] };
|
||||||
return (data.games ?? []).filter((g) => g.slug !== self);
|
return { hall: data.hall ?? '', games: (data.games ?? []).filter((g) => g.slug !== self) };
|
||||||
} catch {
|
} catch {
|
||||||
return [];
|
return { hall: '', games: [] };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user