docs(rust): stage 3 built — TruePVE in the zone step (PROTOCOL §20.6, PLAN_REDESIGNS §14.3.16)

- rust-link/PROTOCOL.md §20.6: hello's integrations.truePve, world.zone's
  truePve (exactly one of exclude and ruleset, all or nothing, the
  refusals), the unmapping on every erase path with truepve.json for
  while TruePVE is away, rg.world's two fields, and the website's two
  params. The §15 command table points at it.
- modules/rust/PLAN_REDESIGNS.md §14.3.16: the stage-3 record, ten points
  settled in code (all overrulable), TruePVE's one-second save, the tests
  and the rig compile. Pointers from §9's summary and §14.3.2.

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 05:47:27 -05:00
parent bf2524aa6c
commit 65c57cec36
2 changed files with 101 additions and 2 deletions

View File

@@ -1436,7 +1436,7 @@ five routes.
| Command | Answers | |
|---|---|---|
| `world.monuments` | `world.monuments` | This map's monuments in one stable order (grouped by prefab short name, then by position). Each has `value` (`kind`, or `kind#n` when the kind repeats), `kind`, `instance`, `of`, `label` (the game's display phrase), `x`, `z` and `grid`. Also `worldSize`, the placeable `prefabs` (`key`, `kind`, `label`), `eventsEnabled`, `maxCrates`, `maxNpcs` and `zoneManager` |
| `world.zone` | `world.ok` or `world.error` | Opens a ZoneManager temporary zone owned by the bridge. Needs `runId`, `key`, a location, `radius` (5–150 m) and `holdMs` (1 minute to 7 days); `name` is optional. Protocol 13 adds `flags`, `settings`, `enterMessage`, `leaveMessage`, `delivery`, `format` and `dome` (§19.11) |
| `world.zone` | `world.ok` or `world.error` | Opens a ZoneManager temporary zone owned by the bridge. Needs `runId`, `key`, a location, `radius` (5–150 m) and `holdMs` (1 minute to 7 days); `name` is optional. Protocol 13 adds `flags`, `settings`, `enterMessage`, `leaveMessage`, `delivery`, `format` and `dome` (§19.11); protocol 14 adds `truePve` (§20.6) |
| `world.place` | `world.ok` or `world.error` | Places `count` of one allowlisted `prefab` at a location, scattered within `spread` m (0–50, 10 by default for a group). All or nothing: if the game refuses one, the ones already made are killed. Protocol 13 adds `profile`, a RunicNPC profile in place of a prefab (§19.12), and for a profile `escort`, `ally` and `tether` (§19.13) |
| `world.revert` | `world.ok` | Gives back what a run owns: the named `ids`, or else everything under `key`, or else everything the run owns. The answer lists `removed`, `gone` and `refused` |
| `world.owned` | `world.owned` | What the world still holds of what events made, **looked for** by net id or zone id, narrowed by `runId`. Anything gone is pruned from the registry as the walk passes it |
@@ -3019,3 +3019,59 @@ is every website command's path. On both rigs it reads `true`. Hello is sent aga
- **The tally's two counts** in `rust_player_wipe_stats.crates_hacked` and `.drops_looted`; title categories
`crateshacked` (*Safecracker*) and `dropslooted` (*Scavenger*); leaderboard columns *Crates hacked* and *Drops
looted*, sortable (`sort=cratesHacked`, `sort=dropsLooted`).
### 20.6 TruePVE in a zone — `world.zone`'s `truePve` (§14.3.2, D362, D368)
nivex's **TruePVE** (2.4.6, uMod), optional like Economics (D199) and not in `overlay.toml`. A zone an event
opens may ask TruePVE to leave it alone, or to use one of the operator's rulesets inside it. The design is
[`PLAN_REDESIGNS.md`](../modules/rust/PLAN_REDESIGNS.md) §14.3.2, and what §14.2's test found, which shapes it,
is §14.2 there. None of TruePVE's hooks is used.
**Hello and status.** `integrations` gains `truePve`:
```json
"truePve": { "loaded": true, "version": "2.4.6" }
```
Hello is sent again when TruePVE loads or unloads.
**`world.zone` gains an optional `truePve`** (the rest of the zone is §15 and §19.11):
```json
{"cmd":"world.zone","reqId":"r-4","runId":"13","key":"9c1e…","monument":"airfield_1","radius":40,
"holdMs":1800000,"truePve":{"exclude":true}}
{"cmd":"world.zone","reqId":"r-5","runId":"13","key":"0b7d…","monument":"launch_site_1","radius":60,
"holdMs":1800000,"truePve":{"ruleset":"pvp-arena"}}
```
- **Exactly one of `exclude` and `ruleset`.** `exclude` is `true` or left out; `ruleset` is 1–64 characters
after trimming, passed as written, because TruePVE matches its names case-sensitively. Both, neither, a
non-object or a blank name is **`malformed`**.
- **TruePVE not loaded** is **`truepve-missing`**, before anything is made.
- **All or nothing.** The bridge makes the zone, and its dome when asked, then calls
**`AddOrUpdateMapping(zoneId, "exclude" | ruleset)`**. TruePVE answers false for a ruleset it does not have,
and nothing else lists the names, so the call is the check (D368). A false erases the dome and the zone
just made and answers **`truepve-ruleset`** with the name, or **`refused`** for `exclude` (TruePVE not ready).
- The registry entry keeps the mapping it was given (`TruePve`), so a mapping is only ever removed for a zone
this plugin mapped. **Re-creating a zone** (a restart, a hot reload, a ZoneManager reload, §19.11) maps
nothing again: TruePVE keeps its table in its own data file, and the zone keeps its id.
**The unmapping lives with the zone (D362).** TruePVE prunes a mapping whose zone is gone only when the zone
id is a number, and ours are `rg-…`. So every path that erases one of our zones calls **`RemoveMapping`**
first: its deadline (checked every second, with the site down too, §15.3), `world.revert`, a zone that
`world.owned` finds ZoneManager no longer holds, and a new wipe dropping the old map's entries. When TruePVE is not loaded at
that moment, the id goes into **`data/RunicGateway/truepve.json`**, and the bridge removes each one at
`OnPluginLoaded(TruePVE)` (TruePVE has read its table in `Init` by then) and at its own load. The file is
deleted when it is empty.
**Status.** `rg.world` prints `truePve=` (loaded) and `truePveLeftover=` (ids waiting in `truepve.json`).
**The sidecar** forwards `world.zone` whole, as before; nothing in it changed.
**The website (Module-Rust).** `rust.zone.open` gains **`noPvpProtection`** (a boolean, *"No PvP protection in
this zone"*) and **`pvpRuleset`** (a string, *"or this TruePVE ruleset"*). Setting both is refused, as is a
name over 64 characters, and either one is refused where the server's last hello said TruePVE is not loaded
(*"TruePVE is not installed on this server"*); all three at verify too. A server whose hello has not said
(a plugin before protocol 14, or never reached) is left to the plugin. `truepve-missing` and
`truepve-ruleset` fail the step for good, with the plugin's words. Server settings' plugin line says whether
TruePVE is loaded.