docs(rust): RaidableBases deferred for the current paid copy; both editions supported (D347, D348) #344
@@ -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)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user