docs(rust): the RaidableBases spikes, and D203-D208 #294

Merged
whitlocktech merged 3 commits from docs/rust-raidablebases-spike into main 2026-09-29 00:18:45 +00:00
Member

What & why

The org lead asked on 2026-09-28 how RaidableBases' many options fit the event system. They didn't fit yet; only D202's one-line plan existed.

This PR records two spikes and the decisions that came out of them, in modules/rust/PLAN_REDESIGNS.md §11.4.1–§11.4.5:

  • a spike of the free edition on both rigs, which led to D203–D205;
  • a helper spike on the Oxide rig, which led to D206–D208.

Tracking: Module-Rust#21.

Findings (RaidableBases 3.2.0 free + CopyPaste 4.3.0, Oxide and Carbon)

  • CopyPaste is required, and no base files ship. The default profile names bases RaidBase1–5, which don't exist, and a base with no box is thrown away at once. The spike made RaidBase1 from the walk hut.
  • Public API: IsPremium, GetAllDifficulties (free: Normal), GetAllEvents (it warns that its shape will change) and EventTerritory. Nothing spawns a base, despawns one or lists profiles.
  • Hooks: Started, Ended, Completed, Despawn, Despawned and PrivilegeDestroyed share one 17-argument shape. It binds on both frameworks.
  • The only way to spawn from outside is the console's rbevent <base>, which places the base where RaidableBases chooses. Every base's id is "0".
  • Despawning from outside is all-or-nothing (rbevent despawnall). Left alone, a base despawns on its profile's timer.
  • Boot cost: 6.7 s (Oxide) and 7.9 s (Carbon) on the main thread, then about 50 s of grid building during which spawns are refused.
  • Each profile has 100+ settings, and the profiles live in the plugin's data folder.

The helper spike (§11.4.4; Oxide, free edition)

  • One base can be despawned alone, through its own Despawn(). The usual despawn hooks fire.
  • Overrides work: PvP, despawn minutes, NPCs on/off and their counts. They go in at OpenEvent, through a Harmony postfix and a deep copy of the profile's settings. The shared profile is left untouched.
  • Lock-to-first-attacker lives only in RaidableBases' main config, not in a profile.
  • An admin-given spot works; bases landed at the exact x and z. Height has to go through a copied profile, either as an adjustment or as a forced exact height.
    • Trap: BuildingOptions.Clone() is shallow. The first run's height change leaked into the shared profile until the nested Setup object was copied too.
  • The area check refuses a player's building and an existing raid base, but lets a spot 50 m under water through.
  • A RaidableBases reload drops Harmony patches, so the helper has to re-patch in OnPluginLoaded.

Decided (§11.4.3, §11.4.5)

D203 By default, RaidableBases picks where an event's base goes; the site shows it once it starts.
D204 A helper, RunicGatewayRaids.cs, despawns only the event's base. Without the helper, the base expires on its own timer.
D205 A step picks a profile and a difficulty, and may add per-event overrides through the helper. The site's config page edits RaidableBases' profiles, as a named exception to the rule that it never walks a data folder.
D206 Lock-to-first-attacker is set per event, by a patch on BypassUseOwners() that applies to the event's base only.
D207 A step places its base where RaidableBases picks (the default) or at an admin-given spot: x and z, plus a height adjustment or an exact height.
D208 A blocked spot is refused, and the reason is given (player building, raid base, in water). The editor runs the same check when the step is saved.

§11.4.2 stays open for the paid edition, which the org lead will supply later this week. That spike, and the helper spike, get rerun there and on Carbon.

How it was tested

Docs only. Every figure comes from the spikes' logs.

Afterwards, the spikes, RaidableBases and CopyPaste were unloaded and deleted on both rigs, and the box placed in the walk hut was removed. Two things were left behind on purpose: the RaidBase1 CopyPaste file, and the configs the plugins wrote on first load.

Checklist

  • I have read CONTRIBUTING.md.
  • The change builds and existing tests/checks pass locally.
  • I have added or updated tests/docs where it makes sense.
  • My commits are reasonably scoped with clear messages.

AI-assisted contributions (required)

  • No AI tools were used to produce this contribution.
  • AI tools were used. Tool(s): Claude Code (Claude Opus 5.5). I have reviewed and understand
    every change, and take responsibility for it. AI-authored commits are
    marked with a Co-Authored-By / Assisted-By trailer.

License

  • I agree that my contribution is licensed under this project's license
    (GNU GPL v3.0 or later), and I have the right to contribute it.

🤖 Generated with Claude Code

https://claude.ai/code/session_01E14m6SuuY6i1vASFeGDBeY

## What & why The org lead asked on 2026-09-28 how RaidableBases' many options fit the event system. They didn't fit yet; only D202's one-line plan existed. This PR records two spikes and the decisions that came out of them, in `modules/rust/PLAN_REDESIGNS.md` §11.4.1–§11.4.5: - a spike of the **free edition** on both rigs, which led to D203–D205; - a **helper** spike on the Oxide rig, which led to D206–D208. Tracking: Module-Rust#21. ### Findings (RaidableBases 3.2.0 free + CopyPaste 4.3.0, Oxide and Carbon) - **CopyPaste is required, and no base files ship.** The default profile names bases `RaidBase1–5`, which don't exist, and a base with no box is thrown away at once. The spike made `RaidBase1` from the walk hut. - **Public API:** `IsPremium`, `GetAllDifficulties` (free: `Normal`), `GetAllEvents` (it warns that its shape will change) and `EventTerritory`. **Nothing spawns a base, despawns one or lists profiles.** - **Hooks:** Started, Ended, Completed, Despawn, Despawned and PrivilegeDestroyed share one 17-argument shape. It binds on both frameworks. - **The only way to spawn from outside is the console's `rbevent <base>`,** which places the base where RaidableBases chooses. Every base's id is `"0"`. - **Despawning from outside is all-or-nothing** (`rbevent despawnall`). Left alone, a base despawns on its profile's timer. - **Boot cost:** 6.7 s (Oxide) and 7.9 s (Carbon) on the main thread, then about 50 s of grid building during which spawns are refused. - **Each profile has 100+ settings**, and the profiles live in the plugin's **data** folder. ### The helper spike (§11.4.4; Oxide, free edition) - **One base can be despawned alone**, through its own `Despawn()`. The usual despawn hooks fire. - **Overrides work:** PvP, despawn minutes, NPCs on/off and their counts. They go in at `OpenEvent`, through a Harmony postfix and a deep copy of the profile's settings. The shared profile is left untouched. - **Lock-to-first-attacker lives only in RaidableBases' main config**, not in a profile. - **An admin-given spot works;** bases landed at the exact x and z. Height has to go through a copied profile, either as an adjustment or as a forced exact height. - **Trap:** `BuildingOptions.Clone()` is shallow. The first run's height change leaked into the shared profile until the nested `Setup` object was copied too. - **The area check refuses a player's building and an existing raid base, but lets a spot 50 m under water through.** - **A RaidableBases reload drops Harmony patches**, so the helper has to re-patch in `OnPluginLoaded`. ### Decided (§11.4.3, §11.4.5) | | | |---|---| | **D203** | By default, RaidableBases picks where an event's base goes; the site shows it once it starts. | | **D204** | A helper, `RunicGatewayRaids.cs`, despawns **only** the event's base. Without the helper, the base expires on its own timer. | | **D205** | A step picks a **profile and a difficulty**, and may add **per-event overrides** through the helper. The site's config page **edits RaidableBases' profiles**, as a named exception to the rule that it never walks a data folder. | | **D206** | Lock-to-first-attacker is set **per event**, by a patch on `BypassUseOwners()` that applies to the event's base only. | | **D207** | A step places its base where **RaidableBases picks** (the default) **or at an admin-given spot**: x and z, plus a height adjustment or an exact height. | | **D208** | A **blocked spot is refused, and the reason is given** (player building, raid base, in water). The editor runs the same check when the step is saved. | **§11.4.2 stays open for the paid edition**, which the org lead will supply later this week. That spike, and the helper spike, get rerun there and on Carbon. ## How it was tested Docs only. Every figure comes from the spikes' logs. Afterwards, the spikes, RaidableBases and CopyPaste were unloaded and deleted on both rigs, and the box placed in the walk hut was removed. Two things were left behind on purpose: the `RaidBase1` CopyPaste file, and the configs the plugins wrote on first load. ## Checklist - [x] I have read [CONTRIBUTING.md](CONTRIBUTING.md). - [x] The change builds and existing tests/checks pass locally. - [x] I have added or updated tests/docs where it makes sense. - [x] My commits are reasonably scoped with clear messages. ## AI-assisted contributions (required) - [ ] No AI tools were used to produce this contribution. - [x] AI tools were used. Tool(s): `Claude Code (Claude Opus 5.5)`. I have reviewed and understand every change, and take responsibility for it. AI-authored commits are marked with a `Co-Authored-By` / `Assisted-By` trailer. ## License - [x] I agree that my contribution is licensed under this project's license (**GNU GPL v3.0 or later**), and I have the right to contribute it. 🤖 Generated with [Claude Code](https://claude.com/claude-code) https://claude.ai/code/session_01E14m6SuuY6i1vASFeGDBeY
wtclaude added 1 commit 2026-09-28 16:57:05 +00:00
The free edition (3.2.0) on both rigs with CopyPaste: its public API, the
17-argument lifecycle hooks, spawning only through `rbevent` at a spot the
plugin picks, base ids always "0", despawn only all-at-once, the boot
hitch and grid wait, and the profile options. Section 11.4.2 is left for
the paid edition the org lead supplies later in the week.

D203 RaidableBases picks where; D204 a helper despawns only the event's
base; D205 profile + difficulty + per-event overrides, and the site edits
RaidableBases' profiles as a named exception.

Refs RunicGateway/Module-Rust#21

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01E14m6SuuY6i1vASFeGDBeY
wtclaude added 1 commit 2026-09-28 17:18:40 +00:00
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 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01E14m6SuuY6i1vASFeGDBeY
wtclaude added 1 commit 2026-09-28 17:20:37 +00:00
Lock-to-first-attacker per event via a BypassUseOwners patch; a step places
its base where RaidableBases picks or at an admin-given spot with a height
adjustment or exact height; a blocked spot is refused with the reason.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01E14m6SuuY6i1vASFeGDBeY
wtclaude changed title from docs(rust): the RaidableBases spike, and D203-D205 to docs(rust): the RaidableBases spikes, and D203-D208 2026-09-28 17:21:12 +00:00
whitlocktech merged commit 18a4a561e3 into main 2026-09-29 00:18:45 +00:00
whitlocktech deleted branch docs/rust-raidablebases-spike 2026-09-29 00:18:46 +00:00
Sign in to join this conversation.
No description provided.