feat(bridge): protocol 13 with RunicNPC, edge → main (runicnpc 9e step 3, merge 2 of 3) #29
Reference in New Issue
Block a user
No description provided.
Delete Branch "edge"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
What & why
Merge 2 of 3, together with Rust-Link's and installer's cutovers. Protocol 13 (the plan-fix steps of 2026-09-26/27), the PLAN_REDESIGNS §1/§3/§4/§5 bridge work, and RunicNPC's stages 4–9 on the bridge side;
overlay.tomldeclaresprotocol = 13andrunicnpc_api = 6.feat:commits since).runicnpc_api6 (9b).The order (docs/runicnpc/PLAN.md, 9e step 3)
edge→main— after runicnpc-rust#18 (thefeat!:) has merged intoedge. Releases v1.0.0.edge→main, together — after I have checked v1.0.0 (checksums, manifestapi6). The bridge and the sidecar both move protocol 12 → 13, and the bundle's Gate 1 refuses a pair that disagrees, so one without the other leaves a bundle that cannot compose.v2/rust/current.jsononinstaller'sbundlesbranch moves to protocol 13 with RunicNPC 1.0.0 in it (dispatchingbundle.ymlif a compose run lost the race).edge→main— last, once a server can actually get RunicNPC from a bundle.Please leave
edgestanding (untick "delete branch" on merge): later work lands there.After the merges: the installer's RunicNPC path and the egg's banner from the real bundle (the row the walk left for this step), then the docs PR recording step 3.
How it was tested
Each change on
edgecame in by its own PR with its own checks and rig walk (stages 4–9, the 9d player session, 9e steps 1–2).edgeis 0 commits behindmain, so this merges clean; this PR's checks are the run against the merged tree.Checklist
AI-assisted contributions (required)
Claude Code (Claude Opus 5.5). I have reviewed and understandevery change, and take responsibility for it. AI-authored commits are
marked with a
Co-Authored-By/Assisted-Bytrailer.License
(GNU GPL v3.0 or later), and I have the right to contribute it.
🤖 Generated with Claude Code
https://claude.ai/code/session_01E14m6SuuY6i1vASFeGDBeY
The bridge's half of PLAN_FIXES §6 step 2 (decisions D181-D185, docs#288). - F13: `world.expired` carries the entity's kind as `what`. It used to write it over the frame's own `kind`, so every expiry left filed as "zone". - F1 (D159): `gathered` also counts OnDispenserBonus (the final-hit bonus), OnCollectiblePickup (hemp, mushrooms, stones off the ground) and OnGrowableGathered (farmed plants); all three are void and in ExpectedHooks. - F3: taking down a building block you own, or one on a cupboard you are authorised on, no longer counts toward `structures`. The frame still goes. - F4: every remaining UserIDString is SteamIdOf(userID), so a player another plugin spawned is never `steamId: null`. - F8 (D184): `plugin.loaded` / `plugin.unloaded`, once the world is ready, with the permissions that plugin added or removed (a diff of the registered list, taken a tick after the hook). - F12 (D181, D182): RunicGatewayZones.cs, a D168 helper shipped beside the bridge, Harmony-postfixes ZoneManager's Zone.InitializeZone and, a tick later, enters every connected player ZoneManager's own IsPositionInZone places inside, through ZoneManager's own OnPlayerEnterZone. Without it (or when it cannot find what it patches) the bridge scores its zones by IsPositionInZone. Hello reports `zoneHelper: { state, version?, reason? }`. - release.yml stages every helper beside the bridge and lists each .cs with its sha256 in manifest.files; the installer and the egg place them all. Not yet compiled: this is walked on both rigs before it merges. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01E14m6SuuY6i1vASFeGDBeYworld.zone gains flags, settings, enterMessage, leaveMessage, delivery, format and dome (PROTOCOL §19.11). Flags are checked against the live ZoneManager's own list, read through its API call ZoneFieldListRaw() (D211), and refused bad-option rather than dropped; settings are an allowlist of five with bounds. Both are kept on the registry entry and re-applied when a zone is re-created. The bridge says a zone's enter and leave messages itself (D193), as chat or a popup (chat when PopupNotifications is missing), and stays quiet for 5 s after re-creating a zone. RunicGatewayDomes.cs, a new helper, patches ZoneDomes so its API can be called without a player, and raises OnRgDomesReady after ZoneDomes' own start; the bridge puts its domes back only after it, so none is drawn twice. Domes are removed before their zone at expiry and revert. hello carries zoneManager { version, flags }, integrations.zoneDomes the ZoneDomes and helper state, and hello is sent again when ZoneManager, ZoneDomes or either helper loads or unloads. The release ships the new helper beside the zone helper. Not compiled or walked on a rig: the panel's file API was down on both. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01E14m6SuuY6i1vASFeGDBeY- npc.profiles answers with RunicNPC's faction table, and npc.profiles.set pushes one beside the profiles (RunicNpc_SetFactions), set first so the profiles are checked against it; a refused table comes back as factionsRefused and the old one is kept (D254); - world.place with a profile takes escort (a Steam id; the player must be on, else escort-offline), ally ({kind: clan|player, id}) and tether (the run's own zone that holds the point, else no-zone), and gives each NPC its orders through RunicNpc_Escort, _Ally and _Tether. All or nothing: an order RunicNPC refuses removes every NPC the step placed (D269, D270, D272); - the RunicNPC API the bridge needs is 4 (overlay.toml runicnpc_api = 4). Compiled on the Oxide rig. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01E14m6SuuY6i1vASFeGDBeYworld.place with a profile takes dropLoot (D296): false spawns the NPCs with RunicNPC's {"loot":{"dropTable":false}} override, so they keep their corpse's start but roll no table. Absent or true, as before. runicnpc_api and RunicNpcApiNeeded are 6. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01E14m6SuuY6i1vASFeGDBeY