docs(runicnpc): stage 4 built and walked; protocol 13 §19.12; API 3

PROTOCOL.md §19.12: RunicNPC over the bridge — integrations.runicNpc, the
npc.profiles, npc.profiles.set, npc.placements and npc.placement commands and
their refusals, the npc.died, npc.health and npc.placement.changed frames,
world.place with a profile, attackerNpc and attackerProfile, the tally's
npcProfileKills, the four sidecar routes, and overlay.toml's runicnpc_api.

API.md: API 3 — RunicNpc_AddPlacement, RunicNpc_RenamePlacement,
RunicNpc_RespawnPlacement and OnRunicNpcPlacementChanged.

PLAN.md stage 4: what was built in five repositories, the walk on both rigs
row by row, what was not walked and why, and what building it found.

rust-link/INSTALL.md: RunicNPC as the bundle's third file, by hand, the egg,
doctor and uninstall.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01E14m6SuuY6i1vASFeGDBeY
This commit is contained in:
2026-09-30 08:45:21 -05:00
parent c6ba46d692
commit 2ad2043060
4 changed files with 208 additions and 10 deletions

View File

@@ -7,12 +7,13 @@ the design of record is [`../modules/rust/PLAN.md`](../modules/rust/PLAN.md) §3
## What this installs
Two components per Rust server, released together as a **bundle** — an exact pair CI has checked
speaks one protocol, never "the latest of each":
speaks one protocol, never "the latest of each" — and, from RunicNPC's stage 4, a third:
| Component | What it is | Released from |
|---|---|---|
| **The plugin** | `RunicGateway.cs`, one file that runs unchanged on Oxide and Carbon — and beside it, from protocol 13, the optional **ZoneManager helper** `RunicGatewayZones.cs` (PLAN_FIXES D181, D182), installed by default | [Rust-Plugins](https://gitea.whitlocktech.com/RunicGateway/Rust-Plugins/releases) |
| **The sidecar** | `rust-link-sidecar`, which the plugin dials on loopback and the website reaches over HTTP | [Rust-Link](https://gitea.whitlocktech.com/RunicGateway/Rust-Link/releases) |
| **RunicNPC** | `RunicNPC.cs`, Runic Gateway's NPC plugin ([`../runicnpc/PLAN.md`](../runicnpc/PLAN.md)), placed beside the bridge **when the bundle carries it**: from RunicNPC's stage 4, the latest RunicNPC release that answers the API the bridge needs (D224). Optional until RunicNPC's stage 9; it needs **Kits**, like the bridge | [runicnpc-rust](https://gitea.whitlocktech.com/RunicGateway/runicnpc-rust/releases) |
The game server opens no port for the bridge: the plugin is the client and the sidecar the
listener, on `127.0.0.1`. **One sidecar serves one Rust server.** A community running six servers
@@ -121,7 +122,8 @@ When you create a server from it:
**The install** downloads the sidecar, its launcher and the plugin from the bundle, checks each
against the bundle's checksum, and only then places them: the sidecar in `rust-link/`, the plugin in
`oxide/plugins/` or `carbon/plugins/`. Any mismatch fails the install with the reason, before
`oxide/plugins/` or `carbon/plugins/`. When the bundle carries RunicNPC, `RunicNPC.cs` goes beside the plugin
(its data directory is left for RunicNPC to make). Any mismatch fails the install with the reason, before
anything is placed.
**The first boot** prints, in the console, the token the sidecar generated — **once** — and a line
@@ -154,7 +156,10 @@ history, and the token is unchanged.
[`v2/rust/current.json`](https://gitea.whitlocktech.com/RunicGateway/installer/src/branch/bundles/v2/rust/current.json)
on the installer's `bundles` branch. It names the sidecar binary for your platform and the
plugin tarball, each with a `sha256`.
2. **Download and verify** both against those checksums (`sha256sum -c`, or `Get-FileHash`).
2. **Download and verify** both against those checksums (`sha256sum -c`, or `Get-FileHash`) — and, when
the bundle has an `npc` entry, RunicNPC's tarball too. Copy `runicnpc/RunicNPC.cs` from it into the same
plugins directory as the bridge. **Do not create `data/RunicNPC/` yourself**: RunicNPC makes it on first
load, and one made from outside the game (a panel's file manager) is not writable by it.
3. **The plugin:** copy `runicgateway-rust-plugin/RunicGateway.cs` from the tarball into
`oxide/plugins/` or `carbon/plugins/`, and every other `.cs` the tarball's `manifest.json` lists
in `files` beside it — from protocol 13 that is `RunicGatewayZones.cs`, which lets ZoneManager count a
@@ -220,9 +225,9 @@ With the installer:
| | |
|---|---|
| `doctor --game rust [--server-id <id>]` | Per server: the framework; whether the plugin file is still the one deployed; each helper deployed beside it, as a **warning** when missing or edited (the bridge runs without one, and the row says what that costs); that the plugin's config names this server; the required uMod plugins; the service; and `/health` through to **plugin connected**. A stopped server is a warning; a running one whose plugin never connected is a failure, printed with the framework versions the plugin is known good on |
| `doctor --game rust [--server-id <id>]` | Per server: the framework; whether the plugin file is still the one deployed; each helper deployed beside it, as a **warning** when missing or edited (the bridge runs without one, and the row says what that costs); RunicNPC, when the bundle carried it, the same way (without it the site's NPC profiles and placements and events' profile NPCs are off); that the plugin's config names this server; the required uMod plugins; the service; and `/health` through to **plugin connected**. A stopped server is a warning; a running one whose plugin never connected is a failure, printed with the framework versions the plugin is known good on |
| `update --game rust` | Moves the sidecar and every server's plugin to the current bundle, and restarts the sidecars. Always all servers together — they share one binary |
| `uninstall --game rust [--server-id <id>] [--purge]` | Removes the service and the plugin file. **Keeps the plugin's config** — it is the website's, and it names the server. `--purge` also removes the sidecar config (the token) and the database. Removing the last server removes the shared binary too |
| `uninstall --game rust [--server-id <id>] [--purge]` | Removes the service, the plugin file, its helpers and RunicNPC. **Keeps the plugin's config** and RunicNPC's `data/RunicNPC/` (an admin's placements and routes) — it is the website's, and it names the server. `--purge` also removes the sidecar config (the token) and the database. Removing the last server removes the shared binary too |
With the egg: reinstall to update (above); the console is the diagnosis.