15 Commits

Author SHA1 Message Date
340f1dc8f5 Merge pull request 'test(harness): stage 5 spike, NPC targets, turrets, kit items, PVE (D231, D253)' (#7) from spike/stage-5 into edge
Reviewed-on: #7
2026-10-01 08:17:26 +00:00
9424dca6d1 test(harness): stage 5 spike, NPC targets, turrets, kit items, PVE (D231, D253)
All checks were successful
PR Checks / plugin-checks (pull_request) Successful in -1m28s
RunicNpcHarness 0.2.0 adds the measurements stage 5 opens with:

- rnh.npcfight: our own sensing and combat state against a stock
  scientist, another of ours, a boar and a wolf, and with an ally on
  the line of fire. Rust's BaseProjectile.ServerUse drops every hit on
  an NPC from an NPC's gun unless the victim's faction is Horror; the
  prototype marks only its current target Horror for the length of
  each of its own shots.
- rnh.sense: what that sensing costs, 100 against 100 scientists and
  50 against 50 of ours.
- rnh.turrets: auto turret, flame turret and shotgun trap against a
  stand-in player, a stock scientist and ours (D259).
- rnh.items: which kit items Rust's AI uses by itself (D260).
- rnh.pve: what TruePVE or NextGenPVE does with our NPC, and with an
  answer to CanEntityTakeDamage (D261).

Never shipped: a developer tool in tools/.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01E14m6SuuY6i1vASFeGDBeY
2026-10-01 00:23:47 -05:00
bf2940b819 Merge pull request 'feat: API 3, placements from a website (stage 4, D249)' (#6) from feat/stage-4-api3 into edge
Reviewed-on: #6
2026-09-30 19:52:55 +00:00
e2c0db2a5d ci(release): ask the installer to recompose the Rust bundle (stage 4, D224)
All checks were successful
PR Checks / plugin-checks (pull_request) Successful in 9s
RunicNPC is the Rust bundle's third artefact from stage 4, so its release
ends as Rust-Plugins' does: a dispatch of the installer's bundle workflow,
warned rather than failed when the token cannot reach it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01E14m6SuuY6i1vASFeGDBeY
2026-09-30 04:52:36 -05:00
fe20ca41af feat: API 3, placements from a website (stage 4, D249)
RunicNpc_AddPlacement creates a placement and names it as /rnpc place
does (D241, D246). A position without y is a map point: it is put on the
ground there (terrain and rock, never a building or a tree, D245), then
checked against the navmesh like an in-game placement. It answers the id,
the grounded position, whether the spot is player-built, and the cost
warning, or the in-game refusal sentence.

RunicNpc_RenamePlacement and RunicNpc_RespawnPlacement do what rnpc
rename and rnpc respawn do. OnRunicNpcPlacementChanged(id, change,
previous) is raised on every set, remove and rename, from the API or in
game, so the bridge can tell the site at once.

rnpc place and here now share CreatePlacement with the API, so both give
the same refusals. The test harness gains an api3 group; all 157 checks
pass on the Oxide and Carbon rigs.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01E14m6SuuY6i1vASFeGDBeY
2026-09-30 04:01:30 -05:00
9c366ab5b5 Merge pull request 'feat: stage 3, the /rnpc commands in game' (#5) from feat/stage-3-in-game into edge
Reviewed-on: #5
2026-09-30 08:20:17 +00:00
0a57d783ca feat: stage 3, the /rnpc commands in game
All checks were successful
PR Checks / plugin-checks (pull_request) Successful in 7s
The chat command /rnpc and the same verbs as rnpc.<verb> in a console
(PLAN.md §5), behind runicnpc.place and runicnpc.admin:

- place / here with key=value options in any order (D242); placements
  made in game are named <profile>-<n> and renamable (D241).
- remove, rename, near, info (the NPC you look at), profiles, tp,
  respawn, clear, and rnpc.profile create|show|set|delete for a
  standalone server (refused while the site manages profiles, D221).
- path record / point / undo / save [loop|back] / cancel / list /
  delete (D240). A point an NPC cannot walk to from the last one is
  refused, as is a loop that cannot close: Rust's path query says so.
- A roamer may stand on a player-built floor, with a warning (D239).
  If the floor is destroyed under a live NPC, Rust leaves it standing
  in the air, so the brain puts it on the nearest navmesh within 2 s;
  a placement whose spot is off the mesh respawns on the nearest.
- The API's SetPlacement now refuses a roamer off the navmesh, as the
  command does; placements report a note while they fall back.
- Pos.V and Profile.IsSentry no longer leak into the JSON files.

The harness gains the cmd and floor groups. Both rigs: 134/134 in one
rnt.run all, rnpc reload 5/5, server restart 5/5.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01E14m6SuuY6i1vASFeGDBeY
2026-09-30 03:17:44 -05:00
15120ef80d Merge pull request 'feat: stage 2, the NPC and its API (API 2)' (#4) from feat/stage-2-npc-api into edge
Reviewed-on: #4
2026-09-30 06:52:37 +00:00
f8084955e8 feat: stage 2, the NPC and its API (API 2)
All checks were successful
PR Checks / plugin-checks (pull_request) Successful in -1m38s
RunicNPC now spawns its own NPC: Rust's scientist with its ScientistNPC and
ScientistBrain swapped for ours, copying a fixed field list generated from
Rust's unmodified assembly (D232, tools/fieldlist). Profiles live in
data/RunicNPC/profiles.json in the approved shape (D238); placements persist
with each/group respawn (D236) and wait for a missing profile or route
(D237); roamers wander, follow Rust's monument paths, or walk a route (D233,
D234), with our own chase where Rust's needs an AI zone; sentries hold their
spot; NPCs walk home and sleep past 160 m of any player (D235). Spawns wait
for the navmesh and are spread over frames; caps are off by default and the
cost warning is shown instead (D227). The whole PLAN.md section 4 API and its
hooks are in, documented in docs/runicnpc/API.md.

tools/RunicNpcTest.cs is the stage 2 harness; every group passed on both
rigs, and after a plugin reload and a server restart. checkPlugin no longer
counts an override (RunicNpcPlayer.OnDied) as a hook.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01E14m6SuuY6i1vASFeGDBeY
2026-09-30 01:31:04 -05:00
914047f1b0 Merge pull request 'chore(tools): the stage 1 harness, RunicNpcHarness.cs' (#3) from feat/stage-1-harness into edge
Reviewed-on: #3
2026-09-30 04:26:33 +00:00
18c90961ba chore(tools): the stage 1 harness, RunicNpcHarness.cs
All checks were successful
PR Checks / plugin-checks (pull_request) Successful in 6s
A developer plugin, never shipped, that measured the six questions stage 2
depends on (docs/runicnpc/PLAN.md §9, stage 1) on both rigs: the subclass
swap, saving across a hard kill, what Rust's brain honours, navmesh coverage,
the cost of 1/10/100 idle and fighting, and the death screen and bridge frames.

It spawns stand-in players (player.prefab, a made-up user id, IsNpc false) as
targets, at the org lead's suggestion. It needs a hidden Kits kit, rnhrevolver.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01E14m6SuuY6i1vASFeGDBeY
2026-09-29 23:04:46 -05:00
da8b013a09 Merge pull request 'release: cut edge over to main — RunicNPC v0.1.0 (stage 0)' (#2) from edge into main
All checks were successful
Release plugin / release (push) Successful in -1m42s
Reviewed-on: #2
v0.1.0
2026-09-30 02:05:52 +00:00
bb08158c50 Merge pull request 'feat: stage 0, an empty RunicNPC that releases through CI' (#1) from chore/stage-0-scaffold into edge
All checks were successful
PR Checks / plugin-checks (pull_request) Successful in 8s
Reviewed-on: #1
2026-09-30 02:02:56 +00:00
249f2e513f feat: stage 0, an empty RunicNPC that releases through CI
All checks were successful
PR Checks / plugin-checks (pull_request) Successful in -1m44s
The repository RunicNPC is built in (docs/runicnpc/PLAN.md §9, stage 0):

- plugin/RunicNPC.cs: `// Requires: Kits` (D217), `[Info]` with the 0.0.0
  placeholder the release stamps, `RunicNpc_ApiVersion()` (API 1), and
  `rnpc.status`, which reports the version and which hooks have fired. It
  spawns nothing.
- plugin.toml: the API version, the framework floors it was loaded on
  (Oxide 2.0.7726, Carbon 2.0.259) and requires_plugins = ["Kits"].
- scripts/checkPlugin.js, adapted from Rust-Plugins': every hook listed and
  void unless written down; chat-command signatures; every RunicNpc_ call
  reachable by Call (the HumanNPC trap, PLAN.md §1.2); ApiVersion,
  `// Requires:` and [Info] agreeing with plugin.toml. 23 self-tests, including
  the real plugin and a CRLF checkout.
- PR Checks on PRs into main and edge; the release workflow on main, with
  Rust-Plugins' release engine unchanged and an adapter that ships
  runicnpc-<ver>.tar.gz (runicnpc/RunicNPC.cs + manifest.json) and SHA256SUMS.
  No bundle dispatch until stage 4.
- tools/: the rig panel scripts, with the panel and server ids moved into a
  git-ignored tools/rigs.json. `con.js` became `console.js`: CON is a reserved
  device name on Windows, and git there cannot open the file.
- README, CONTRIBUTING (edge-based flow, AI disclosure, borrow-not-copy),
  SECURITY, the code of conduct, issue and PR templates.

`feat:` so the cutover to main cuts the first release, 0.1.0.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01E14m6SuuY6i1vASFeGDBeY
2026-09-29 21:01:49 -05:00
8641d8fb2e chore: seed the repository with its licence and a stub README
The repository was created empty, so this one commit goes to main directly to
give `edge` something to branch from (stage 0, docs/runicnpc/PLAN.md §9). A
`chore:` subject so the release workflow, when it lands, cuts nothing for it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01E14m6SuuY6i1vASFeGDBeY
2026-09-29 20:53:58 -05:00