feat(bridge): Guarded Crate on protocol 14 (PLAN_REDESIGNS §14.3.5) #39

Merged
whitlocktech merged 1 commits from feat/guarded-crate into edge 2026-10-15 18:18:45 -05:00
Member

Stage 6 of the §14.3 integration plan. Spec: docs rust-link/PROTOCOL.md §20.9 and §17.3 (docs PR alongside). Record: modules/rust/PLAN_REDESIGNS.md §14.3.19.

  • Three events from Guarded Crate's own hooks:

    • gc.started { x, z, key? }
    • gc.ended { steamId?, name?, x?, z? }: the player who killed the last guard. Both are absent when nobody did (NpcSpawn reloaded, the guards died some other way, or another NPC killed the last one).
    • gc.failed { x, z }: the timeout

    None is sent while the world is not live. A clearing is still counted.

  • The key's join is exact, as Dangerous Treasures' is: the start hook fires inside the call that creates the event.

  • gc.place { key, event, monument+offsets | x,z[,y] } (a world call's location) runs <command> position <event> x,y,z and answers gc.placed { key, event, repeat, x, z }.

    • The command name is read from Guarded Crate's config (gcrate by default).
    • A key already answered gets its first answer again and places nothing. Keys are kept seven days.
    • Nothing removes a placed crate (D373).
  • Refusals (gc.error):

    • malformed, bad-event, gc-missing
    • npcspawn-missing: Guarded Crate's position does not check NpcSpawn, so without it the crate would land unguarded and free to hack (D364)
    • console-unavailable (D363)
    • the location's own refusals: no-monument, out-of-range, off-map
    • Guarded Crate's own messages, read from its lang file: gc-too-close (another crate within 80 m), bad-position, refused
  • Guarded Crate's own running list, its private EventManager.Instances, is read by reflection because Guarded Crate has no API that lists events. It is used three ways:

    • to seed the map after a hotload
    • to drop the events that its unload or gcrate stop all ended, since neither raises a hook
    • to tell which event a clearing ended

    Where the list can't be read, the hooks alone keep the set, and the log says so once.

  • Hello gains integrations.guardedCrate:

    • { loaded, version, npcSpawn: { loaded, version }, events }
    • events comes from Guarded Crate's data file (CrateEventEntries), not its config.
    • Hello is sent again when either plugin loads or unloads.
  • Tally guardedWon (Warden, D375). Map: map.live's world gains kind: "guarded". rg.world prints the new fields and re-checks the list first.

  • Fix found on the rig: Guarded Crate's cargo plane was announced as Rust's airdrop.called. Planes for which Guarded Crate's own API_IsGuardedCrateCargoPlane returns true are now skipped.

Tested:

  • checkPlugin.js passes (84 hooks) and its 18 tests pass.
  • Compiled and loaded on both rigs (Rust 25902425, Oxide 2.0.7830, Carbon 2.0.262).
  • With Guarded Crate 2.0.17 and NpcSpawn 3.4.8 loaded, on both rigs:
    • rg.world read the four events from the data file, and Guarded Crate's list was readable.
    • gcrate start and gcrate position (in the fully quoted form ConsoleSystem.Run sends) each counted a running crate, with no airdrop.called after the fix.
    • A hotload of the bridge found the running crate again.
    • gcrate stop all took it off.
  • Both rigs were then cleaned of the two plugins and their files, and put back on the protocol-13 bridge.
  • The clearing, the timeout and the step through the sidecar are left to §14.3.5's rows at the end walk.

AI-assisted: written with Claude Code (disclosed per org policy).

🤖 Generated with Claude Code

https://claude.ai/code/session_01E14m6SuuY6i1vASFeGDBeY

Stage 6 of the §14.3 integration plan. Spec: docs `rust-link/PROTOCOL.md` §20.9 and §17.3 (docs PR alongside). Record: `modules/rust/PLAN_REDESIGNS.md` §14.3.19. - **Three events from Guarded Crate's own hooks:** - `gc.started` `{ x, z, key? }` - `gc.ended` `{ steamId?, name?, x?, z? }`: the player who killed the last guard. Both are absent when nobody did (NpcSpawn reloaded, the guards died some other way, or another NPC killed the last one). - `gc.failed` `{ x, z }`: the timeout None is sent while the world is not live. A clearing is still counted. - **The key's join is exact**, as Dangerous Treasures' is: the start hook fires inside the call that creates the event. - **`gc.place` `{ key, event, monument+offsets | x,z[,y] }`** (a world call's location) runs `<command> position <event> x,y,z` and answers `gc.placed` `{ key, event, repeat, x, z }`. - The command name is read from Guarded Crate's config (`gcrate` by default). - A key already answered gets its first answer again and places nothing. Keys are kept seven days. - Nothing removes a placed crate (D373). - **Refusals** (`gc.error`): - `malformed`, `bad-event`, `gc-missing` - `npcspawn-missing`: Guarded Crate's `position` does not check NpcSpawn, so without it the crate would land unguarded and free to hack (D364) - `console-unavailable` (D363) - the location's own refusals: `no-monument`, `out-of-range`, `off-map` - Guarded Crate's own messages, read from its lang file: `gc-too-close` (another crate within 80 m), `bad-position`, `refused` - **Guarded Crate's own running list**, its private `EventManager.Instances`, is read by reflection because Guarded Crate has no API that lists events. It is used three ways: - to seed the map after a hotload - to drop the events that its unload or `gcrate stop all` ended, since neither raises a hook - to tell which event a clearing ended Where the list can't be read, the hooks alone keep the set, and the log says so once. - **Hello** gains `integrations.guardedCrate`: - `{ loaded, version, npcSpawn: { loaded, version }, events }` - `events` comes from Guarded Crate's **data** file (`CrateEventEntries`), not its config. - Hello is sent again when either plugin loads or unloads. - **Tally** `guardedWon` (Warden, D375). **Map:** `map.live`'s `world` gains `kind: "guarded"`. `rg.world` prints the new fields and re-checks the list first. - **Fix found on the rig:** Guarded Crate's cargo plane was announced as Rust's `airdrop.called`. Planes for which Guarded Crate's own `API_IsGuardedCrateCargoPlane` returns true are now skipped. **Tested:** - `checkPlugin.js` passes (84 hooks) and its 18 tests pass. - Compiled and loaded on both rigs (Rust 25902425, Oxide 2.0.7830, Carbon 2.0.262). - With Guarded Crate 2.0.17 and NpcSpawn 3.4.8 loaded, on both rigs: - `rg.world` read the four events from the data file, and Guarded Crate's list was readable. - `gcrate start` and `gcrate position` (in the fully quoted form `ConsoleSystem.Run` sends) each counted a running crate, with no `airdrop.called` after the fix. - A hotload of the bridge found the running crate again. - `gcrate stop all` took it off. - Both rigs were then cleaned of the two plugins and their files, and put back on the protocol-13 bridge. - The clearing, the timeout and the step through the sidecar are left to §14.3.5's rows at the end walk. AI-assisted: written with Claude Code (disclosed per org policy). 🤖 Generated with [Claude Code](https://claude.com/claude-code) https://claude.ai/code/session_01E14m6SuuY6i1vASFeGDBeY
wtclaude added 1 commit 2026-10-15 12:27:36 -05:00
feat(bridge): Guarded Crate on protocol 14 (PLAN_REDESIGNS §14.3.5)
All checks were successful
PR Checks / plugin-checks (pull_request) Successful in 9s
4e83def0dd
Stage 6 of the §14.3 integration plan. Spec: docs rust-link/PROTOCOL.md §20.9.

- gc.started, gc.ended (the clearer, or nobody) and gc.failed from Guarded
  Crate's three hooks; the start's key joins exactly, inside the call.
- gc.place { key, event, location as a world call } runs `<command> position
  <event> x,y,z`; refuses npcspawn-missing itself, since Guarded Crate's
  `position` does not check and the crate would land unguarded (D364).
- The running set is checked against Guarded Crate's private list (by
  reflection): the hotload seed, `stop all` (no hook), and which event ended.
- Hello's integrations.guardedCrate with npcSpawn and the events from its data
  file; the tally's guardedWon (Warden); map.live's guarded rows; rg.world.
- Guarded Crate's cargo plane no longer says airdrop.called.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01E14m6SuuY6i1vASFeGDBeY
whitlocktech merged commit 92915f7de6 into edge 2026-10-15 18:18:45 -05:00
whitlocktech deleted branch feat/guarded-crate 2026-10-15 18:18:46 -05:00
Sign in to join this conversation.
No Reviewers
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: RunicGateway/Rust-Plugins#39
No description provided.