docs(rust): RaidableBases deferred for the current paid copy; both editions supported (D347, D348) #344

Merged
whitlocktech merged 1 commits from docs/rust-raidablebases-editions into main 2026-10-14 09:35:35 +00:00

View File

@@ -11,7 +11,7 @@ chose neither route: Runic Gateway writes its own NPC plugin, RunicNPC, planned
[`../../runicnpc/PLAN.md`](../../runicnpc/PLAN.md) (D214–D314), and the rest of this plan waits for it.** RunicNPC v1.0.0 shipped on 2026-10-09, and the plan
resumed with §2 the same day (D331–D334); §2 was built on 2026-10-12, and §11's Economics spike the same day
raised D335–D336 (§11.2.1). Economics was built on 2026-10-12 too (§11.2.4). The Backpacks spike followed and raised D337–D339 (§11.3.1), and Backpacks was built the same day (D340, D341, §11.3.4). The org lead then added permission rewards (§12,
D342–D346), planned the same day. **Every item left is built, tested and PR'd first; every walk —
D342–D346), planned and built the same day. On 2026-10-14 RaidableBases was deferred until the current paid copy arrives (D347), with both editions to be supported (D348, §11.4.2). **Every item left is built, tested and PR'd first; every walk —
theirs and the ones still owed by §3 and §5 — happens together at the end (D331, §9).**
This is a companion to [`PLAN_FIXES.md`](PLAN_FIXES.md) and [`PLAN.md`](PLAN.md). Where they disagree, this
@@ -919,7 +919,8 @@ pulls) is research, not a walk, so it still comes first:
6. **The step editor and the kit weekend** (§2). It is core's, so it can be built alongside any of the above.
It goes out as its own website PR with the Module-uo proof.
7. **The first-class optional plugins** (§11): Economics, then Backpacks, then RaidableBases, each starting
with its source pull and rig spike.
with its source pull and rig spike. Economics and Backpacks were built on 2026-10-12. **RaidableBases waits
for the current paid copy (D347)** and is built for both editions (D348).
**Then one walk, on Oxide and Carbon, of everything still owed (D331):** §2.7; §11's rows; the in-game rows
of §5.7 and §3.4; PLAN_FIXES §8's re-walk, including the Carbon pass of the first player walk. What it finds
@@ -1019,6 +1020,13 @@ module does not have, and R9 keeps item icons out of the asset bridge.
Permission rewards, added on 2026-10-12, were decided as D342–D346; they are tabled with their section, in §12.8.
Reading the paid edition (§11.4.2) raised two more, answered on 2026-10-14:
| # | Decision | Rejected | § |
|---|---|---|---|
| **D347** | **RaidableBases waits for the current paid copy.** No §11.4 code is written until the org lead supplies it and its spike (§11.4.2) has run. The old 3.0.5 copy was read for drift only. | Building §11.4 on the free edition now and fitting the paid edition in later; spiking the old 3.0.5 copy on the rigs. | 11.4.2 |
| **D348** | **Runic Gateway and all its systems support either edition, free or paid, as far as each allows.** Every part detects what the installed copy offers and uses the best route it has, and says so where there is none (§11.4.2). This widens D202: both editions must get each part, not only the paid edition's extras. | Building on the free edition's API and treating the paid edition as extras on top. | 11.4.2 |
## 11. First-class optional plugins (D199–D202)
The org lead named four plugins the module supports as first-class integrations. Kits already is one. The other
@@ -1440,6 +1448,7 @@ overruled:
- **The paid edition (D202).** Hello reports the edition. Where it is the paid one, the spawn step offers its
five difficulties and the feed carries lockouts. On the free edition the step offers the one difficulty it
has. **Testing the paid edition needs a licence for the rigs**, which is the org lead's to buy or supply.
D348 (2026-10-14) widens this: every part works on either edition, by the best route each has (§11.4.2).
- **The spike first:** pull the free source, confirm every hook and API signature above, and find the listing
and despawn calls. Then load it on both rigs, with TruePVE, and raid one base.
@@ -1511,23 +1520,83 @@ the end" is not possible on the free edition through anything RaidableBases offe
it does offer is: spawn a named base, somewhere, now; learn where and when it will despawn from the hook;
and remove every base at once. §11.4.3 asks which way to go.
#### 11.4.2 The paid edition — to be filled when the licensed copy arrives
#### 11.4.2 The paid edition: an old copy read (2026-10-14), the current copy still to come
The org lead supplies a licensed copy later in the week of 2026-09-28. The same spike runs against it on
both rigs, and this section records:
**RaidableBases is deferred until the org lead supplies the current paid copy (D347). Runic Gateway supports
both editions as far as each allows (D348).**
- `IsPremium()` and `GetAllDifficulties()` (expected: five tiers);
- whether it adds a spawn at a position, a monument or a difficulty, a despawn of one base, or real base
ids — by API or console command;
- whether the 17-argument hooks and `GetAllEvents` have the same shape (the free edition warns that the
latter is changing), and what `level` carries per difficulty;
The only paid copy at hand on 2026-10-14 was **3.0.5, from 2025-05-03** (`IsPremium()` returns `true`). By then
uMod's free edition was **3.2.2**; the spikes above ran on 3.2.0. The org lead asked for the free source to be
compared with that old paid copy before anything else, and the comparison was a reading only. Nothing was
loaded on a rig. Because 3.0.5 is older than 3.2.2, most of what differs is probably old against new rather
than paid against free. The current paid copy settles which.
**The same in both, so §11.4.3–§11.4.5 stand on them:**
- `OnRaidableBaseStarted`, `Ended`, `Completed`, `Despawn`, `Despawned` and `PrivilegeDestroyed` carry the same
17 arguments in the same order (§11.4.1). Only `level` differs: the free edition always passes `512`, and the
paid one passes the base's tier, 0 (Easy) to 4 (Nightmare). `OnPlayerEnteredRaidableBase` / `Exited` keep
their 14 arguments, with the same split on `level`.
- `rbevent [baseName]`, `rbevent despawnall` / `despawn_inactive` and `rb.reloadprofiles` all work as before.
- Every base's `id` is `"0"` in both.
- Everything §11.4.4's helper reached has the same name and shape:
- the plugin's list of live bases, `OpenEvent(RandomBase)` (which sets `raid.Options = rb.options`), and
each base's own `Despawn()`;
- the shallow `BuildingOptions.Clone()` trap, `PasteBuilding(RandomBase)`, and `RandomBase` itself (the
paid one adds a `payments` field);
- the profile settings the overrides change: `AllowPVP`, `SpawnAmountMurderers` / `SpawnAmountScientists`,
`DespawnMinutes` / `DespawnMinutesInactive`, `OverrideConfig`, and `Setup.EnableForcedHeight` /
`ForcedHeight` / `PasteHeightAdjustment`. Their JSON names match too. Only the NPC counts' defaults
differ: `-9` free, `1` paid.
- the "Initialized Grid" log line that ends the boot-time spawn refusal.
**Where paid 3.0.5 differs from free 3.2.2:**
| Area | Free 3.2.2 | Paid 3.0.5 | What it touches |
|---|---|---|---|
| Difficulties | `GetAllDifficulties()` → `[("Normal", 512)]` | No `GetAllDifficulties`. `GetRaidableModes()` returns names: Easy, Medium, Hard, Expert, Nightmare | the step's difficulty list (§11.4.3, D205) |
| Live bases | `GetAllEvents()` and `GetAllEventsNonAlloc`: an 18-field tuple, with the level as an int. Plus `GetAllEventsCount` and `GetActiveEventCount` | `GetAllEvents(Vector3, float)`: a 17-field tuple with the mode as a string and no level int; the position is ignored. No count or non-alloc calls | the map layer and the servers page (§11.4.1's API table) |
| Spawning | `rbevent [base]` only | `rbevent` also takes a difficulty name and a count. A private `SpawnRandomBase(string baseName, Vector3 position, int mode, int type, bool free)` that another plugin can `Call` returns `"API_INVALID_PROFILE"` or a result, and queues the base at that position when one is given | D203 and D207: a position and a difficulty without the helper's reflection |
| Lock to first attacker | Each base has `BypassUseOwners()`, and the config has a **Manual** pair and a **Management** pair | **No `BypassUseOwners()` method and no Manual pair.** The Management pair is checked inline in three places | **D206's patch target is missing** |
| Water | No seabed spawns | Profiles can place bases on the seabed (`Water.Seabed`, with minimum and maximum depths) | D208's "in water" refusal would block a profile built for the seabed |
| The area check | `SpawnsController.IsAreaSafe(…, RaidableType type)` | One more optional parameter at the end (`BuildingOptionsDifficultySpawns`) | the helper has to bind it by name, not by an exact parameter list |
| Paid-only hooks | — | `OnRaidableBasePurchased` (10 arguments: buyer id, position, grid, level, PvP, …, base name, spawn and despawn times), `OnPurchaseBase`, `OnPurchaseTakePayments`, `OnRaidableResetPayLock`, `OnRaidableBaseHint` | the feed. **No hook announces a lockout**, so §11.4's "the feed carries lockouts" has nothing to listen to in 3.0.5 |
| Free-only hooks | `OnRaidableBaseUnlocked`, and a 17-argument `OnRaidableAwardOwner` | Neither. A 5-argument `OnRaidableBaseCompleted` overload instead | the feed. The bridge binds only the 17-argument hooks, so it does not hear the overload |
| Ranked ladder | A player's `Raids` and `TotalRaids` | Adds `Points`, `TotalPoints` and a count per difficulty | none: *Warlord* counts from the bridge's own `Completed` hook |
| `loadTime` | `Time.realtimeSinceStartup` | `Time.time` | nothing we read |
**When the current paid copy arrives**, the same spike runs against it on both rigs, and this section records:
- its version, and a fresh read of the free edition's at the same time, since each may have moved;
- `IsPremium()`, and whether it has `GetAllDifficulties()`, `GetRaidableModes()` or both;
- whether 3.0.5's callable `SpawnRandomBase` is still there and takes the same parameters, and whether it now
adds a despawn of one base or real base ids;
- whether the 17-argument hooks and `GetAllEvents` have the same shape as free 3.2.2's (the free edition
warns that the latter is changing), and what `level` carries per difficulty;
- whether `BypassUseOwners()` and the Manual lock pair exist, which decides how D206 is built;
- lockouts, buyable events and the ranked ladder: the hooks they raise and what the feed could say;
- anything in it that needs a D168 helper, and anything the free edition's answer in §11.4.3 would get
wrong for it.
- the seabed option, and how D208's water test should treat it;
- everything §11.4.4's helper touches, rerun on both rigs (Oxide and Carbon), as the helper spike was on
the free edition.
The design in §11.4.3 is written so the paid edition extends it rather than replaces it. The step reads
what the installed edition offers — difficulties, and any placement or despawn it supports — and offers
exactly that.
**What D348 asks of the build.** Every part of §11.4 asks the installed copy what it has, rather than assuming
an edition:
- **Detection.** Hello reports the edition (`IsPremium()`) and the version. The bridge and the helper check
for each call and member they use, by name, and report what they found. "Paid" or "free" is never taken
to mean that a call exists.
- **Every edition gets each part, by the best route it has.** Difficulties come from whichever list call
exists. The live map is built from the lifecycle hooks, which both editions raise alike, and needs neither
`GetAllEvents` shape. A spawn uses the plugin's own position-and-difficulty call where there is one, and
the helper's route (§11.4.4) where there isn't.
- **Where a part has no route on the installed copy, the site says so** on the step, the page or the feed,
as D199 does for a missing plugin. It never offers something that fails at run time. The open cases on
3.0.5 are the lock (D206) and lockouts in the feed.
- **The checks D348 adds are part of the build's tests:** each mechanism is exercised against both editions'
shapes, and the end walk (D331) covers a rig with each edition.
The design in §11.4.3–§11.4.5 stays, and D348 governs how it is built. Which route each part takes on the
current paid edition is recorded here after its spike, before any §11.4 code.
#### 11.4.3 Decided (2026-09-28)