From a34b5fdbf0d5b5fdd47cf288b460331e763a9f22 Mon Sep 17 00:00:00 2001 From: wtclaude Date: Mon, 28 Sep 2026 12:18:33 -0500 Subject: [PATCH] =?UTF-8?q?docs(rust):=20record=20the=20RaidableBases=20he?= =?UTF-8?q?lper=20spike=20(=C2=A711.4.4)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit One base despawns alone; overrides go in at OpenEvent through a deep copy; lock-to-first-attacker is main-config only; an admin-given spot and height work through a copied profile (Clone() is shallow and leaked); the area check misses water; reloads drop Harmony patches. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01E14m6SuuY6i1vASFeGDBeY --- modules/rust/PLAN_REDESIGNS.md | 70 ++++++++++++++++++++++++++++++++-- 1 file changed, 66 insertions(+), 4 deletions(-) diff --git a/modules/rust/PLAN_REDESIGNS.md b/modules/rust/PLAN_REDESIGNS.md index cc31f03..35b0537 100644 --- a/modules/rust/PLAN_REDESIGNS.md +++ b/modules/rust/PLAN_REDESIGNS.md @@ -823,10 +823,72 @@ The org lead answered the spike's three questions the same day: guarantees: the write is recorded, a reload is watched, and a failed load rolls back (D178, D179). The reload is `rb.reloadprofiles`, which the spike ran on both rigs, not a plugin reload. -**Still to settle in the build's own spike:** exactly which internal routine the helper calls to despawn one -base, and which settings it can override after `Started`, on both editions. Also the one-at-a-time rule: the -step refuses to spawn a second base of the same name on a server while a first one is waiting to start, -because the free edition's bases have no ids to tell them apart. +**Still to settle in the build's own spike:** the same helper questions on Carbon and on the paid edition. +Also the one-at-a-time rule: while a first base of the same name is still waiting to start on a server, the +step refuses to spawn a second one, because the free edition's bases have no ids to tell them apart. +§11.4.4 may retire that rule. + +#### 11.4.4 The helper spike (2026-09-28) + +The org lead asked for two tests of a D168 helper before the build: can it despawn one base, and which +settings can it override? A third question came with them: can an admin give the spot, meaning x, z and a +height adjustment? The spike ran on the rust-oxide rig against the free edition, 3.2.0. Carbon and the paid +edition are still to run (§11.4.2). Every finding below reaches RaidableBases' internals by reflection and a +Harmony patch. None of it is public API, so the helper has to check the plugin's version at hello, as the +zone helper does. + +- **Despawning one base works.** The plugin keeps its live bases in a list on the plugin, and each base has + its own `Despawn()`. Calling it on one base removed that base and no other. It fired the usual + `OnRaidableBaseDespawn` and `OnRaidableBaseDespawned` hooks, so the bridge's feed sees nothing new. +- **The helper can know exactly which base is the event's.** A Harmony postfix on the plugin's `OpenEvent` + receives the new base object itself. The helper can tag it for the run at birth, instead of matching the + position and spawn time `Started` reports afterwards (D204). The one-at-a-time rule above may then go, + if the build confirms it on Carbon and the paid edition. +- **Overrides go in at `OpenEvent`, not after `Started`.** At `OpenEvent` the base holds a reference to its + profile's settings object, which every base of that profile shares. The helper swaps in a deep copy (a + JSON round trip), changed for this spawn. The shared profile was checked afterwards and was untouched. + Proven on the rig: + - PvP on/off; + - despawn minutes (inactive and total, via the profile's own "override config" switch); + - NPCs on/off, and the scientist and murderer counts. +- **Lock-to-first-attacker is not a profile setting.** It lives in RaidableBases' main config, in two + pairs of switches (PvP and PvE): one pair for "Manual" bases, which is what `rbevent` and the helper + spawn, and one pair for scheduled bases. A per-event lock would need a second Harmony patch, on the + base's `BypassUseOwners()`. Not built; a question for the org lead. +- **An admin-given spot works.** The helper builds the same spawn request the plugin's own "spawn where I + look" command builds, from numbers instead of a player's view. It then calls the plugin's paste. Bases + landed at the given x and z every time. +- **Height has to go through a copy of the profile.** The plugin recomputes y at paste time from the + ground (or water), plus the building's own height, plus the profile's paste height adjustment. It + ignores any y it is handed, unless the profile forces a height. So the helper copies the profile: + - an adjustment is added to the copy's paste height adjustment; + - an absolute y turns on the copy's forced height. + + Results, measured as the height of the base's building blocks: + + | Request | Blocks at | Ground there | + | --- | --- | --- | + | no adjustment | 1–4 | −0.2 | + | +5 | 6–9 | −1.1 | + | absolute y = 30 | 31–34 | 0.5 | + | a plain `rbevent` spawned right after | 1–4 | −0.2 | + + **Trap:** the plugin's own `BuildingOptions.Clone()` is a shallow `MemberwiseClone`. The first run changed + the height through that clone, and the change leaked into the shared profile: the next plain `rbevent` + base spawned 35 m up. The height settings sit in a nested object, so the helper must copy that too, or + use the same deep copy as the overrides. Nothing reached the file on disk, and `rb.reloadprofiles` reset + the leak. +- **The plugin's area check catches buildings, but not water.** Its safety check, run at an admin's spot, + refused a player's building and refused an existing raid base. At 25 m away from the building it passed. A + spot on the seabed 50 m under water also passed: the plugin tests water in its own location picker, not + in this check. So an admin-given spot needs the helper's own water and terrain test as well as the + plugin's check. The spike reported the check but did not enforce it; whether to enforce is a question + for the org lead. +- **A RaidableBases reload drops the helper's Harmony patches**, because the patched methods belong to the + old assembly. The helper must re-patch in `OnPluginLoaded`, as the zone helper does for ZoneManager. +- **After a server boot the plugin refuses every spawn for about 50 s**, until its log says "Grid + initialization completed". This includes the helper's spawns. The step has to wait for that, not fail + on it. ### 11.5 Protocol