← Server architecture · all tasks

Stage 1 — director service + Postgres + protocol (no Godot)

done priority 1 estimate L

server-architecture/005 · created 2026-08-02 · updated 2026-08-03

What to do

Build the director service and its Postgres-backed persistence, with no Godot process involved yet — this stage proves the persistence model (overview.md’s “Persistence” section) and the message protocol shape (overview.md’s “Netcode” section) work, before any game engine is in the loop at all.

  1. Schema: a worlds table (at minimum: id, owner, member list or a join table, last_played_at — per the decided-from-day-one column even though nothing reads it yet — and whatever snapshot-state column/blob the world’s serialised state lives in) and whatever accounts/identity table backs the “no auth for MVP, but a real durable ID” decision.
  2. Director process: owns world lookup, membership checks, and (stubbed is fine at this stage, since there’s no Godot process yet to actually spawn) the world-instance lifecycle hooks. Runtime: agent’s choice between the two candidates overview.md names (Go, or Node/TS leaning per the stated tooling-reuse reason) — pick one, state which and why in the handoff note; this task is what actually answers the epic’s one remaining open question, in practice if not yet by updating the epic’s own prose.
  3. Protocol: the versioned, JSON, schema-defined message envelope described in overview.md’s “Netcode” section — implement it for whatever minimal message set this stage needs (create world, join world, world-state response), not the full in-game protocol yet.
  4. CLI test client: a script (not a GUI) that: creates/loads a world, confirms it hydrates from Postgres, and — this is the actual proof this stage exists to deliver — kill the director process, restart it, and confirm the world’s state (and membership) survived the restart intact. Also confirm membership routing actually rejects a non-member’s request to join a world they don’t belong to.
  5. Automated tests covering the above (schema round-trip, protocol envelope encode/decode, the restart-persistence property, the membership-rejection property).
  6. Write the handoff note: land-of-lor/pocs/multiplayer-poc/handoff/stage-1.md — what was built, which runtime was chosen and why, how to run the tests and the CLI test client, and what stage 2 can assume exists (the protocol shape, the schema, how to talk to the director).

Definition of done

Automated tests pass; the CLI test client demonstrably proves world-hydration-from-Postgres and survival-across-a-full-process-restart; the handoff note exists. Set this task’s own state to review once that’s true — do not mark it done yourself; that’s Kris’s call (or a session explicitly acting on his confirmation) once he’s verified it, per overview.md’s “Build plan” section. Marking done unblocks stage 2.

Where the work lands

land-of-lor/pocs/multiplayer-poc/ (per overview.md’s “Where PoC code lives”).

Docs to read first

server-architecture/overview.md in full, especially “Persistence,” “Runtime” (director runtime candidates), and “Netcode” (protocol envelope, no direct-position messages). deliverables/004-server-setup-guide.md §4 for the Postgres shape this stage’s schema will eventually run against on the real droplet (this stage can run against a local/dev Postgres — it doesn’t need the droplet from server-instance to exist yet).

Status (2026-08-03)

State: done. Kris personally ran npm test and npm run test-client in land-of-lor/pocs/multiplayer-poc/director/ on 2026-08-03: all tests passed, including the 9 test-client checks. This is his explicit confirmation per the epic’s build-plan gating rule — Stage 2 (006) is unblocked.

Director runtime: Node/TypeScript — decided directly by Kris on 2026-08-03 (not an agent assumption this time; this was the epic’s one open question and he closed it explicitly before this task was picked up). overview.md’s “Runtime” section and “Key open questions” are updated accordingly.

Built: land-of-lor/pocs/multiplayer-poc/director/ — a Node/TS + ws + pg + zod director service, a Postgres schema (accounts, worlds, world_members), a versioned JSON message envelope, 17 passing automated tests (npm test, includes a real SIGKILL + process-restart persistence test and a membership-routing test), and a headless CLI test client (npm run test-client) that proves all three of the stage’s verification bullets end-to-end with no human interaction. Local Postgres for dev/test is provided by the embedded-postgres devDependency (a real Postgres binary run userspace, no root needed) — the production code only ever talks to DATABASE_URL and doesn’t know or care that it’s this vs. the droplet’s real apt-installed Postgres.

Full detail: land-of-lor/pocs/multiplayer-poc/handoff/stage-1.md.

Assumptions

View source in repository · also available as raw markdown.