Public: anyone can read this; the crew can change it.
The link you send a friend: a shared world is shared by pasting a URL #35
Check · Review · Land · Live done — Landed and live in production.
Pasted into a chat, drift now previews as the sea instead of a bare domain. `static/icon.svg` is a real icon (a wake, a mote, the bloom it carries) linked by content through `asset()`, the empty `data:,` is gone, and `GET /icon-180.png` gives a phone home screen a sized bitmap. `GET /card.png` is a 1200×630 card the app draws at boot in `src/card.ts` — the arena square, three wakes braided into on…
shipped production is serving it deploy feb7d92
Sign in to join this conversation.
Pasted into a chat, drift now previews as the sea instead of a bare domain.
static/icon.svgis a real icon (a wake, a mote, the bloom it carries) linked by content throughasset(), the emptydata:,is gone, andGET /icon-180.pnggives a phone home screen a sized bitmap.GET /card.pngis a 1200×630 card the app draws at boot insrc/card.ts— the arena square, three wakes braided into one lane, the bloom going through the gate on the rim — so it can never contain a player's name; both images are addressed by the hash of their own bytes (/card.png?v=0f2c8dd2) and immutable for a year there.src/png.tsturns pixels into a PNG in about a hundred lines (signature, IHDR, one deflated IDAT, adaptive row filters) onnode:zlib, which Bun ships: no dependency was added.src/meta.tsowns the head's social half androbots.txt. Every address it builds — canonical,og:url,og:image— comes frompublicOrigin, andHost,X-Forwarded-HostandForwardedare never read; a test drives/with five spoofed host headers and assertsevil.exampleappears nowhere in the page.robots.txtleaves the page crawlable and closes/events,/mcpand/__forge/, the other half of joining being a socket event. The head grew ~700 bytes and nothing in it blocks rendering:/is 3.7 KB and answers in under a millisecond warm, and the card is drawn just after the socket opens (~220 ms, once) so no request waits for pixels.Worth a look in the preview:
/card.pngitself, and the page source's head order — stylesheet first, the card tags after. Two things I chose not to do: the card carries no text, because rendering the rule sentence into a bitmap means shipping a font or a pixel alphabet, and every unfurler already showsog:titleandog:descriptionas real text beside the image; and there is no live render of the current round, which would leak who is playing and be blank most of the time.bun testis green (28 tests, including a round trip through the encoder checked against Bun's own CRC-32).🤖 Generated with Claude Code
Closes #28