docs(runicnpc): stage 5 built, tested and walked; API 4; protocol 13 §19.13
- runicnpc/PLAN.md: stage 5 as built, what the build found that the spike did not (Rust's CanSeeTarget is no line of sight for an NPC target; a destroyed escort target compares equal to null; a rocket's line of sight), the harness results on both rigs, and the site walk; - runicnpc/API.md: API 4 (the faction table, escort, ally, tether, the profile's stage 5 fields, a placement's tether, OnRunicNpcEscortEnded, the new rows of RunicNpc_List, rnpc.faction, /rnpc follow, tether=); - rust-link/PROTOCOL.md §19.13: the faction table on npc.profiles and npc.profiles.set, world.place's escort, ally and tether, the three new world.error reasons; the bridge needs RunicNPC API 4. Joins protocol 13 (D253). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01E14m6SuuY6i1vASFeGDBeY
This commit is contained in:
@@ -1437,7 +1437,7 @@ five routes.
|
||||
|---|---|---|
|
||||
| `world.monuments` | `world.monuments` | This map's monuments in one stable order (grouped by prefab short name, then by position). Each has `value` (`kind`, or `kind#n` when the kind repeats), `kind`, `instance`, `of`, `label` (the game's display phrase), `x`, `z` and `grid`. Also `worldSize`, the placeable `prefabs` (`key`, `kind`, `label`), `eventsEnabled`, `maxCrates`, `maxNpcs` and `zoneManager` |
|
||||
| `world.zone` | `world.ok` or `world.error` | Opens a ZoneManager temporary zone owned by the bridge. Needs `runId`, `key`, a location, `radius` (5–150 m) and `holdMs` (1 minute to 7 days); `name` is optional. Protocol 13 adds `flags`, `settings`, `enterMessage`, `leaveMessage`, `delivery`, `format` and `dome` (§19.11) |
|
||||
| `world.place` | `world.ok` or `world.error` | Places `count` of one allowlisted `prefab` at a location, scattered within `spread` m (0–50, 10 by default for a group). All or nothing: if the game refuses one, the ones already made are killed. Protocol 13 adds `profile`, a RunicNPC profile in place of a prefab (§19.12) |
|
||||
| `world.place` | `world.ok` or `world.error` | Places `count` of one allowlisted `prefab` at a location, scattered within `spread` m (0–50, 10 by default for a group). All or nothing: if the game refuses one, the ones already made are killed. Protocol 13 adds `profile`, a RunicNPC profile in place of a prefab (§19.12), and for a profile `escort`, `ally` and `tether` (§19.13) |
|
||||
| `world.revert` | `world.ok` | Gives back what a run owns: the named `ids`, or else everything under `key`, or else everything the run owns. The answer lists `removed`, `gone` and `refused` |
|
||||
| `world.owned` | `world.owned` | What the world still holds of what events made, **looked for** by net id or zone id, narrowed by `runId`. Anything gone is pruned from the registry as the walk passes it |
|
||||
|
||||
@@ -2394,7 +2394,7 @@ stays true. RunicNPC is optional until its stage 9. Without it every `npc.*` com
|
||||
|
||||
The bridge needs **RunicNPC API 3** (D249), `RunicNpcApiNeeded` in the code and **`runicnpc_api = 3` in
|
||||
`overlay.toml`**, which the release copies into its manifest and `checkPlugin.js` holds equal to the code.
|
||||
An older RunicNPC answers `npc.error` **`runicnpc-old`**.
|
||||
An older RunicNPC answers `npc.error` **`runicnpc-old`**. **Stage 5 raised it to API 4** (§19.13).
|
||||
|
||||
**Hello and status.** `integrations` gains `runicNpc`, like the other optional mods:
|
||||
|
||||
@@ -2475,6 +2475,49 @@ names still reads a scientist.
|
||||
**`player.tally` gains `npcProfileKills`**, the player's kills of RunicNPC's NPCs by profile name
|
||||
(`{"warden": 2}`). They are counted in `npcKills` as well.
|
||||
|
||||
### 19.13 RunicNPC stage 5: the faction table and an event's orders (runicnpc PLAN.md stage 5)
|
||||
|
||||
Stage 5's wire changes **join protocol 13** while it is unreleased (D253); no message changes shape, and
|
||||
`PROTOCOL_VERSION` stays 13. The bridge now needs **RunicNPC API 4**: `RunicNpcApiNeeded = 4`,
|
||||
**`runicnpc_api = 4`** in `overlay.toml`. An older RunicNPC answers `npc.error` `runicnpc-old` as before.
|
||||
|
||||
**The faction table** (D254, D268) travels with the profiles. `npc.profiles` gains **`factions`**, the
|
||||
server's table:
|
||||
|
||||
```json
|
||||
{"kind":"npc.profiles","managed":false,"profiles":{…},"refused":{},
|
||||
"factions":[{"a":"bandits","b":"guards","relation":"hostile"}]}
|
||||
```
|
||||
|
||||
`npc.profiles.set` takes an optional **`factions`** beside `profiles`. The bridge sets the table first
|
||||
(`RunicNpc_SetFactions`), so the profiles are checked against the table they will be used with. A table
|
||||
RunicNPC refuses is kept out, the old one stays, and `npc.ok` carries **`factionsRefused`**, RunicNPC's
|
||||
sentence; the profiles are pushed either way. One row is one pair, both ways; `scientists` and `animals`
|
||||
are Rust's own two.
|
||||
|
||||
**`world.place` with a `profile` takes three orders**, each optional (D269, D270, D272):
|
||||
|
||||
| Field | Means |
|
||||
|---|---|
|
||||
| `escort` | A player's Steam id. The NPCs keep close to that player and fight whoever attacks them, and walk back to their spot when the player dies or leaves. The player must be on the server |
|
||||
| `ally` | `{"kind": "clan", "id": "<the game's clan id>"}` or `{"kind": "player", "id": "<steam id>"}` (that player and their team). The NPCs never target the ally's people and defend them and what they own |
|
||||
| `tether` | `true`: the zone **this run made** (`world.zone`) that holds the step's point. The NPCs never leave it |
|
||||
|
||||
The bridge gives each NPC its orders through `RunicNpc_Escort`, `RunicNpc_Ally` and `RunicNpc_Tether`
|
||||
right after spawning it. **Still all or nothing:** an order RunicNPC refuses removes every NPC the step
|
||||
placed, and the step answers `world.error` `refused` with RunicNPC's sentence. Three new `world.error`
|
||||
reasons:
|
||||
|
||||
| `reason` | Means | Retried? |
|
||||
|---|---|---|
|
||||
| `escort-offline` | the escort is not on the server | yes: they may join |
|
||||
| `no-zone` | no zone of this run holds the point | no |
|
||||
| `runicnpc-old` | an order was given and RunicNPC answers an API older than 4 | no |
|
||||
|
||||
`ally.kind` other than `clan` or `player`, or an `escort` that is not a number, is `malformed`.
|
||||
Nothing new is sent the other way: an escort's end is RunicNPC's hook (`OnRunicNpcEscortEnded`), and the
|
||||
bridge does not forward it.
|
||||
|
||||
**Hooks.** `OnRunicNpcDied`, `OnRunicNpcHealth` and `OnRunicNpcPlacementChanged` join `rg.hooks`' list.
|
||||
`rg.npc` prints RunicNPC's version and API and the last `npc.*` command.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user