A credibility pass over the whole repo: the board's mechanics in board.ts, one copy of each helper and stylesheet rule, the kit's plumbing this game never used removed, and the ops scripts counting traffic through one parser
The engine and the bot no longer import each other: geometry, movement
and captures live in src/lib/game/board.ts and both use it. The escape
test, the four directions, the king's neighbours and the enumeration of
a side's moves each exist once; the tally counts by the named end
sentences rather than by regex over them; exports nobody imports are
exports no more. The tests pin the bot's opening move and the three-
beside-the-throne capture they named but never exercised.
In the client: .small, the word-as-button, the × that dismisses, the
visually-hidden rule and the frame of the reading pages are in app.css
once; the preferences panel and the report slip share one modal shape;
the room store drops the simultaneous-round fields this game never read
and gains seatEmpty and seatUnheld, which the lobby and the join page
read instead of three spellings of their own. The wire shapes for
reports and the tally are declared in view.ts for both sides. The
artwork component is re-indented for the top level it lives at.
On the server and in deploy: the plaintext-token fallback and its
migration script guarded ledgers this game never wrote; the seat line
now requires the hash and the start line the rules revision. The route
table lists every route. The visitors digest and the nightly rollup
count Caddy's log through deploy/traffic.py, and the rollup writes the
finished-games count it had been computing behind "and False". The
reports digest is one program, deploy/report-digest.ts, that
pull-reports.sh and the desk skill both use. The deploy README, the
visitors skill and the reports skill no longer describe a browser-only
game, a /play route or a rules text in docs/; conventions.md carries
the kit's Preferences and tally sections.
Kit-shared files touched, to port back: server/src/{index,rooms,store,
tally,reports}.ts, deploy/{deploy.sh,replay-ledgers.ts,pull-reports.sh,
traffic.py,report-digest.ts,*-rollup.sh,*-visitors.sh,*-pulse.sh},
src/lib/net/{client.ts,room.svelte.ts,view.ts}, Preferences.svelte,
ReportSlip.svelte, TableTalk.svelte.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GwFKMuQnPAEHJ5yA1q4orh
This commit is contained in:
co-authored by
Claude Fable 5.1
parent
6d041e3a63
commit
ee5690ebda
+7
-4
@@ -2,8 +2,8 @@
|
||||
|
||||
`src/lib/components/BoardArtwork.svelte` owns both palettes, surface filters,
|
||||
wear, grid, inlays and counters. `Board.svelte` supplies interactive state;
|
||||
`Hall.svelte` supplies an opening position from the game engine. Update the
|
||||
shared component to change either illustration and the game together.
|
||||
`Hall.svelte` supplies an opening position from the game engine. Edit the
|
||||
component and the game, the hall's still and the share card change together.
|
||||
|
||||
After editing the artwork, run:
|
||||
|
||||
@@ -15,5 +15,8 @@ This renders the same Svelte component into `static/board-copenhagen.svg` and
|
||||
`static/board-tablut.svg`, then regenerates `docs/og-card.svg` and the 1200 × 630
|
||||
`static/og.png`. Preview the share composition in `docs/og-card.html`.
|
||||
The share composition and copy live in `docs/render-art.mjs`. Commit generated
|
||||
assets with source changes. The export uses Sharp as a development dependency;
|
||||
it does not add any image-processing code to the shipped app.
|
||||
assets with source changes.
|
||||
|
||||
`docs/icon.html` draws the king's counter on the oak for the icons:
|
||||
`static/favicon.svg` is its drawing, and `static/apple-touch-icon.png` is the
|
||||
page screenshotted at 180 px.
|
||||
|
||||
@@ -68,6 +68,17 @@ README.
|
||||
variant, a side, a length): the game declares them in `GameSpec.options`,
|
||||
the hall renders them as selects, the room line records them, and
|
||||
`create` receives them. A game with one way to play declares none.
|
||||
- **Preferences** are what a browser remembers about its player: a panel
|
||||
opened from *preferences* in the hall and the masthead, kept in
|
||||
localStorage and nowhere else. The kit's own settings are motion (full or
|
||||
reduced, and the system's reduced-motion request counts too) and
|
||||
confirming a move before it is sent; a game declares more in
|
||||
`GameSpec.preferences` and the panel renders them. The hall also
|
||||
remembers the host's last table options as the next table's defaults.
|
||||
- **The tally** sits in the about panel: what the ledgers add up to
|
||||
(tables, games begun and finished, names seated, turns, time at the
|
||||
table, games with a bot, talk), counted on demand from the files and
|
||||
cached a minute. A game adds its own lines through `GameSpec.tally`.
|
||||
|
||||
## The engine
|
||||
|
||||
|
||||
+1
-1
File diff suppressed because one or more lines are too long
|
Before Width: | Height: | Size: 57 KiB After Width: | Height: | Size: 57 KiB |
+4
-3
@@ -6,6 +6,9 @@ import sharp from 'sharp';
|
||||
import { createGame } from '../src/lib/game/index.ts';
|
||||
const root = new URL('../', import.meta.url);
|
||||
const source = await readFile(new URL('src/lib/components/BoardArtwork.svelte', root), 'utf8');
|
||||
const app = await readFile(new URL('src/app.css', root), 'utf8');
|
||||
/** The site's design tokens, from the :root block of app.css. */
|
||||
const tokens = Object.fromEntries([...app.slice(0, app.indexOf('}')).matchAll(/(--[\w-]+):\s*([^;]+);/g)].map(m => [m[1], m[2]]));
|
||||
const compiled = compile(source.replace("'$lib/game'", "'../src/lib/game/index.ts'"), { generate: 'server', css: 'injected', filename: 'BoardArtwork.svelte' });
|
||||
const temporary = new URL(`.board-art-${process.pid}.mjs`, import.meta.url);
|
||||
try {
|
||||
@@ -21,10 +24,8 @@ try {
|
||||
const paletteSource = source.slice(source.indexOf('/* Copenhagen:'));
|
||||
const base = paletteSource.slice(0, paletteSource.indexOf('/* Tablut:'));
|
||||
const overrides = set === 'tablut' ? paletteSource.slice(paletteSource.indexOf('/* Tablut:'), paletteSource.indexOf('\n\t.artwork {')) : '';
|
||||
const values = Object.fromEntries([...`${base}\n${overrides}`.matchAll(/(--[\w-]+):\s*([^;]+);/g)].map(m => [m[1], m[2]]));
|
||||
const values = { ...tokens, ...Object.fromEntries([...`${base}\n${overrides}`.matchAll(/(--[\w-]+):\s*([^;]+);/g)].map(m => [m[1], m[2]])) };
|
||||
values['--piece-rim'] = values['--defender-rim'];
|
||||
values['--font'] = 'Georgia, serif';
|
||||
values['--frost'] = '#9ccbdd';
|
||||
svg = svg.replace(/:where\((\.[\w-]+)\)/g, '$1');
|
||||
svg = svg.replace(/var\((--[\w-]+)\)/g, (_, key) => values[key] ?? 'inherit');
|
||||
svg = svg.replace('</style>', ['attacker', 'defender', 'king'].map(kind => `.piece.${kind} .base{fill:${values[`--${kind}-rim`]}}.piece.${kind} .body,.piece.${kind} .turned{stroke:${values[`--${kind}-rim`]}}`).join('') + '</style>');
|
||||
|
||||
Reference in New Issue
Block a user