Files
runicnpc-rust/plugin.toml
wtclaude 21d3c477dc feat: API 4, factions, escort, allies, tether, turrets, kit extras and PVE (stage 5)
Stage 5's behaviour (docs runicnpc/PLAN.md, D253-D272):

- profiles gain faction, relations (exceptions), alertRadius, turrets,
  hurtByPlayers, hurtsPlayers and kitUse, and the guard role; the faction
  table rides in profiles.json, one row per pair, both ways (D254, D268);
- our own sensing and fight beside Rust's design: only the factions a
  profile hunts, within its leash of its anchor (D263), the target made
  Horror for the length of our own shot, and Rust's attack routine;
- shooting back at whoever hurt it (D268), the alert radius (D256), clan,
  team or player allies that are never targeted and are defended with
  what they own (D257), escort as an order that walks home when its
  charge is gone (D269), and a placement's tether through ZoneManager
  (D272);
- turrets: ignore through CanBeTargeted, and always through a Harmony
  patch on the safe-zone sentries for our always NPCs only (D267);
- the kit's extras, each opted into and used up: heal, melee,
  flamethrower, grenades and rockets (D260, D265);
- TruePVE/NextGenPVE answered both ways unless a profile turns a direction
  off, and the opt-out enforced by RunicNPC itself (D261, D271);
- API 4: RunicNpc_Factions, _SetFactions, _Escort, _Ally, _Tether and the
  OnRunicNpcEscortEnded hook; rnpc follow, rnpc.faction and tether=.

Compiled and loaded on both rigs (Oxide and Carbon); the sentry patch
applies on both.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01E14m6SuuY6i1vASFeGDBeY
2026-10-01 07:20:59 -05:00

53 lines
3.0 KiB
TOML

# Release metadata for RunicNPC.
#
# Consumed by the release workflow, which folds these values into the
# manifest.json shipped inside the release tarball. The Runic Gateway installer
# and the Pterodactyl egg read that manifest to decide what they are placing
# (docs/runicnpc/PLAN.md D224), and the bridge will read the same `api` at hello
# (stage 4).
#
# There is deliberately NO version key here. The release version is derived from
# git tags and conventional commits by the release workflow, so there is no bump
# commit to keep in sync and no way for this file to disagree with the tag.
# ── The API version other plugins call ───────────────────────────────────────
#
# The number a caller of `RunicNpc_*` relies on (PLAN.md §4). It MUST equal
# `ApiVersion` in plugin/RunicNPC.cs; `node scripts/checkPlugin.js` holds the two
# equal on every pull request. It moves when a call or a raised hook changes
# shape, not on every release.
#
# The plugin answers this at run time through `RunicNpc_ApiVersion()`, but only
# once a server has booted with it loaded — too late for an installer to refuse
# a RunicNPC too old for the bridge it is pairing with. Declaring it here is what
# lets a bundle check the pair BEFORE an operator installs it.
#
# 1 was stage 0's: `RunicNpc_ApiVersion()` and nothing else.
# 2 was stage 2's whole API, PLAN.md §4.
# 3 was stage 4 (D249): RunicNpc_AddPlacement, _RenamePlacement, _RespawnPlacement and the
# OnRunicNpcPlacementChanged hook.
# Current: 4 — stage 5: RunicNpc_Factions, _SetFactions, _Escort, _Ally, _Tether, the profile's stage 5
# fields, a placement's tether, and the OnRunicNpcEscortEnded hook, documented in docs/runicnpc/API.md.
api = 4
# ── Framework floors ─────────────────────────────────────────────────────────
#
# The same file runs on Oxide and Carbon; the installer and the egg decide
# whether it lands in `oxide/plugins/` or `carbon/plugins/`. These are the builds
# it is known good on — the two rigs it was loaded on — not a measured minimum.
# (The bridge's Oxide floor is older, 2.0.7585; RunicNPC has never run on that.)
min_oxide_version = "2.0.7726"
min_carbon_version = "2.0.259"
# ── Plugins it cannot load without ───────────────────────────────────────────
#
# Kits is how every RunicNPC NPC is equipped, and it is required (D217). The
# plugin says so itself with `// Requires: Kits`, which stops either framework
# loading it without Kits; this list is the same fact for the installer's
# `doctor`, which reports a missing one rather than installing it. The PR check
# holds this list and the plugin's `// Requires:` lines equal.
#
# ZoneManager is NOT listed: a zone tether is optional (PLAN.md §6). A placement
# or an event step that asks for one on a server without it is refused (D272).
requires_plugins = ["Kits"]