All checks were successful
PR checks / checks (pull_request) Successful in 1m13s
Twenty pages completing the tree section 10 planned: Modules (8), Architecture
(5) and Reference (7). Four decisions, D38-D41, recorded in PLAN.md section 10.
D39 is the one that shaped the phase. Section 1 forbids re-specifying a
contract, and a Reference section is exactly where that rule is most tempting to
break, so the line is drawn at names: every environment variable, config key,
installer command, visibility rung and canonical document is listed with one
terse line saying what it is FOR, while shapes, semantics and every "why" stay
in the canonical document.
That is only safe because the names are checked. checkReference.mjs compares six
enumerations against the repositories that own them, over the Gitea API, as set
comparisons in BOTH directions -- and the second direction is the one that earns
its keep, because a reference page does not usually rot by describing something
that vanished, it rots by quietly not mentioning what was added since.
The check went green on its first run, which is the least trustworthy possible
outcome, so it was verified by breaking it: seven mutations, all caught. The one
worth keeping is the visibility ladder REORDERED with its membership unchanged
-- it is a security boundary, and a set comparison alone would have passed it.
D41 turns plannedSidebar from a checklist into a checked invariant, and finding
out why was the phase's first defect: it had already drifted, because phase 7
added the Content page under D37 and never updated the list. Nothing failed,
because nothing read it. checkSidebar.mjs now asserts the two trees agree on
groups, labels and order -- order because the order of Getting started IS the
installation path.
Two more things the writing found. PLAN.md's page count was wrong and had been
since section 10 was written ("roughly 38, 37 planned" for a tree of forty).
And module.json's `mounts` and the SPA's paths are different mechanisms that no
single document stated plainly -- module-uo declares admin: ["/shard",
"/uo-link"] while its screen lives at /admin/uo/link, because API routes are
deliberately NOT namespaced while SPA routes are. That is precisely the
distinction the installer got wrong in v0.1.0, and it now has a named home.
D40: the docs link to /architecture/'s drawn diagrams rather than importing
them. Those components carry marketing chrome and depend on diagram.css, which
Starlight does not load; the docs use text diagrams, which paste into an issue.
npm run verify green: 40 pages across 5 groups agree with plannedSidebar, 2390
internal links resolve, 123 repository links point at a branch, 19 facts, 59
quickstart checks, 22 reference enumerations, astro check 0 errors, 36 tests.
Co-Authored-By: Claude <noreply@anthropic.com>
108 lines
5.0 KiB
Plaintext
108 lines
5.0 KiB
Plaintext
---
|
|
title: The Integration Kit
|
|
description: The instruction book for putting a different game on the platform — four chapters, a buildable template, and an honest account of its status.
|
|
---
|
|
|
|
import { Aside } from '@astrojs/starlight/components';
|
|
|
|
The [Integration
|
|
Kit](https://gitea.whitlocktech.com/RunicGateway/Integration-kit) is a separate repository
|
|
whose entire job is teaching someone **outside this project** how to put a different game on
|
|
the platform.
|
|
|
|
<Aside type="caution" title="The kit describes itself as a draft, and so do we">
|
|
In its own words: *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.*
|
|
|
|
We are not going to describe it as finished before that happens. If you are the person who
|
|
tries it, the places you get stuck are the most valuable thing the repository can receive —
|
|
[open an issue](https://gitea.whitlocktech.com/RunicGateway/Integration-kit/issues) saying
|
|
where you left the kit and what you did next.
|
|
</Aside>
|
|
|
|
## What it covers
|
|
|
|
Three things, because the reasons live in the joins between them:
|
|
|
|
```
|
|
your game server ──dials out──▶ your sidecar ──HTTP + WS──▶ website core
|
|
(plugin: bounded queue, (owns the socket, (loads your module,
|
|
writer thread) persists, then forwards) serves the pages)
|
|
```
|
|
|
|
| Part | What it is |
|
|
|---|---|
|
|
| **The website module** | A bundle core loads at boot. The bulk of the work, and the only part every module needs |
|
|
| **The sidecar** | A small service owning the connection to your game server, and the durable copy of what the game said. **Not optional** |
|
|
| **The game-side plugin** | Whatever runs inside your game and feeds the sidecar, without ever letting the sidecar stall the game |
|
|
|
|
## The four chapters
|
|
|
|
| # | Chapter | What it covers |
|
|
|---|---|---|
|
|
| 1 | Your first module in twenty minutes | Copy the template, rename it, build it, install it, see a page. No theory |
|
|
| 2 | The website module | `module.json`, `register(ctx, api)`, the schema fragment, the client chunk, packaging, and what a module must never do |
|
|
| 3 | The sidecar | Why the website never talks to a game server, what "persist before you forward" means, and what a *thin* sidecar is |
|
|
| 4 | The game-side plugin | The least code and the highest stakes: never block the game thread |
|
|
|
|
Before any of them, the kit points at the [Rust dry
|
|
run](https://gitea.whitlocktech.com/RunicGateway/docs/src/branch/main/modules/rust-dryrun.md)
|
|
— a complete module designed on paper for a second game, and the shortest honest picture of
|
|
the whole job.
|
|
|
|
## The template is built, not just quoted
|
|
|
|
Chapters 1 and 2 quote `template/`, a real module that CI builds against a pinned core. The
|
|
code in those chapters is **a tree that is proved rather than prose that looks like one**.
|
|
|
|
Chapters 3 and 4 cite `uo-link` and `servuo-plugins` by file and identifier rather than by
|
|
line number, deliberately: those repositories move for their own reasons, and a line number
|
|
in a book is wrong the moment they do.
|
|
|
|
## The kit never re-specifies a contract
|
|
|
|
This is its governing rule, and it is the same one this site follows.
|
|
|
|
> Nothing in these chapters is normative. Where a chapter and one of these documents
|
|
> disagree, the document is right and the chapter has a bug.
|
|
|
|
| Authority | For |
|
|
|---|---|
|
|
| `MODULE_API.md` | Everything a module may do |
|
|
| `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 game ↔ sidecar wire protocol, as one real sidecar implements it |
|
|
|
|
The chapters teach the order to do things in, the reasoning, and **the mistakes that cost
|
|
this project time**.
|
|
|
|
## The pin that forces a re-read
|
|
|
|
`ci/core-ref.json` pins the exact core commit the kit is written against, and CI asserts
|
|
that the version `template/module.json` declares **equals** that core's
|
|
`MODULE_API_VERSION`.
|
|
|
|
Equality, not "satisfies". That is the mechanism, not a bug: a contract bump in the website
|
|
repository is *meant* to turn the kit red, so that someone re-reads the chapters before the
|
|
pin moves.
|
|
|
|
<Aside type="note" title="It has already earned its keep">
|
|
Writing the chapters against 1.6.0 found that core's inverted-slot fills named three of
|
|
`module-uo`'s slots **literally** — so the mechanism worked for that one module and silently
|
|
did nothing for any other game, producing an empty page with nothing logged.
|
|
|
|
That is exactly the class of defect a book written for an audience outside this org exists
|
|
to catch, and it was fixed in core before the pin moved.
|
|
</Aside>
|
|
|
|
## Running its checks
|
|
|
|
Dependency-free Node scripts, from the repository root — which is also how a reader runs
|
|
them:
|
|
|
|
```bash
|
|
node scripts/checkLinks.js # every relative link resolves; no commit permalinks
|
|
node scripts/checkRenameSites.js # the rename checklist matches the template tree
|
|
node scripts/checkChapterPaths.js # every path a chapter names in backticks still exists
|
|
```
|