← Building the Game — one site, the Builder, and the building blocks · all tasks

The Builder's read side, and the hub pages that show every block live

review priority 1 estimate L

building-the-game/002 · created 2026-09-03 · updated 2026-09-03 · blocked by building-the-game/001

What to do

Stand up builder/ (TypeScript, the director’s toolchain, its own package.json) as a separate process on the droplet: lor-builder.service, Caddy spellgrove.com/builder/* → its port, /etc/lor/builder.env (DATABASE_URL for lor_builder, GAME_DATABASE_URL as a read-only Postgres role on lor_game, CONTENT_CHECKOUT=/opt/lor/content). Bare http.createServer, no framework, the director’s test conventions (embedded Postgres).

Public reads, CORS *, ETag + 60 s memo (copy the pattern from game/director/src/publicMap.ts, do not import it): GET /builder/content/elements.json (evaluated from the checkout’s game/shell/elements.js), ground.json (the meanings, via game/shell/ground_rules.mjs), creatures.json (kinds parsed from game/world/entity_factory.gd, models listed from disk), world.json (authored fields from the game DB, public Areas only), areas/<slug>.json (properties, rules, portals, ground — public Areas only; private ones name/type/size/position).

Site: src/lib/builderApi.ts; pages building/elements.astro (element table + ground table, rows lower trigram, columns upper; a cell opens a card), building/creatures.astro, building/areas/[slug].astro; the /building landing shows live counts; /world balls link to Area pages; the nav’s soon entries become links.

The local hub (tools/hub-ui/) is the offline mirror: its routes and this task’s endpoints should agree on shapes.

Definition of done

builder/test/content.test.ts green; curl https://spellgrove.com/builder/content/elements.json returns the table; changing a name in the checkout shows on /building/elements with no site rebuild; the site build still passes.

Built (2026-09-03)

builder/ is live at spellgrove.com/builder/ (lor-builder.service, port 8090, database lor_builder, read-only role lor_builder_ro on lor_game, /etc/lor/builder.env), 13 tests green against embedded Postgres loading the real world through the director’s loader. The site’s /building landing shows live counts and the public areas; /building/elements draws the 64 twice (elements, ground) with a card per cell; /building/creatures; /building/areas/<slug> with the ground drawn from the database; the world map’s panel links to an area’s page. Checked in headless Chrome against the live Builder.

Interpretations worth a glance: portals whose far end is private are omitted rather than blanked; /health answers 503 when the game DB is unreachable; an elements.js edit shows within the 60 s memo, not instantly.

Review artifact: builder/README.md

View source in repository · also available as raw markdown.