docs(runicnpc): stage 3's design, D239–D242
The org lead answered stage 3's four questions on 2026-09-30: - D239: a roamer may stand on a player-built floor (Rust's mesh covers it a moment after it is built, stage 2), with a warning in the answer. §5, §8 and stage 10 now follow it; stage 2's open item is closed. - D240: routes are recorded point by point (record, point, undo, save loop|back, cancel), with nothing drawn on screen. - D241: placements made in game are named <profile>-<n>, renamable. - D242: /rnpc place and /rnpc here take key=value options in any order. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01E14m6SuuY6i1vASFeGDBeY
This commit is contained in:
@@ -4,7 +4,8 @@
|
||||
**Stage 0 closed 2026-09-30** (runicnpc-rust#1/#2, §9): v0.1.0 released and loaded on both rigs. D229–D230 were
|
||||
decided with it. **Stage 1 measured 2026-09-30** (§9): six answers on both rigs; D231 was decided with it.
|
||||
**Stage 2's design answered 2026-09-30:** D232–D238 (§0), which reshape stage 2 (§9). **Stage 2 built and tested
|
||||
2026-09-30** on both rigs (§9); its API is [API.md](API.md).
|
||||
2026-09-30** on both rigs (§9); its API is [API.md](API.md). **Stage 3's design answered 2026-09-30:** D239–D242
|
||||
(§0).
|
||||
|
||||
RunicNPC is Runic Gateway's own NPC plugin for Rust servers, in its own repository,
|
||||
[`RunicGateway/runicnpc-rust`](https://gitea.whitlocktech.com/RunicGateway/runicnpc-rust). It runs on Oxide and
|
||||
@@ -52,6 +53,10 @@ architectural or design decision is implemented.
|
||||
| **D236** | **Respawn is chosen per placement:** `each` (the default: every NPC returns its delay after its own death) or `group` (none return until all are dead, then all return together). | One fixed rule. |
|
||||
| **D237** | **A deleted profile leaves its placements waiting.** Their NPCs despawn; the placements are kept and shown as "profile missing" in game and on the site; they spawn again if the profile returns. | Refusing the delete; deleting the placements with it. |
|
||||
| **D238** | **A profile's shape** is §2's, as the org lead approved it: `names`, `kits`, `prefab`, `role`, `movement`, `health`, `damageDealt`, `damageTaken`, `aimCone`, `ranges`, `visionCone`, `sleepDistance`, `healthThresholds`, in `data/RunicNPC/profiles.json` with the `managed` flag. Placements and routes have their own files beside it; the optional caps (D227) are in the plugin's config. Stages 5–7 add their own sections. | A smaller stage-2 profile, combat values deferred to stage 5. |
|
||||
| **D239** | **A roamer may be placed wherever Rust's navmesh reaches, a player-built floor included, and the answer warns when it is one** ("this spot is on a player-built structure; if it is destroyed, the NPC falls back to the nearest navmesh"). Sentry-only stays the rule for a spot that is truly off the mesh. Stage 10 shrinks to pasted or custom prefabs and moving platforms (stage 2's finding). | Allowing it silently; keeping anything player-built sentry-only even where the mesh covers it. |
|
||||
| **D240** | **A route is recorded point by point:** `/rnpc path record <name>` starts it, `/rnpc path point` adds where the admin stands (checked against the navmesh; a bad point is refused with the reason), `/rnpc path undo` drops the last, `/rnpc path save [loop\|back]` writes it, `/rnpc path cancel` discards it. Nothing is drawn on screen (D216). | The same flow with the points drawn on screen; a point dropped every few metres as the admin walks. |
|
||||
| **D241** | **A placement made in game is named after its profile and a number** (`/rnpc place bandit` answers "Placed bandit-3"), and `/rnpc rename <id> <new>` renames it. `/rnpc near` lists the names. | Bare numbers; the admin naming every placement. |
|
||||
| **D242** | **`/rnpc place` and `/rnpc here` take `key=value` options in any order after the profile:** `count=`, `respawn=`, `mode=each\|group`, `move=wander\|monument\|route:<name>`, `radius=`. Anything left out takes the profile's default. | `/rnpc place bandit 3 300 group route:gate`; `/rnpc place` then `/rnpc set`. |
|
||||
|
||||
**Borrowing, not copying.** NpcSpawn states no licence at all, so its source grants us nothing and is read only as a
|
||||
description of *what* can be done in Rust. HumanNPC is MIT on uMod, which is GPL-compatible, but §1.2 rules out its
|
||||
@@ -290,10 +295,13 @@ permissions reach the site's permission manager through the inventory, like any
|
||||
|
||||
| Command | Does | Permission |
|
||||
|---|---|---|
|
||||
| `/rnpc place <profile> [count] [respawn]` | Places at the spot you are looking at, persistent | `runicnpc.place` |
|
||||
| `/rnpc here <profile> [count]` | The same, where you stand | `runicnpc.place` |
|
||||
| `/rnpc remove` | Removes the placement of the NPC you are looking at | `runicnpc.place` |
|
||||
| `/rnpc near [radius]` | Lists placements and live NPCs near you | `runicnpc.place` |
|
||||
| `/rnpc place <profile> [key=value ...]` | Places at the spot you are looking at, persistent, and answers with its name (D241). Options in any order (D242): `count=`, `respawn=` (seconds), `mode=each\|group`, `move=wander\|monument\|route:<name>`, `radius=` | `runicnpc.place` |
|
||||
| `/rnpc here <profile> [key=value ...]` | The same, where you stand | `runicnpc.place` |
|
||||
| `/rnpc remove [placement]` | Removes a placement and its NPCs: the one named, or that of the NPC you are looking at | `runicnpc.place` |
|
||||
| `/rnpc rename <placement> <new>` | Renames a placement (D241) | `runicnpc.place` |
|
||||
| `/rnpc near [radius]` | Lists placements (by name) and live NPCs near you | `runicnpc.place` |
|
||||
| `/rnpc path record <name>` · `point` · `undo` · `save [loop\|back]` · `cancel` | Records a route where you walk, point by point (D240) | `runicnpc.place` |
|
||||
| `/rnpc path list` · `delete <name>` | Lists or deletes routes; a placement on a deleted route waits, as for a deleted profile (D237) | `runicnpc.place` |
|
||||
| `/rnpc info` | The NPC you are looking at: profile, owner, health, target, state | `runicnpc.place` |
|
||||
| `/rnpc profiles` | The profiles this server has | `runicnpc.place` |
|
||||
| `rnpc.profile <create\|set\|delete> ...` (console) | Edits a profile on a standalone server; refused when the site manages them (D221) | `runicnpc.admin` |
|
||||
@@ -305,8 +313,11 @@ permissions reach the site's permission manager through the inventory, like any
|
||||
cost warning (D227): how many RunicNPC NPCs the server now has and what stage 1 measured that number to cost.
|
||||
|
||||
On the navmesh, the NPC roams, chases and fights
|
||||
normally. Off it (a roof, inside a base, a pasted structure), a **stationary** profile is placed and a roaming one
|
||||
is refused with the reason. An event step gets the same answer, as a blocked RaidableBases spot does (D208).
|
||||
normally, and that includes a player-built floor, which Rust's mesh covers a moment after it is built (stage 2).
|
||||
**On a player-built structure the placement is made with a warning** (D239): if the structure is destroyed, the
|
||||
NPC falls back to the nearest navmesh. Off the mesh (a pasted structure, a custom prefab), a **stationary** profile
|
||||
is placed and a roaming one is refused with the reason. An event step gets the same answer, as a blocked
|
||||
RaidableBases spot does (D208).
|
||||
|
||||
---
|
||||
|
||||
@@ -349,7 +360,8 @@ shipped no custom mesh. Where it does not reach, a profile is a sentry (§5).
|
||||
**Stage 10, only if needed:** a point graph recorded in game. An admin walks the route, `/rnpc mesh record <name>`
|
||||
samples it, and NPCs move between the points directly, as NpcSpawn's custom meshes do, for:
|
||||
|
||||
- pasted or player-built bases, and roofs;
|
||||
- pasted structures, and roofs the mesh does not reach (a player-built floor needs none: Rust's mesh covers it
|
||||
a moment after it is built, stage 2 and D239);
|
||||
- custom map prefabs Rust's mesh does not cover;
|
||||
- moving platforms, together with parenting.
|
||||
|
||||
@@ -479,8 +491,8 @@ boots load the saved `proceduralmap.<size>.<seed>.<n>.navmesh`. **Placements tha
|
||||
| A player-built floor 4 m up | **not on the mesh** in the frame it spawned; **on it 0.1–0.3 s later** (stage 2) | the same |
|
||||
| One check | 13.6 µs | 8.3 µs |
|
||||
|
||||
Monument roofs (Launch Site, Airfield, Trainyard, the warehouses) are mostly walkable. Player-built floors and
|
||||
roofs never are: that is §5's sentry rule, and stage 10.
|
||||
Monument roofs (Launch Site, Airfield, Trainyard, the warehouses) are mostly walkable. This stage read
|
||||
player-built floors and roofs as never walkable; stage 2 corrected that (the row above), and D239 follows from it.
|
||||
|
||||
**5. The cost (D227's numbers).** Seven 60 s phases on a field 400 m from any monument: a baseline, 1, 10 and 100
|
||||
of ours idle, the same 100 shooting 20 stand-ins (whose damage the harness zeroes, so none die), a fresh 100 set to
|
||||
@@ -584,7 +596,7 @@ What building it found:
|
||||
- **Rust's navmesh covers a new player-built floor in 0.1–0.3 s** (2–3 frames), on both rigs. Stage 1's "a
|
||||
player-built floor is never on the mesh" (Q4) sampled in the same frame the floor spawned, so it is wrong: a
|
||||
roamer can stand on a player-built floor a moment after it exists. §5's sentry rule, §8 and stage 10 were
|
||||
written on stage 1's reading. **Open for the org lead.**
|
||||
written on stage 1's reading; the org lead answered with D239, and those sections now follow it.
|
||||
- **Rust's navmesh sampler reaches further down than across.** A roamer asked to stand on a roof found the
|
||||
ground 4.7 m below. A roamer's spot must now be within 2 m, up or down, of the navmesh it is put on.
|
||||
- **A brain can think before Unity has started it.** For that moment it has no navigator, so RunicNPC leaves that
|
||||
@@ -596,12 +608,15 @@ What building it found:
|
||||
|
||||
### Stage 3 — In game
|
||||
|
||||
The chat and console commands (§5), their permissions, the navmesh placement check, respawn delays, and recording
|
||||
routes in game (`/rnpc path record`, then setting points, D234). A placement may name a movement override and a
|
||||
respawn mode (D233, D236).
|
||||
The chat and console commands (§5), their permissions, the navmesh placement check with D239's warning on a
|
||||
player-built structure, respawn delays, and recording routes in game point by point (D234, D240). Placements made
|
||||
in game are named after their profile and a number, and renamable (D241). `/rnpc place` and `/rnpc here` take
|
||||
`key=value` options, a movement override and a respawn mode among them (D233, D236, D242).
|
||||
|
||||
**Tested by** a written in-game walk: place, remove, look-at info, respawn, record a route and place a patrol on it,
|
||||
restart. **This is the first stage that needs a player on a rig.**
|
||||
**Tested by** the harness for everything a console can reach (the commands' parsing, refusals, names, and the
|
||||
route file a recording writes), then a written in-game walk: place, remove, rename, look-at info, respawn, record a
|
||||
route and place a patrol on it, place on a player-built floor and destroy it, restart. **This is the first stage
|
||||
that needs a player on a rig.**
|
||||
|
||||
### Stage 4 — Runic Gateway integration
|
||||
|
||||
|
||||
Reference in New Issue
Block a user