Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01E14m6SuuY6i1vASFeGDBeY
133 lines
8.1 KiB
Markdown
133 lines
8.1 KiB
Markdown
# 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.
|
|
|
|
In the week before each monthly forced wipe, Runic Gateway checks every new Rust staging build (PLAN.md stage
|
|
9c, the staging drill), so a RunicNPC release that needs fixing is usually out before the update is.
|