docs(rust): stage 1 built — world events on protocol 14 (PROTOCOL §20.5, D378, D379)

- rust-link/PROTOCOL.md §20.5: `world.event` and its 24 types (the type in
  `event`, not the envelope's `type`), the credit block, the tally's two
  counts, `world.call`, hello's `console`, the sidecar forward and the site.
- modules/rust/PLAN_REDESIGNS.md: D378 (the Chinook is called with no
  position) and D379 (`chinook.downed` counts toward Rotorbane), both the org
  lead's on 2026-10-15; §14.3.14, the stage-1 record: the placement spike, the
  seven changes the build found (among them a correction to §14.2.1: Carbon
  refuses plugin console commands only inside a console command, so the
  bridge's own path works), what was settled in the code, the tests and the
  walk rows it adds; pointers from §14.3.1 and §14.3.8.

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-15 00:39:01 -05:00
parent 0ada1e4f26
commit adf197e5f8
2 changed files with 229 additions and 2 deletions

View File

@@ -928,7 +928,8 @@ pulls) is research, not a walk, so it still comes first:
9. **Rust's own world events and six more optional plugins** (§13, §14). First comes one test phase covering
all of them on both rigs (§14.2, D352); **it ran on 2026-10-14 (§14.2.1)**. Then one integration plan,
answered before code: **written on 2026-10-14 as §14.3**, from D361–D369, and answered as D370–D376. Then the
build, in §14.3.11's nine stages (two of them core), §13 first.
build, in §14.3.11's nine stages (two of them core), §13 first. **Stage 1, §13, was built on 2026-10-15
(§14.3.14)**, with D378 and D379.
**Then one walk, on Oxide and Carbon, of everything still owed (D331):** §2.7; §11's rows; §12.9; §13's and
§14's rows; the in-game rows
@@ -1090,6 +1091,8 @@ The org lead answered §14.3's Q26–Q32 on 2026-10-14:
| **D375** | **Three new titles (Q31):** *Treasure Hunter* (DT treasures won), *Warden* (guarded crates cleared), *Hoarder* (the most RP, above 0), renamable, each with a column on servers that report the plugin. | No titles for the plugins' counts. | 14.3.4, 14.3.5, 14.3.7 |
| **D376** | **A public line names a player only for the presence audience (Q32):** the event and its grid are public (*"Patrol helicopter downed at G8"*), and the name shows only to the audience the operator chose for presence. | The name always public (D353 as written); the whole line hidden below the presence audience. | 14.3.1 |
| **D377** | **The leaderboard changes only for something new and substantial.** A new title may add its column (*Safecracker*, *Scavenger*, *Treasure Hunter*, *Warden*, *Hoarder* do), but a small plugin's own numbers, such as ZLevels' levels, never become columns (org lead, 2026-10-14, confirming D374 beside D375). | Adding a column for every number a plugin reports. | 14.3.1, 14.3.6 |
| **D378** | **The Chinook is called with no position.** It drops only at the map's own drop zones (seven on the rigs' map, all at monuments), and the one route that sends it to a chosen zone borrows the Airfield call terminal's shared state, so a player at the real terminal and a step calling at once would race for one Chinook (stage 1's spike, org lead 2026-10-15). The airdrop and the patrol helicopter take a position. | A position snapped to the nearest drop zone through the terminal's state, refused while a real Airfield call is active. | 14.3.1, 14.3.14 |
| **D379** | **`chinook.downed` is a 24th world event**, with the credit block and the operator's rule, and counts toward *Rotorbane*: D174 counted Chinook kills there, and the plan's first draft would have dropped them (org lead, 2026-10-15). | Counting Chinook kills through the old tally, with no line; patrol helicopters only. | 14.3.1, 14.3.14 |
## 11. First-class optional plugins (D199–D202)
@@ -2361,6 +2364,11 @@ not touched:** `requires_plugins` stays Kits, ZoneManager and RunicNPC, and none
#### 14.3.1 Rust's own world events (§13; D349, D353–D356, D366, D367)
> **Built as stage 1 (§14.3.14), with seven changes the build found.** The one that matters to a reader of the
> examples below: **a world event's type is in `event`, not `type`**, which is the envelope's. There are
> **24 types** with `chinook.downed` (D379); the Chinook takes no position (D378); `airdrop.called` comes
> from the plane's spawn. [PROTOCOL.md](../../rust-link/PROTOCOL.md) §20.5 is the wire as built.
**Hello.** Nothing new: the events need no plugin. Hello gains one fact the steps below need, **`console`**:
`{ plugins: true | false }`, found at load by running one of the bridge's own read-only commands through
`ConsoleSystem.Run`, the route a plugin command takes. On Carbon 2.0.262 it is `false` (D363), and the site
@@ -2673,7 +2681,7 @@ in the app; wipe and see the points stay.
| Kind | New in protocol 14 |
|---|---|
| Hello | `console.plugins`; `integrations.truePve`, `dynamicPvp`, `dangerousTreasures`, `guardedCrate` (with `npcSpawn`, `events`), `zLevels`, `serverRewards` |
| Events | `world.event` (23 types); `pvp.zone.created` / `deleted`; `dt.started` / `won` / `ended`; `gc.started` / `ended` / `failed` |
| Events | `world.event` (24 types with `chinook.downed`, D379; the type in `event`, §14.3.14); `pvp.zone.created` / `deleted`; `dt.started` / `won` / `ended`; `gc.started` / `ended` / `failed` |
| Commands | `world.call`; `dt.start`; `gc.place`; `points.pay` / `balances` / `adjust`; `world.zone`'s `truePve` |
| Tally | `cratesHacked`, `dropsLooted`, `treasuresWon`, `guardedWon`; `points` (a value). **`heliKills` and `apcKills` leave the tally**: the site counts them from `world.event`'s `credit` (D372) |
| `map.live` | `world` kinds `treasure` and `guarded`; the `pvp` layer |
@@ -2814,6 +2822,79 @@ ten minutes"*.
**Tests (website).** The delay honoured; clamped at both ends; counted as an attempt; no retry for a run paused
or cancelled in the wait; `MODULE_API.md` and the classify rules updated.
#### 14.3.14 Stage 1, built: Rust's own world events (2026-10-15)
Built on `edge` in Rust-Plugins, Rust-Link and Module-Rust, specified in
[PROTOCOL.md](../../rust-link/PROTOCOL.md) §20.5, on Rust 25902425, Oxide 2.0.7830 and Carbon 2.0.262 (the
latest of each that day). Walked at the end with everything else (D331).
**The placement spike (research, D331).** A throwaway plugin on both rigs called each event at a chosen point by
the routes the game itself has, and measured where it went:
| Event | Route | Result |
|---|---|---|
| Airdrop | `CreateEntity(cargo_plane)`, `InitDropPosition(point)`, then `Spawn()` | Released **0–1 m** above the point on both rigs; lands there. The plane crosses a 6000 map in about 480 s and drops at half way |
| Patrol helicopter | `PatrolHelicopterAI.SetInitialDestination(point)` **before** `Spawn()`, so `ServerInit` skips its random start | Came within **10–54 m** of the point after 65–165 s, then patrolled as usual |
| Chinook | It drops only at the map's `CH47DropZone`s (seven, all at monuments). Its brain's interest point: it orbited the zone 110 s and left without dropping (a drop needs it five minutes old). The Airfield terminal's statics, set 5 s after spawn: dropped 5 m from the zone. Set before spawn: it dropped at its offshore spawn and vanished | **No position (D378)**: the working route is the real terminal's shared state |
| Cargo leaving | `cargoship.egress` | **`OnCargoShipEgress` fires** on both frameworks (a natural one was seen on Oxide); the kill follows after `egress_duration_minutes`. So `cargo.left` is the egress |
**What changed from §14.3.1 as planned, each found by the build:**
1. **The type is `event`, not `type`.** §14.3.1's example wrote `"type":"heli.downed"`, but `type` is the
envelope's and the sidecar files on it: the rig's sidecar dropped every world event as untyped, the same
collision protocol 13's `world.expired` had (§19). Every frame says `"type":"event","event":"heli.downed"`.
2. **`airdrop.called` comes from the cargo plane's spawn.** The console's `supply.call` raised neither
`OnAirdrop` nor `OnCargoPlaneSignaled`, so a line from those hooks would miss it. They now only say who and
where; the drop point is otherwise read from the plane.
3. **A Bradley's `where` is told by the game's spawners**, not by `RoadSpawned`, which defaults to true (a
plugin's Bradley would read as a road one): Launch Site's when `BradleySpawner.singleton` holds it, road when
the road event's list does. **A Bradley neither holds is `other`**; its spawn says nothing, but its death is
sent and counts toward Tankbreaker, as it did under D174.
4. **`chinook.downed` (D379).** D174 counted Chinook kills toward Rotorbane; they keep counting, by the rule.
5. **The Chinook's drop is joined at the crate's landing.** The crate a Chinook drops has no net id when
`OnCrateDropped` fires (it is made just before its spawn), so the drop is joined to the crate that lands
under it within 40 m and 120 s.
6. **`world.call` runs one of the schedule's events at random, as `EventSchedule.Trigger` does, but not
`Trigger`**, which would also reset the schedule's clock: calling an airdrop must not delay the next natural
one. The schedule is found whether or not it is enabled.
7. **Carbon's console, corrected.** §14.2.1 found Carbon 2.0.262's `ConsoleSystem.Run` answers "not found" to
every plugin command. Stage 1 found that holds only for a call **inside a console command**, or in a
`NextTick` a console command queued, which is how §14.2's spike ran every test (`rgs.cmd …`). From a timer,
and from a `NextTick` queued by a background thread — **the bridge's own path for every website command** —
Carbon finds plugin commands, `c.version` included. So the console probe (D363) runs from a timer, and reads
**true on both rigs**. It also suggests D180's Carbon reload works from the website after all, and that
Rust-Plugins#34 describes the spike's context rather than the bridge's; the end walk confirms it.
**Settled in the code, and overrulable:**
- **A position never leaves the module.** The feed sends a grid; `x` and `z` reach staff only, because the map
has its own audience for where things are (D111).
- **`EventsMaxWorldCalls`** defaults to its ceiling, 10 per run per server.
- **The credit rule is on the server's settings** (Admin → Rust → the server, *World events*), and an unknown
stored word reads as the default, the killing blow.
- **`damage` is the damage each hit reported**, summed, and a credit block names at most 32 damagers.
- **The feed gains a *World events* filter**, and the two leaderboard columns sort.
- **A trigger's `player`, for a downed one, is the credited names as a phrase** (*"Alice, Bob and 2 others"*),
by the server's rule; `credited` is how many.
- **A step's answer** says how many the game started (`called`), and a note when it started fewer than asked.
**Tests.** Bridge: `checkPlugin.js` (76 hooks, every one void and listed) and a new check that the console probe
names a command the plugin declares, 18 tests. Compiled and loaded on both rigs; `heli.arrived`,
`cargo.arrived` and `airdrop.called` read back from each rig's sidecar store, and hello's
`console.plugins` on both. Sidecar: 71 tests, `fmt` and `clippy` clean. Module-Rust: 585 server tests (22 new
in `test/worldEvents.test.js`: the catalogue against the protocol's 24 types, D372's four rules against one
block and against one with nobody, the line and the count agreeing under every rule, the per-viewer reading,
the grid off the map, ingest, the triggers and their variables, the step's bounds and refusals), 84 client
tests, every check, and a boot against the pinned core (43 triggers, 12 actions, 10 budgets, 20 option sources;
the 89 routes unchanged).
**Walk rows added to §14.3.1's:** the Travelling Vendor (the spike's schedule run raised no spawn on the rig);
the road Bradleys' line (twelve were already out, so none came); the console probe after a `c.reload` typed in
Carbon's console; and a configuration save's reload from the website on Carbon (D180), which settles item 7.
**Not changed:** the Android app. It reads the API leniently, so it shows neither world events nor the two
columns until it learns them.
### 14.4 Questions for the org lead
**Answered on 2026-10-14:** Q17 as proposed, out (D358). **Q18 against the proposal: the end walk waits for