docs(runicnpc): stage 3 as built, and its in-game walk

- PLAN.md stage 3: what was built (runicnpc-rust#5), the results on
  both rigs (134/134, reload and restart 5/5), what building it found
  (Rust leaves an NPC in the air when its floor goes; a route leg can
  be on the navmesh and still unwalkable; a shore floor not covered;
  stage 2's JSON leak), the console-only at= option for the org
  lead's call, and the in-game walk checklist.
- API.md: SetPlacement's navmesh check and D239 fallback, the
  placements' note, List's regrounded, and SetRoute's unchecked legs.

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 03:19:14 -05:00
parent fdfd525bc4
commit 953044b806
2 changed files with 69 additions and 4 deletions

View File

@@ -5,7 +5,7 @@
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). **Stage 3's design answered 2026-09-30:** D239–D242
(§0).
(§0). **Stage 3 built and tested 2026-09-30** on both rigs (§9); its in-game walk waits for a player.
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
@@ -618,6 +618,60 @@ route file a recording writes), then a written in-game walk: place, remove, rena
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.**
**Built (2026-09-30, runicnpc-rust#5, API still 2).** Every verb of §5 is `/rnpc <verb>` in chat and `rnpc.<verb>`
in a console, one dispatcher behind both. `runicnpc.admin` includes `runicnpc.place`, and the server console has
both. `/rnpc` alone lists the verbs the caller may use. `rnpc.profile` answers only in a console (F1 included): in
chat it points there. **One addition for the org lead's call:** the server console has no position, so there
`place`, `here` and `path point` take `at=x,y,z` (and `yaw=`), which is also how the harness drives them. In game
these options are refused.
| Group | What it proves | Oxide | Carbon |
|---|---|---|---|
| cmd | D242's options and defaults; D241's names (the next number, the freed number taken again, rename keeps the live NPC and moves its owner); 11 refusals, none leaving a placement behind; a sentry 40 m up; D240's recording (undo, too few points, a point in the air, `loop\|back`); a patrol walking the recorded route 18 m in 12 s; a deleted route leaves its placement waiting; respawn, clear, remove; the chat path as a stand-in player (nothing without the permission, `here`, `remove`); standalone `rnpc.profile` create, set, show and delete, refused while managed | 57/57 | 57/57 |
| floor | D239's warning; a roamer standing on a player-built floor; the floor destroyed under it; the respawn falling back to the ground and back onto the rebuilt floor; a route leg to a floor with no stairs refused | 7/7 | 7/7 |
| all | stage 2's groups and the two above in one `rnt.run all` | 134/134 | 134/134 |
| RunicNPC reloads / the server restarts | stage 2's checks | 5/5 · 5/5 | 5/5 · 5/5 |
What building it found:
- **Rust leaves an NPC standing in the air when the floor under it is destroyed.** Measured for 15 s; it kept its
state and never fell. RunicNPC's brain now checks every 2 s, and a roamer more than 2 m above the nearest
navmesh is put on it (as Rust's own navigator warps) and wanders from there until it respawns. It was on the
ground 2 s after its floor went, on both rigs. A placement whose spot is off the mesh when its NPCs respawn
spawns them on the nearest navmesh, and returns to its spot once the floor is rebuilt. This is how D239's "falls
back to the nearest navmesh" is implemented.
- **A route can be on the navmesh and still not walkable.** The first recorded test route climbed a hill a player
can walk. Its first point was on an island of navmesh on a rock top, and the patrol never left it. `path point`
now asks Rust for a path from the previous point and refuses the point if there is none; `path save loop`
refuses a route whose last point cannot reach its first. `RunicNpc_SetRoute` does not check legs (API.md).
- **A floor over the shore was not covered by the navmesh in 10 s,** where a floor over dry ground a few metres
away was covered in 0.1 s (stage 2's figure). The command answers with the reason in both cases, so nothing
depends on it. It is noted here in case stage 10 meets it again.
- **Stage 2 wrote two computed properties into its JSON** (`V` in every position, `IsSentry` in every profile),
in the files and in the API's answers. Both are ignored now.
- **Rust's console argument type has changed** from `string[]` to `StringView[]` in the current build. The
console verbs read each argument through `GetString`, which both have.
**The in-game walk is still to do** (it needs a player). Its checklist, on either rig, with `runicnpc.admin`
granted and one standalone profile made from the console (`rnpc.profile create bandit`, then `set bandit kits
<kit>`):
1. `/rnpc` lists the verbs; without the permission it says which is missing.
2. `/rnpc place bandit` on the ground you look at → "Placed bandit-1"; it spawns facing you, and the cost
warning is shown. `/rnpc here bandit count=3 mode=group` → bandit-2, three NPCs around you.
3. Look at one: `/rnpc info` shows its name, profile, placement, health, state and target. Shoot it: the target
line names you.
4. `/rnpc near` lists bandit-1 and bandit-2 with distances. `/rnpc rename bandit-2 camp`; `/rnpc tp camp`.
5. Kill one of `camp`: nothing returns until all three are dead (`group`); then `/rnpc respawn camp` brings all
back at once.
6. `/rnpc path record gate`, walk and `/rnpc path point` four times (try one on a rock or a roof: refused),
`/rnpc path undo`, one more point, `/rnpc path save loop`. `/rnpc place bandit move=route:gate` → the NPC walks
the points in order.
7. Build a foundation and a floor 2 high with stairs, stand on the floor: `/rnpc here bandit` → the warning.
Destroy the floor: the NPC is on the ground within 2 s. `/rnpc near` shows the note.
8. Look at an NPC: `/rnpc remove` removes its placement. `server.save`, restart: every other placement is back,
and no plain "Scientist" stands at a spot.
### Stage 4 — Runic Gateway integration
Across four repositories, split into 4a–4c if it grows: