docs(runicnpc): stage 5 decisions D263-D266

The org lead's answers to the spike's four open questions (2026-10-01):
D263 a fight with Rust's scientists stays one-sided and our NPCs never
go hunting into monuments; D264 `turrets: always` adds Outpost's and
Bandit Camp's sentries; D265 the main weapon's ammunition is endless, as
in Rust; D266 fire burns as it does in Rust, allies included.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01E14m6SuuY6i1vASFeGDBeY
This commit is contained in:
2026-10-01 03:05:42 -05:00
parent ae0b8753bb
commit 7dade6cce1

View File

@@ -79,6 +79,10 @@ architectural or design decision is implemented.
| **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. |
| **D263** | **A fight with Rust's scientists stays one-sided, and our NPCs never go hunting.** A scientist one of ours shoots takes cover, as Rust's AI does, and is not made to fire back. A profile hostile to `scientists` fights only scientists that come within its own leash of its spot. It never walks into a monument to look for them, so our NPCs never clear a monument on their own (stage 5 spike; the org lead's words: "our NPCs will not clear monuments on their own"). | RunicNPC driving a hit scientist to fire back; balancing fights so a few cannot clear a monument; refusing such profiles near monuments at placement. |
| **D264** | **`turrets: always` means the safe-zone sentries too**: Outpost's and Bandit Camp's turrets shoot that profile's NPCs as they shoot a hostile player. `default` is what Rust does (player turrets shoot it, safe-zone sentries do not), and `ignore` means no turret shoots it (stage 5 spike, refines D259). | Dropping `always`, since `default` already means player turrets. |
| **D265** | **The main weapon's ammunition is endless, as in Rust.** An NPC never runs dry, and its loot keeps the kit's ammunition. Only D260's extras (syringes, grenades, rockets and the like) are used up (stage 5 spike, refines D260). | Ammunition used up shot by shot; a per-profile setting. |
| **D266** | **Fire burns as it does in Rust.** A flamethrower NPC's flames burn every NPC in them, its own allies included, because Rust filters only bullets between NPCs. Admins place flamethrower NPCs with that in mind (stage 5 spike). | Our NPCs taking no fire damage from their allies. |
**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
@@ -862,10 +866,10 @@ Rust's own `TickAttack` the target, so the shot is still Rust's.
| Ally of ours standing on the line of fire | **0 hits on the ally**; the scientist died at 47 s | **0 hits**; died at 39 s |
- **A stock scientist never shoots back at ours.** Rust's `HumanNPC.IsTarget` is true only for players, pets and
scarecrows, and it is not virtual. Shot by ours, the scientist takes cover and does nothing else. **Open, question 1
below.**
scarecrows, and it is not virtual. Shot by ours, the scientist takes cover and does nothing else. **One-sided, as
D263 decided.**
- **Fire is not filtered.** Rust's NPC-to-NPC check exists only for bullets. An NPC with a flamethrower burned a
polar bear that walked in, and would burn allied NPCs the same way. **Open, question 4.**
polar bear that walked in, and would burn allied NPCs the same way. **It stays that way (D266).**
**2. What our sensing costs.** Thirty seconds a phase, after five to settle. The frame times include the world's own AI.
About 570 brains (Rust's scientists and animals) already queue for Rust's 2 ms AI budget on this map, which is why the
@@ -903,7 +907,7 @@ turret's trigger and moved in, because a flame turret only notices what *enters*
- **Shooting back works, and a revolver barely scratches a turret.** A flame turret's damage arrives through its
fireballs, so "who hurt me" follows the fireball's creator back to the turret.
- `ignore` has Rust's own hook to use: `CanBeTargeted` for the auto turret, the flame turret and the trap.
NextGenPVE uses the same hook. **What `always` means is open, question 2.**
NextGenPVE uses the same hook. **`always` adds the safe-zone sentries (D264).**
**4. The kit items Rust's AI uses by itself (D260).** Ours carried the kit's revolver, 3 syringes, 2 grenades and a
machete, with Rust's `CanUseHealingItems` switched on. A stand-in "shot" it 20 damage every 4 s, down to 37 health.
@@ -920,7 +924,7 @@ Then the main weapon was swapped for a rocket launcher, and then for a flamethro
because an NPC reloads for free.
So **every behaviour D260 lists is ours to write**: healing, grenades, melee, rockets, and the flamethrower's range.
**Whether the main weapon's ammunition should be used up too is open, question 3.**
**The main weapon's ammunition stays endless (D265).**
**5. TruePVE and NextGenPVE (D261).** Each damage direction was probed with a 10-damage hit, each plugin on its default
rules. The harness answered `CanEntityTakeDamage` three ways: not at all, "allow", and "deny". The PVE stand-ins
@@ -947,20 +951,27 @@ victim's body landed beside it. That looks like Rust's ground check on a deploya
not anything an NPC did. The world's own wolves and a polar bear wandered into two scenarios; the tables count only the
entities the harness labelled.
**Open for the org lead** (each becomes a D-number when answered):
**What the answers left open, and the org lead's answers (2026-10-01):**
1. **Rust's scientists cannot fight back against ours.** A bandit profile set hostile to `scientists` will shoot them,
and they will only take cover. The two ways: leave it one-sided; or have RunicNPC drive a stock scientist that ours has
hit (face ours, fire, our mark on ours for that shot), which costs RunicNPC a loop over every scientist in a fight.
2. **`turrets: always`.** With `default`, player turrets already shoot ours. Does `always` mean that outpost and
bandit-camp sentries shoot it too, so a hostile NPC walking into Outpost is shot as a hostile player would be? Or
does it mean something else?
3. **Ammunition.** Rust never uses up an NPC's ammunition or fuel. D260 consumes the extras (syringes, grenades,
rockets). Should the main weapon's ammunition be used up too, so an NPC can run dry and its loot shows what it shot?
Or does it keep Rust's endless magazine?
4. **Fire and allies.** A flamethrower NPC burns every NPC in its flame, its own faction's included, because Rust
filters only bullets. The choices: leave it as Rust does; or protect allies of ours from the fire (our NPC's own
`Hurt`, which cannot protect Rust's scientists).
1. **Rust's scientists cannot fight back against ours. → D263:** the fight stays one-sided; the scientist takes cover.
A profile hostile to `scientists` fights only the scientists that come within its own leash, and never goes into a
monument to look for them.
2. **What `turrets: always` means. → D264:** the safe-zone sentries too. Outpost's and Bandit Camp's turrets shoot that
profile's NPCs as they shoot a hostile player.
3. **Ammunition. → D265:** endless, as in Rust. Only D260's extras are used up.
4. **Fire and allies. → D266:** fire burns as it does in Rust, allies included.
What this adds to the build (D263–D266):
- **Sensing (D263):** a profile's hunt for `scientists`, `animals` or another profile is limited by its own leash
around its spot (its chase range, D233). Our sensing never drives an NPC towards a target beyond it, so it never
walks into a monument to look for scientists.
- **Turrets (D264):** `default` needs no code. `ignore` answers `CanBeTargeted` with "no" for the auto turret, flame
turret and trap. `always` makes Outpost's and Bandit Camp's sentries (`NPCAutoTurret`) target it, which Rust's own
`Ignore` and `IsEntityHostile` refuse for every `ScientistNPC`. Stage 5's build finds the hook that reaches those
two, or answers for the sentry from RunicNPC's side, and says which in this plan.
- **Ammunition (D265) and fire (D266):** nothing to build. The NPC's reload stays Rust's own, and fire damage is not
touched.
### Stage 6 — Roles