docs(runicnpc): stage 9b built; INSTALL and COMMANDS; RunicNPC required (D315, D316)
- runicnpc/PLAN.md: 9b built and measured; D315 (the performance check records today's cost, the warning says it, idle overhead is runicnpc-rust#13) and D316 (the picker keeps Rust's own; a step on a server without RunicNPC is refused on save). - runicnpc/INSTALL.md (new): requirements, the installer and egg, by hand without Runic Gateway, Kits and ZoneManager reported not installed, its files, the cost warning with stage 9's numbers, caps, and after a Rust update. - runicnpc/COMMANDS.md (new): every /rnpc verb and console command with its permission, options and defaults, and how to read rnpc.status. - rust-link/INSTALL.md: RunicNPC is required; the installer refuses a bundle without it and doctor fails. (The plan named modules/rust/OPERATING.md, which is a verbatim uMod mirror; this is the operator guide that lists Kits.) - rust-link/PROTOCOL.md: §19.16, every NPC placement needs RunicNPC; no message changes shape. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01E14m6SuuY6i1vASFeGDBeY
This commit is contained in:
132
runicnpc/INSTALL.md
Normal file
132
runicnpc/INSTALL.md
Normal file
@@ -0,0 +1,132 @@
|
||||
# Installing RunicNPC
|
||||
|
||||
RunicNPC is Runic Gateway's own NPC plugin for Rust, on Oxide and Carbon. On a Runic Gateway server it is
|
||||
**required**: every NPC an event places is RunicNPC's, Rust's own scientists included (D310). It also runs on any
|
||||
Rust server on its own, driven by its `/rnpc` commands and by other plugins through its API.
|
||||
|
||||
Every command is in [COMMANDS.md](COMMANDS.md), the API is in [API.md](API.md), and the design of record is
|
||||
[PLAN.md](PLAN.md).
|
||||
|
||||
## What it needs
|
||||
|
||||
| | |
|
||||
|---|---|
|
||||
| **Oxide 2.0.7726 or Carbon 2.0.259**, or newer | The builds it was tested on. Its release manifest states them, and the installer checks them. |
|
||||
| **[Kits](https://umod.org/plugins/kits)** | **Required.** A profile equips its NPCs with Kits kits, and RunicNPC declares `// Requires: Kits`, so neither framework loads it without Kits. |
|
||||
| **[ZoneManager](https://umod.org/plugins/zone-manager)** | Optional. Only a tether (`tether=` on a placement, or an event's "keep inside the zone") uses it. |
|
||||
|
||||
**Kits and ZoneManager are reported, never installed.** The installer and `doctor` say when either is missing, and
|
||||
you install them from uMod. Runic Gateway does not fetch third-party plugins.
|
||||
|
||||
**Do not reload Kits while an event runs.** RunicNPC requires Kits, so both frameworks reload RunicNPC with it, and
|
||||
every NPC it had spawned is gone. Placements come back on their own; an event's NPCs do not (D283).
|
||||
|
||||
## On a Runic Gateway server
|
||||
|
||||
There is nothing to do by hand. RunicNPC is part of the Rust **bundle**, the exact set of releases CI has checked
|
||||
together, beside the bridge plugin and the sidecar:
|
||||
|
||||
- **The installer** (`install --game rust`, `update --game rust`) places `RunicNPC.cs` beside the bridge, checked
|
||||
against the bundle's checksum. It refuses a bundle without RunicNPC. `doctor --game rust` fails when RunicNPC is
|
||||
missing or was never installed, and warns when the file was edited by hand. `uninstall` removes `RunicNPC.cs`
|
||||
and keeps `data/RunicNPC/`. The installer's own guide is [../rust-link/INSTALL.md](../rust-link/INSTALL.md).
|
||||
- **The Pterodactyl egg** places it the same way on every install and reinstall.
|
||||
|
||||
Once the server has started, **Admin → Rust → Servers** shows the server as complete. A server without RunicNPC, or
|
||||
with a RunicNPC older than the bridge needs, reads "Incomplete" with the reason, and every Place NPCs step on it is
|
||||
refused with "needs RunicNPC". **Admin → Rust → NPC profiles** shows each server's RunicNPC version and API.
|
||||
|
||||
On such a server the website owns the NPC profiles and the faction table. It pushes them to RunicNPC, and the
|
||||
console commands that would edit them are refused. Placements stay on the server: they can be made in game with
|
||||
`/rnpc place` or from the site's map, and both see the same list.
|
||||
|
||||
## Without Runic Gateway
|
||||
|
||||
1. Download `runicnpc-<version>.tar.gz` and `SHA256SUMS` from the
|
||||
[releases](https://gitea.whitlocktech.com/RunicGateway/runicnpc-rust/releases), and check the tarball:
|
||||
`sha256sum -c SHA256SUMS`.
|
||||
2. Install Kits from uMod if the server does not have it.
|
||||
3. Copy `runicnpc/RunicNPC.cs` from the tarball into `oxide/plugins/` or `carbon/plugins/`. The framework compiles
|
||||
and loads it at once.
|
||||
4. In the server console: `rnpc.status`. It should say `navmesh=ready` (a fresh map builds it for several minutes
|
||||
after the first boot) and `swap fields: ... missing=- added=-`.
|
||||
|
||||
On its first load RunicNPC writes four example profiles (a raider, a camp guard, a sniper and the Juggernaut boss)
|
||||
and their kits into Kits' data file, so a fresh server has something to place at once. Grant `runicnpc.place` or
|
||||
`runicnpc.admin` to whoever places NPCs, then `/rnpc place raider` where you look.
|
||||
|
||||
**Do not create `data/RunicNPC/` yourself.** RunicNPC makes it on first load. A directory made from outside the game,
|
||||
for example in a panel's file manager, is not writable by the game.
|
||||
|
||||
## Its files
|
||||
|
||||
| File | What it holds | Who writes it |
|
||||
|---|---|---|
|
||||
| `plugins/RunicNPC.cs` | The plugin. | The installer, the egg or you. |
|
||||
| `config/RunicNPC.json` | Caps (below) and the spawn budget. | You. |
|
||||
| `data/RunicNPC/profiles.json` | The profiles and the faction table. | The website on a Runic Gateway server (`"managed": true`); otherwise `rnpc.profile` and `rnpc.faction`. |
|
||||
| `data/RunicNPC/placements.json` | The placements. | `/rnpc`, the API, and the website's map. |
|
||||
| `data/RunicNPC/routes.json` | The recorded routes. | `/rnpc path`. |
|
||||
| `data/RunicNPC/state.json` | Its own bookkeeping. | RunicNPC. |
|
||||
|
||||
After editing `profiles.json` or `routes.json` by hand, run `rnpc.reload`.
|
||||
|
||||
## The cost warning, and caps
|
||||
|
||||
**RunicNPC has no caps by default** (D227). Instead, every placement and every event step answers with what the
|
||||
server's RunicNPC NPCs cost, and `rnpc.status` ends with the same lines:
|
||||
|
||||
```
|
||||
RunicNPC: 100 NPC(s) on this server. Measured on a test server, they add about 3 ms to every server frame while
|
||||
idle with a player near enough to wake them, and about 0.5 ms once they sleep with nobody near. If all fight at
|
||||
once they add about 9 ms, and Rust's shared 2 ms AI budget then lets each react only every 3 s. ...
|
||||
```
|
||||
|
||||
What it means:
|
||||
|
||||
- **Idle NPCs are cheap, and sleeping ones cheaper.** NPCs that stand, wander or patrol with nobody to fight add a
|
||||
little to a frame. One with no player within its sleep distance (160 m by default) walks home and sleeps, and
|
||||
then costs about a sixth of what it did awake.
|
||||
- **Fighting NPCs hit Rust's AI budget before the frame rate.** All of Rust's human NPCs, its own scientists
|
||||
included, share `aithinkmanager.framebudgetms` (2 ms a frame). With many fighting at once, each one reacts less
|
||||
often. The server stays smooth, and the NPCs get slower to react.
|
||||
- **The figures are measured, not guessed.** Stage 9 measured the released NPC on both frameworks, on a 6000
|
||||
map, as what 100 add to the median server frame of the same session's empty server. Beside it is Rust's own
|
||||
scientist, unchanged but for RunicNPC's swap, measured the same day: fighting costs what Rust's own AI costs.
|
||||
|
||||
| 100 NPCs, over an empty server | RunicNPC on Oxide | RunicNPC on Carbon | Rust's scientist (Oxide / Carbon) |
|
||||
|---|---|---|---|
|
||||
| Idle, a player near enough to keep them awake | +2.7 to +2.9 ms | +1.5 ms | +1.0 / +1.0 ms |
|
||||
| Idle, asleep with nobody within 160 m | — | +0.5 ms | — |
|
||||
| Fighting 20 players | +7.2 ms | +9.0 ms | +7.5 / +8.0 ms |
|
||||
|
||||
The warning uses the worst of these, rounded up: 3 ms awake, 0.5 ms asleep and 9 ms fighting per 100. The awake
|
||||
figure on Oxide is higher than it should be and is being worked on
|
||||
([runicnpc-rust#13](https://gitea.whitlocktech.com/RunicGateway/runicnpc-rust/issues/13)). Your server's own
|
||||
figures depend on its CPU, its map and its players.
|
||||
|
||||
To cap them anyway, set any of these in `config/RunicNPC.json` and reload RunicNPC (0 means none):
|
||||
|
||||
| Key | Caps |
|
||||
|---|---|
|
||||
| `caps.total` | RunicNPC's NPCs on the server. |
|
||||
| `caps.perOwner` | NPCs of one owner: one placement, one event run, or one other plugin. |
|
||||
| `caps.perProfile` | NPCs of one profile. |
|
||||
| `caps.spawnsPerSecond` | How fast NPCs are spawned. |
|
||||
| `spawnBudgetMs` | Milliseconds of a frame the spawn queue may use (8 by default). One NPC takes about 5 ms to spawn, so a large placement is spread over frames instead of stalling one. |
|
||||
|
||||
A step or placement over a cap is refused with the cap named.
|
||||
|
||||
## After a Rust update
|
||||
|
||||
Rust's monthly update can change the scientist RunicNPC is built on. After the update:
|
||||
|
||||
1. **Wait for the navmesh.** `rnpc.status` says `navmesh=building` while Rust rebuilds it (about ten minutes on a
|
||||
large map). Placements wait for it and spawn when it is ready.
|
||||
2. **Check the swap.** `rnpc.status`'s `swap fields` line should end `missing=- added=-`. Anything else means Rust's
|
||||
scientist has changed since this RunicNPC was released: update RunicNPC (on a Runic Gateway server,
|
||||
`update --game rust` or an egg reinstall takes the current bundle).
|
||||
3. **Check the hooks.** A hook listed as `silent` long after the server has been played on may have been renamed.
|
||||
|
||||
Runic Gateway checks every new Rust staging build before it reaches the public branch (PLAN.md stage 9, the
|
||||
staging drill), so a RunicNPC release that needs fixing is usually out before the update is.
|
||||
Reference in New Issue
Block a user