docs(runicnpc): stage 5 decisions D253-D262

The org lead's answers of 2026-09-30 for stage 5 (behaviour): one stage
walked once, opening with the D231 spike; named factions with per-profile
exceptions; players-only by default; group alert at 40 m; clan and team
allies defended; escort targets from events, the API and /rnpc follow;
turrets as for Rust's scientists; kit extras opt-in; PVE hooks allowed both
ways; a patrol returns to the point it was heading to.

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 23:05:24 -05:00
parent 337451f9f7
commit f899834453

View File

@@ -69,6 +69,16 @@ architectural or design decision is implemented.
| **D250** | **Per-profile kills are shown on the player's public stats ("Warden kills: 3"), in a "kills of a profile" title category, and as a leaderboard the visitor picks a profile for** (stage 4, D225, D247). | The player page and titles only; titles only. |
| **D251** | **Where an adopted server profile and a site profile share a name on that server, the site's wins** (stage 4, refines D244). The server's own is still imported, marked "replaced" and kept for an admin to restore, and that server's placements take the site profile's values. | The adopted one winning on its server, with the site's profile skipping it. |
| **D252** | **A player's per-profile kills are shown by opening their row in a server's leaderboard** ("Warden 3 · Bandit 12", for the wipe the page shows), and to the player on their own Player → Rust page. The module has no public player page, and stage 4 adds none (stage 4, the "player's public stats" of D250). | A new public player page; the profile leaderboard only. |
| **D253** | **Stage 5 is one stage, walked once end to end**, as stage 4 was (D248). It opens with the D231 spike, and its wire changes join protocol 13 while that protocol is unreleased (stage 5). | 5a/5b/5c, each walked and merged before the next; the spike alone first, the split decided afterwards. |
| **D254** | **Factions are named, with per-profile overrides.** Each profile names its faction (`bandits`), and a faction table states once how factions treat each other: *hostile*, *neutral* or *allied*. Rust's scientists (`scientists`) and animals (`animals`) are two built-in factions. A profile may also list its own exceptions, which win over its faction's relations. The table is authored on the site and pushed with the profiles; a standalone server edits it from the console (D221) (stage 5). | Named factions only; per-profile lists only, where a sixth bandit means editing the other five. |
| **D255** | **A profile with no faction settings fights players only**, as it does today. Fighting Rust's scientists, animals or other profiles is opted into per faction or per profile. Stage 1 measured sensing NPCs at about seven times the cost of fighting players (stage 5). | Hostile to Rust's scientists by default; hostile to everything outside its faction. |
| **D256** | **Group alert:** each profile has an alert radius, **40 m by default** and 0 to turn it off. When one of its NPCs is attacked, every ally within that radius learns the attacker and joins the fight, whether or not it can see him. An ally is the same faction, or the same profile when there is no faction (stage 5). | Only the NPCs of the placement that was hit; off unless a profile turns it on. |
| **D257** | **An NPC allied to a clan or a Rust team never targets its members, and defends them.** It attacks whoever damages one of those players, or anything the clan or team owns (building blocks, doors, deployables), within its leash. Rust's own clans and teams only, with no Clans-plugin dependency (stage 5). | Never targets them, nothing more; defends the players but not their buildings. |
| **D258** | **An escort's target comes from an event step, from the API, or from an admin's `/rnpc follow <placement> <player>`**, the command for trying it out in game. A persistent placement never escorts anyone of its own accord (stage 5). | Persistent placements that escort a named player too; the API alone. |
| **D259** | **Turrets treat our NPC as they treat Rust's scientists by default**, and it shoots back at a turret that shoots it. The spike measures exactly what Rust does. Each profile can choose `turrets: default`, `ignore` or `always` (stage 5). | Always targeted by player turrets; never targeted. |
| **D260** | **A kit's extra items are used only when the profile opts in, behaviour by behaviour:** healing with syringes, grenades, switching to melee, rockets, flamethrowers. All are off by default; the main weapon is always used. An item used comes out of the NPC's inventory, so the loot matches what is left (stage 5). | Every behaviour on whenever the kit carries the item; the main weapon only, with extras as loot. |
| **D261** | **On a PVE server, RunicNPC answers TruePVE's and NextGenPVE's damage hook with "allowed" for its own NPCs, both ways**, so players can fight them and they fight back, as with Rust's scientists. A profile may opt out, for example to make an NPC unkillable (stage 5). | Leaving it to the server's TruePVE rules; a config switch, off by default. |
| **D262** | **A patrol that leaves its route to fight returns to the point it was heading to** and carries on from there (stage 5, refines D234). | The nearest point, in the same direction; starting the route again. |
**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
@@ -342,13 +352,16 @@ Each profile has a **role**, which sets its AI states and defaults:
| **Roamer** | Moves in one of three ways (D233): `wander` within a radius of its spot, `monument` (Rust's AI-zone paths), or `route:<name>`; chases and fights. The profile sets the default, a placement may override it. |
| **Sentry** | Stationary: turns and shoots, never walks. The only role allowed off the navmesh. |
| **Guard** | Holds a point or an entity; chases only to its leash, then returns. |
| **Patrol** | A roamer on `route:<name>` (D233): walks a route recorded in game (`/rnpc path record`); fights and resumes (stage 5). |
| **Escort** | Follows an entity or player; defends it. |
| **Patrol** | A roamer on `route:<name>` (D233): walks a route recorded in game (`/rnpc path record`); fights, then returns to the point it was heading to (D262, stage 5). |
| **Escort** | Follows an entity or player; defends it. Its target comes from an event step, the API, or `/rnpc follow` (D258). |
| **Boss** | Any of the above, plus a health bar, phases and announcements (§3.3). |
| **Passive** | Never fights; press E to talk. Quest-givers and vendors. |
**Factions** are a relation table between profiles, plus optional ties to a team or clan: *hostile*, *neutral*
or *allied*. Rust's scientists are one more faction, so a profile can be told to leave them alone.
**Factions** are named (D254): each profile names one, and a table says how factions treat each other, *hostile*,
*neutral* or *allied*. Rust's scientists and animals are two built-in factions. A profile may list exceptions,
which win over its faction's relations. With no faction settings a profile fights players only (D255). An
NPC can also be allied to a clan or a Rust team: it never targets the members, and it defends them and what they
own (D257). Allies within a profile's alert radius join a fight one of them is in (D256).
**Zone tethering** keeps an NPC inside a ZoneManager zone. At the edge it turns back, and if it ends up outside (it
was pushed, or the zone moved) it is returned home. ZoneManager is already required by `module-rust`; to RunicNPC it
@@ -786,6 +799,31 @@ What building it found:
Guard, patrol and escort roles; factions (between profiles, with Rust's scientists, and with teams or clans); group
alert; zone tethering; turrets; the weapon behaviours a kit's items imply; TruePVE compatibility.
The org lead's answers on 2026-09-30 are D253–D262. **It is one stage, walked once end to end (D253)**, with the
pieces below. Its wire changes join protocol 13 while it is unreleased.
- **The spike first (D231, D253).** A harness answers what the rest depends on, on both rigs:
- our own sensing and combat state against an NPC target: does it shoot, with the kit weapon, and hit;
- the cost of sensing only the factions a profile is hostile to, nearest first, against stage 1's 100² line of
sight tests (17.7–20.4 ms per think);
- what Rust's auto turrets, flame turrets and shotgun traps do to a stock scientist and to ours (D259);
- what TruePVE's and NextGenPVE's hook sees for our NPC (D261);
- which kit items Rust's AI already uses on its own (D260).
- **RunicNPC (API 4):**
- the faction table and each profile's `faction`, exceptions, alert radius, turret mode, PVE opt-out and kit
behaviours, in the profile file and through `RunicNpc_SetProfiles` (D254–D261);
- the guard role (holds a point or an entity, chases to its leash, returns), escort (D258) and patrol resume
(D262);
- sensing and combat against NPC and animal targets, for the factions that ask for it (D255);
- group alert (D256) and clan or team allies (D257);
- zone tethering through ZoneManager, optional;
- turret behaviour (D259), the opted-in kit behaviours (D260), and the PVE hooks (D261);
- `/rnpc follow` and `rnpc.faction` for standalone servers.
- **Rust-Plugins (the bridge):** the faction table pushed with the profiles; `world.place` with an escort target
and a clan or team ally for an event's NPCs.
- **Module-Rust:** the profile form's new fields, a faction table on the NPC profiles page, and the Place NPCs
step's escort target and ally.
**Tested by** harness fights between profiles on the rig (who shoots whom, with what, and within which leash), and
an in-game walk for escort and faction ties to a clan.