wtclaude 5dc14fa626
All checks were successful
PR Checks / prose (pull_request) Successful in 7s
PR Checks / template (pull_request) Successful in 34s
chore(ci): pin the kit to the Event System core, and go green (Phase 16b)
`ci/core-ref.json` moves from 66bb3b9a (MODULE_API 1.9.0, the engagement
cutover) to 655fbf3f -- the commit 1.10.0 reached `main` on, website#199.

This closes a red `main` rather than only dating the book. Chapter 5 landed in
#10 declaring `coreApi ^1.10.0` while this file still named a 1.9.0 core, and
`checkCoreApi` asserts EQUALITY, so the repo has been red on that check since it
merged. That was deliberate and said so in the PR, but the red belongs to the
cutover window and not to the repo; this is the commit that was always going to
close it, and it could not be written until the events sha existed on `main`.
Same shape Teams phase 11 used.

A pin move is a RUN, not an edit -- the template job checks this number and
tests the template against fakes, and a fake accepts what core refuses. So the
template's real declarations went through core's real registries at this exact
ref: the budget, the option source, the lease and the event action were all
accepted, and `apply()` accepted the set. Nothing else here needed to move;
`template/module.json` has declared ^1.10.0 since #10.

Verified against a core at this ref:

  checkCoreApi         coreApi ^1.10.0 matches the pinned core's 1.10.0
  registry rig         all four declarations accepted, apply() accepted
  template server      82 pass, 0 fail          check:imports OK
  template client      20 pass, 0 fail          check:externals OK, build OK
  prose checks         checkLinks, checkRenameSites, checkChapterPaths all OK
  their own tests      10 pass, 11 pass

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016wDDVXWMDz82WqE1i969r4
2026-09-09 19:50:40 -05:00

Runic Gateway — Integration Kit

How to put a game on a Runic Gateway site.

Runic Gateway is a website platform for game communities. Core knows nothing about any particular game: everything game-specific — routes, tables, pages, navigation, notifications — arrives as an installable module, and an operator installs one from an admin panel without building anything. module-uo is the first module and serves an Ultima Online shard. This kit is how you write the second one.

🚧 This is a draft

The kit is finished when someone outside this project builds a working module for a new game by following it alone, without reading core's source. That has not happened yet, so treat every chapter as untested on you. If you are that person: the places you get stuck are the most valuable thing this repo can receive — tell us, and please say where you left the kit and what you did next.


What you are building

Three things, and the kit is one book rather than a page in three repos because the reasons live in the joins between them:

# Part What it is
1 The website module A bundle core loads at boot: server routes, a schema fragment, a prebuilt client chunk, navigation. The bulk of the work, and the only part every module needs.
2 The sidecar A small service that owns the connection to your game server, and owns the durable copy of what the game said. Not optional — see below.
3 The game-side plugin Whatever runs inside your game and feeds the sidecar, without ever letting the sidecar stall the game.
   your game server  ──dials out──▶  your sidecar  ──HTTP + WS──▶  website core
   (plugin: bounded              (owns the socket,              (loads your module,
    queue, writer thread)         persists to its own            serves the pages)
                                  store, then forwards)

The website process never opens a connection to a game server. That is a rule in the contract (MODULE_API.md §2.7, MODULE_API_VERSION 1.4.0), not a style preference, and chapter 3 is mostly about why. The short version: the website is the internet-facing process and your game is not; the sidecar persists before it forwards, so a website that is down or mid-deploy loses nothing; and a game must never block on a web request. A game that genuinely delivers events on a surface of its own needs a thin sidecar, not none — but check that it delivers events rather than answering questions, because a channel built for an operator typing commands can only be polled, and polling turns "someone left at 14:02" into "the count was different at 14:03".

Start here

  1. The dry run — a complete module designed on paper for a second game, Rust, chosen for how little it shares with Ultima Online. Read it first. It is the shortest honest picture of the whole job, and it names the one thing the contract cannot do yet.
  2. template/ — a module that builds and loads, doing almost nothing. Copy it, rename it, and you have a running module before you have read a chapter.
  3. The bookbook/, five chapters, in the order the work happens. The first four are the job. The fifth is optional and comes after you have a working module: what to declare if you want a scheduled event on the website to be able to change your live world, and get it back afterwards.

The one rule this kit follows

It never re-specifies a contract. These documents are normative, and where the kit and one of them disagree, they win and the kit has a bug:

Authority For
MODULE_API.md Everything a module may do: module.json, ctx, the register* calls, the client registry, the UI kit, schema-fragment rules, the loader's obligations.
MODULE_SYSTEM.md Why the module system is shaped this way, and how a module is installed and removed.
link/PLAN.md + INTEGRATION.md The shard↔sidecar wire protocol, as one real sidecar implements it.
EVENTS.md The event system: what an event is, what a module declares, what core owns, and every rule chapter 5 explains the reasoning behind.

The kit teaches: the order to do things in, the reasoning, worked examples, and the mistakes that cost this project time. Where it must show a member list it quotes with a pointer rather than copying, because a guide that restates a contract diverges from it silently — and a reader who follows the divergent copy gets a module that fails validation for reasons the guide cannot explain.

What this repo contains

book/        the chapters
template/    a module that builds — copy this
scripts/     the checks CI runs over both

CI clones core at a pinned commit, asserts the version the template declares still matches that core's MODULE_API_VERSION, builds the template and runs its guards, checks every link in the book, holds the template's rename checklist against the template's own tree, and checks that every path a chapter names is still there. So a change to the contract breaks this repo's build loudly instead of leaving a chapter quietly wrong.

None of that can tell you whether a paragraph has become untrue about a file that still exists. That is a reviewer's job on every pull request, and a MODULE_API_VERSION bump is when it is owed in full.

Licence

GPL-3.0-or-later, like every Runic Gateway repo — see LICENSE.md. The template/ directory is meant to be copied and made yours; it carries the same licence, and so does anything derived from it.

Description
No description provided
Readme 611 KiB
Languages
JavaScript 100%