docs(rust): zones and the dome as built — PROTOCOL 19.11, PLAN_REDESIGNS 3.4, D210, D211

PROTOCOL §19.11: world.zone's seven new fields, bad-option and
dome-unavailable, the bridge-said zone messages, the domes helper and
OnRgDomesReady, hello's zoneManager and integrations.zoneDomes.

PLAN_REDESIGNS: §0.6 corrected (ZoneFieldListRaw exists), §3.4 as built,
D210 (flags ticked on a presets page, the step copies a preset's line) and
D211 (the bridge reads the flag list). INSTALL names the new helper.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01E14m6SuuY6i1vASFeGDBeY
This commit is contained in:
2026-09-29 05:25:45 -05:00
parent 18a4a561e3
commit 7f9026c9e7
3 changed files with 151 additions and 3 deletions

View File

@@ -42,7 +42,7 @@ probe plugin that wrote one data file. It was unloaded and deleted afterwards on
| 0.3 | Do groups carry anything the site does not model? | **Parents.** `GetGroupParent` answers on both. The site's `rust_perm_groups` has no parent column. | §1.4 |
| 0.4 | Is there a framework hook for a finished Rust mission (D173)? | **Yes: option 1 of D173's spike.** Oxide's patched `Assembly-CSharp.dll` raises `OnMissionSucceeded`, `OnMissionFailed`, `OnMissionStarted` and `OnMissionAssigned`, and `Carbon.Hooks.Oxide.dll` patches the same four names onto `BaseMission`. Rust's own methods are `BaseMission.MissionSuccess(MissionInstance, BasePlayer assignee)` and `MissionFailed(MissionInstance, BasePlayer, MissionFailReason, bool)`. The catalogues [`HOOKS.md`](HOOKS.md) and [`CARBON.md`](CARBON.md) predate them. The exact hook arguments are confirmed when a person finishes a mission (§5.7). | §5.7 |
| 0.5 | Is ZoneDomes' API safe with a null player (PLAN_FIXES §4.4, §7)? | **No.** `AddNewDome` and `RemoveExistingDome` end with `player.ChatMessage(...)` and no null check. With a null player the dome is made and saved, and then the call throws. On boot, ZoneDomes also drops every dome whose zone does not exist yet, and the bridge's temporary zones are re-created after that. | §3.2 |
| 0.6 | Can ZoneManager's flag list be read at run time? | **Only from inside.** The list is `ZoneManager.ZoneFlags.NameToIndex`, a public static on a nested type. No hook or `Call` method returns it. The zone helper (`RunicGatewayZones.cs`) already references ZoneManager's types, and the bridge may not (R2, D168). | §3.1 |
| 0.6 | Can ZoneManager's flag list be read at run time? | **Only from inside.** The list is `ZoneManager.ZoneFlags.NameToIndex`, a public static on a nested type. No hook or `Call` method returns it. The zone helper (`RunicGatewayZones.cs`) already references ZoneManager's types, and the bridge may not (R2, D168). **Wrong, found at the build (D211):** ZoneManager 3.1.14's API region has `ZoneFieldListRaw()`, which returns the zone field names followed by every `NameToIndex` key, and the bridge calls it by name. | §3.1, §3.4 |
| 0.7 | What does the map actually show? | **85 markers on the rigs' map (world 3000, seed 1234): 31 substations in four prefab kinds, 7 caves in six, 7 train-tunnel entrances in four, and 5 water wells in three.** The label (`Substation`) groups the variants. Rust also classifies monuments itself (`MonumentInfo`'s `MonumentType`: Cave, WaterWell, Lake, Mountain, Radtown, Building, Town, Airport, Lighthouse). | §4 |
| 0.8 | Can the site see how much of a kit players have used? | **One player at a time.** `kits.list` already returns each kit's `max` (MaximumUses) and `cooldown`, and the module ignores `cooldown`. Per-player use is read only during a credit settle (`GetPlayerKitUses`). | §2.6 |
| 0.9 | Where do the Ultima Online examples a Rust admin sees come from (U-3)? | **Core's own actions.** `core.lease` gives `uo.rate.skillgain` as its example, and the announcement actions talk about Britain and Cove. | §2.1 |
@@ -424,6 +424,47 @@ for one with it; the enter and leave messages arrive as chat and then as popups;
reload and a ZoneDomes reload all keep the flags and the dome; expiry and teardown remove the dome from the
world and from ZoneDomes' data file; and with the domes helper removed, the step stops offering a dome.
### 3.4 As built (2026-09-29; not yet walked on a rig)
Built on `edge` as Rust-Plugins `feat/zones-domes`, Module-Rust `feat/zones-domes` and installer
`feat/rust-domes-helper`; the wire is PROTOCOL §19.11. The build changed §3.1 and §3.2 in four places.
- **Where the flags are ticked (D210).** Core's step editor holds one value per field: a text box, a number,
a yes/no, a date, or one dropdown. It has no checkbox list and no slot for a module's own button, and
MODULE_API 1.12.0 (§8) adds neither. So the checkboxes are on a new page, **Admin → Rust zone presets**,
and the step's **Options** field is one line of text (`NoBuild, NoPlayerLoot, radiation=10`). The field's
dropdown lists the presets, and **each row's value is the preset's line**, so picking one writes that
line into the field. Core already writes a dropdown's pick into the free-text field beside it, so this
needed no core change. It keeps §3.1's promise: the step holds its own copy, and editing a preset
changes no published event. There is no **Save as preset** button in the step; a preset is made on its
page. Presets are `rust_zone_presets` (`name`, `flags`, `settings`, `all_servers`) and
`rust_zone_preset_servers`. As with a group (D189), the same name may be used on two servers but not
twice on one.
- **Who reads the flag list (D211).** The bridge does, with `ZoneFieldListRaw()` (§0.6 corrected). The zone
helper gained nothing, and a server without it still offers every flag, so there is no
"name, radius and duration only" mode. The list is in hello, and the bridge sends hello again when
ZoneManager, ZoneDomes or either helper loads or unloads.
- **The dome must wait for ZoneDomes' own start.** ZoneDomes' `InitializeDomes` also re-draws every dome
in its data file whose zone exists. A dome the bridge added before that is drawn twice, and the first
set of spheres is left in the world with nothing able to remove it. The domes helper therefore
postfixes `InitializeDomes` and raises `OnRgDomesReady`, and the bridge puts domes back only after it.
The helper's patch goes in at load, before ZoneDomes' `OnServerInitialized`.
- **A popup falls back to chat at the moment of speaking**, as §2.4 says, and the zone is not refused for
it: a zone's messages are said long after the step ran. (`rust.announce` still refuses a popup without
PopupNotifications, because its line is said at once.)
**Chosen in the build, within the plan:**
- **Settings bounds:** radiation 0–500, comfort 0–1, temperature −100–100 °C.
- **Permission:** up to 32 of `a–z0–9_`.
- **Dome stack:** 1–10. ZoneDomes itself has no limit, and each sphere is an entity.
- **The 5 s quiet:** after re-creating a zone, the bridge stays silent to anyone already inside it.
- **The flag groups:** in `server/model/zones/zoneOptions.js`. `NoTp` and ZoneManager's `Custom1`–`5`
are under Other.
**The walk is §3.3, not yet done.** The rigs' panel file API was down on 2026-09-29, so nothing could be
installed. On the new `rust-oxide` it also needs ZoneManager, ZoneDomes, PopupNotifications and both
helpers installed first. The default dome type and stack are still to be chosen on the rig (§3.2).
---
## 4. The live map's marker types (§4.5; D165)
@@ -916,3 +957,10 @@ The org lead answered §11.4.4's three questions the same day:
These are new verbs, events and hello fields. If they are built before the cutover they join the unreleased
protocol 13 like everything else here; if the cutover comes first, they open protocol 14. Which one is decided
when §9 reaches item 7.
The §3 build raised two more, answered on 2026-09-29:
| # | Decision | Rejected | § |
|---|---|---|---|
| **D210** | **A zone's flags and settings are ticked on an Admin → Rust zone presets page**, and the zone step's Options field copies a preset's line when it is picked. Core is unchanged. | A list param type in core (MODULE_API) drawn as grouped checkboxes; a module-supplied step editor. | 3.4 |
| **D211** | **The bridge reads ZoneManager's flag list** through its API call `ZoneFieldListRaw()` and sends it in hello. A server without the zone helper still offers every flag. | Keeping the read in the zone helper, with a name/radius/minutes-only mode without it. | 3.4 |