docs(rust): resume the redesigns at §2 — D331–D334 #334
@@ -430,6 +430,8 @@ in Rust-Plugins, Rust-Link and Module-Rust, and the three cut over to `main` tog
|
||||
marker types (§4.5), the chat title conditions (§4.6), and the NPC research (§4.7).
|
||||
*Planned 2026-09-27:* all six are in one document, [`PLAN_REDESIGNS.md`](PLAN_REDESIGNS.md), as the org
|
||||
lead chose. Its eleven questions were answered the same day as D188–D198 (its §10).
|
||||
*Resumed 2026-10-09* after RunicNPC v1.0.0 (D331–D334): the items left are coded first, and every walk
|
||||
still owed — theirs, the redesigns' in-game rows and §8's re-walk — happens once, at the end (D331).
|
||||
4. **The cutover**, once the re-walk (§8) passes on Oxide and Carbon.
|
||||
|
||||
## 7. Helper plugins (D168)
|
||||
|
||||
@@ -8,7 +8,9 @@ they can be read together. **Built so far:** §1, walked 2026-09-28 (§1.9); §5
|
||||
rig walk still to come (§5.8, D209); §3, built and walked on the rigs and the site 2026-09-29, its in-game
|
||||
rows still to come (§3.4); §4, built 2026-09-29 (§4.1). **§6 was spiked on 2026-09-30, and the org lead
|
||||
chose neither route: Runic Gateway writes its own NPC plugin, RunicNPC, planned in
|
||||
[`../../runicnpc/PLAN.md`](../../runicnpc/PLAN.md) (D214–D314), and the rest of this plan waits for it.**
|
||||
[`../../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). **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
|
||||
document is later and wins. Its decisions continue PLAN_FIXES' numbering at **D188**.
|
||||
@@ -23,12 +25,13 @@ document is later and wins. Its decisions continue PLAN_FIXES' numbering at **D1
|
||||
| 6 | NPCs — now RunicNPC, its own plan ([`runicnpc/PLAN.md`](../../runicnpc/PLAN.md)) | §4.7 | **runicnpc-rust**, Rust-Plugins, Rust-Link, Module-Rust, installer |
|
||||
| 11 | First-class optional plugins: Economics, Backpacks, RaidableBases (Kits stays required) | — (added 2026-09-28) | Rust-Plugins, Module-Rust, installer, Android-app |
|
||||
|
||||
**Protocol.** Every wire change here joins **protocol 13**, which is still unreleased on `edge` in all three
|
||||
repos. [`PLAN_FIXES.md`](PLAN_FIXES.md) §5 already lists the inventory verb, ZoneManager's flags, zone
|
||||
options and the new tally fields under it, so this adds no bump (§7).
|
||||
**Protocol.** §1, §3, §4 and §5 joined **protocol 13**, which shipped on 2026-10-09 with RunicNPC v1.0.0
|
||||
(bundle 2026.10.09). The wire changes still to come, §2's and §11's, **open protocol 14** on `edge` and are
|
||||
released together once, after the end-of-plan walk (D332, §7).
|
||||
|
||||
**Core.** §2 is mostly core's editor, which is game-agnostic and serves Module-uo too. Its contract
|
||||
additions are **MODULE_API 1.11.0 → 1.12.0**, additions only (§8). The same proof website#209 ran for 1.11.0
|
||||
additions are **MODULE_API 1.12.0 → 1.13.0**, additions only (§8; 1.12.0 went to Events' `progress()`,
|
||||
website#210). The same proof website#209 ran for 1.11.0
|
||||
applies: Module-uo's frozen-manifest job and its suites, run against the new core.
|
||||
|
||||
---
|
||||
@@ -287,7 +290,9 @@ and must leave Module-uo exactly as it is.
|
||||
|
||||
- **No type tags.** `ParamField` stops printing ` · {type}` and the bare `*`. A required field says so in
|
||||
words only when it is empty at save time.
|
||||
- **Each type gets its control:** a toggle for `boolean`, a number field with the declared range beside it for
|
||||
- **Each type gets its control:** for `boolean`, a toggle when the param is required and three buttons side by
|
||||
side, **[Not set] [Yes] [No]**, when it is optional, because "not set" is a real third state there — the
|
||||
action's own default — and a two-state toggle would save No for every field nobody touched (D334); a number field with the declared range beside it for
|
||||
`int` and `float`, a date picker for `datetime`, and a text box only for `string` without a source.
|
||||
- **`core.lease` renders the chosen lease's own form.** The lease is picked by its **label**. The step then
|
||||
shows the value as the lease's type (a toggle for a boolean lease, a number with the lease's `min`–`max`
|
||||
@@ -295,7 +300,7 @@ and must leave Module-uo exactly as it is.
|
||||
`target.source`** (F11, never built: today the editor reads only `param.source`), and the minutes with the
|
||||
lease's `maxDurationMs` shown beside them.
|
||||
- **Examples.** Core's own examples become game-neutral (§0.9). A lease may declare an optional `example` for
|
||||
its value (**MODULE_API 1.12.0**, §8), and `target.example` already exists, so the examples on a lease step
|
||||
its value (**MODULE_API 1.13.0**, §8), and `target.example` already exists, so the examples on a lease step
|
||||
are that lease's.
|
||||
|
||||
### 2.2 A phase that holds a timed step (U-6)
|
||||
@@ -303,7 +308,7 @@ and must leave Module-uo exactly as it is.
|
||||
A phase with no advance rule ends when its steps finish, and teardown gives a lease back at once. So the
|
||||
"10 minutes" of a lease lasted one second. The fix is to make the duration visible:
|
||||
|
||||
- A param may declare **`duration: 'minutes'`** (**MODULE_API 1.12.0**). `core.lease`'s `minutes` is one,
|
||||
- A param may declare **`duration: 'minutes'`** (**MODULE_API 1.13.0**). `core.lease`'s `minutes` is one,
|
||||
and so are `rust.zone.open`'s `minutes` and the other modules' equivalents.
|
||||
- When a timed step is added to a phase that has **no advance rule**, the editor gives the phase
|
||||
**`advance: { after: '<the longest duration in the phase>m' }`**, visibly, and the author may change it.
|
||||
@@ -327,16 +332,29 @@ choice.**
|
||||
- **Zones.** `rust.zone.open` gains `enterMessage`, `leaveMessage` and `delivery`. The bridge no longer passes
|
||||
the messages to ZoneManager for its own zones. It subscribes to ZoneManager's `OnEnterZone` and `OnExitZone`
|
||||
and sends them itself, as chat or as a popup, only for the zones in its registry. This also gives F12's
|
||||
"row 5 cannot show an enter message" (PLAN_FIXES, the step-2 walk) a message to show.
|
||||
- **Rewards.** The reward actions' message to the player (`rust.kit.entitle` and the other `eventRewards.js`
|
||||
steps that tell a player what they won) gains the same `delivery`.
|
||||
"row 5 cannot show an enter message" (PLAN_FIXES, the step-2 walk) a message to show. **Built with §3**
|
||||
(§3.4), so §2 leaves it alone.
|
||||
- **Rewards (D333).** There was no in-game reward message to give a `delivery` to: a reward's only notice
|
||||
was core's engagement notification (`rust.kit.entitled`). So the message is new. `rust.kit.entitle` gains
|
||||
an optional **`message`** and **`delivery`**. Alice comes second and is rewarded kit `vip`: if she is
|
||||
online she is told at once, in chat or a popup — "You earned kit vip — type /kit vip" — and if she is
|
||||
offline she is told when she next wakes up on that server, since the grant already waits for her.
|
||||
- A blank `message` sends nothing, so a step saved before §2 behaves exactly as it did. `{kit}` in the
|
||||
text is the kit's name. Only linked recipients have a grant, so only they are told.
|
||||
- The notice rides `perm.sync` like the credit it belongs to (PROTOCOL §16.3): a new `notices` field,
|
||||
the site's whole set of untold notices for that server, each `{key, steamId, message, delivery}`,
|
||||
keyed by run and step. The plugin tells each player once, keeps the keys it has told, and reports
|
||||
them back (`noticesTold`), so the site marks the grant row told and stops sending it.
|
||||
- A grant withdrawn before its player came back takes its notice with it: nobody is told about a
|
||||
reward that is no longer theirs.
|
||||
- Protocol 14 (D332). An older plugin ignores `notices`; an older site sends none.
|
||||
- **Without PopupNotifications** a popup falls back to chat. The step editor says so beside the choice when the
|
||||
server's hello reports PopupNotifications absent, as `rust.options.delivery` already does.
|
||||
|
||||
### 2.5 The kit weekend as a template (D164)
|
||||
|
||||
There is no template concept anywhere today. **D192: core gains `api.registerEventTemplates`**
|
||||
(**MODULE_API 1.12.0**), which any module can use: a module declares a named skeleton (phases, steps, params filled in, and a short list
|
||||
(**MODULE_API 1.13.0**), which any module can use: a module declares a named skeleton (phases, steps, params filled in, and a short list
|
||||
of the inputs the author supplies). The editor's "New event" screen offers the skeletons, asks for their
|
||||
inputs, and opens an ordinary draft. Nothing about a template survives into the definition, so it is purely an
|
||||
authoring shortcut and the runner never sees it.
|
||||
@@ -355,15 +373,18 @@ with `advance: { after }` equal to the duration and two steps:
|
||||
"N linked players have already used this kit" needs a bulk read the plugin does not have (§0.8). So there is a
|
||||
new verb, **`kits.uses`**: `{kit, steamIds[]}` in, and `{max, cooldown, exhausted, onCooldown}` out (counts,
|
||||
not a list). It is main thread, capped at the site's linked-player count for that server (the same bound as
|
||||
the sync's).
|
||||
the sync's). It is **protocol 14** (D332): against a protocol-13 server the note is simply left off.
|
||||
|
||||
The warning reaches the core editor through an **optional `note` on an option row** (**MODULE_API 1.12.0**).
|
||||
The warning reaches the core editor through an **optional `note` on an option row** (**MODULE_API 1.13.0**).
|
||||
When the chosen option carries one, the editor shows it under the field. `rust.options.grouppermissions`
|
||||
attaches the note to a `kits.*` target: "Kit `vip`: 2 uses, 24 h cooldown — 9 of 41 linked players have used
|
||||
it up. The weekend's extra use (step 2) is what lets them take it again."
|
||||
|
||||
### 2.7 The walk
|
||||
|
||||
**Deferred to the end-of-plan walk (D331, §9).** The rows, for that walk, plus D333's reward message (online
|
||||
and on next wake, chat and popup, and a withdrawn grant that tells nobody):
|
||||
|
||||
Author a kit weekend from the template on each rig; a lease step with the phase's advance removed (the warning
|
||||
shows); a draft edited after publishing (Start asks); a boolean lease (a toggle); and a Module-uo event opened
|
||||
in the same editor, which must be unchanged apart from the controls.
|
||||
@@ -435,7 +456,7 @@ Built on `edge` as Rust-Plugins `feat/zones-domes`, Module-Rust `feat/zones-dome
|
||||
|
||||
- **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**,
|
||||
MODULE_API 1.13.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
|
||||
@@ -802,24 +823,28 @@ beyond it.
|
||||
|
||||
---
|
||||
|
||||
## 7. Protocol 13, what this adds
|
||||
## 7. Protocols 13 and 14, what this adds
|
||||
|
||||
All of these are additions to the unreleased protocol 13. PROTOCOL.md §19 gains a section for each.
|
||||
The rows for §1, §3 and §5 were additions to protocol 13, which shipped on 2026-10-09; PROTOCOL.md §19 has a
|
||||
section for each. **§2's two rows open protocol 14 (D332)**, which §11 joins, and PROTOCOL.md §20 gains
|
||||
them. §6's row was never built: RunicNPC replaced route A.
|
||||
|
||||
| Change | Direction | § |
|
||||
|---|---|---|
|
||||
| `perm.inventory` / its paged reply (owners, groups with parents, users, leased) | site → game | 1.2 |
|
||||
| `perm.sync`: groups carry `parent`; `managed` and the foreign report removed | site → game | 1.2 |
|
||||
| `kits.uses` / its reply | site → game | 2.6 |
|
||||
| `kits.uses` / its reply — **protocol 14** | site → game | 2.6 |
|
||||
| hello: `zoneManager: { version, flags[] }` (from the zone helper); `zoneDomes: { loaded, version }` and the domes helper's state | game → site | 3.1, 3.2 |
|
||||
| `world.zone`: `flags`, `settings`, `enterMessage`, `leaveMessage`, `delivery`, `dome: { type, stack }`; reason `bad-option` | site → game | 2.4, 3.1, 3.2 |
|
||||
| the reward verbs' player message: `delivery` | site → game | 2.4 |
|
||||
| `world.place` for an NPC (the verb behind `rust.npc.place`): `kit`, `name`, if route A is chosen | site → game | 6 |
|
||||
| `perm.sync`: `notices` (the reward message, D333), and the report's `noticesTold` — **protocol 14** | site ⇄ game | 2.4 |
|
||||
| ~~`world.place` for an NPC~~ — not built; RunicNPC (D214) | — | 6 |
|
||||
| `player.tally`: `animalKills`, `weaponKills`, `headshots`, `bestPvpM`, `bestPveM`, `apcKills`, `heliKills`, `crafted`, `built`, `repaired`, `healed`, `rockets`, `explosives`, `missions` | game → site | 5.1 |
|
||||
|
||||
## 8. MODULE_API 1.12.0 (core, website `main`)
|
||||
## 8. MODULE_API 1.13.0 (core, website `main`)
|
||||
|
||||
Additions only, so Module-uo, declared `^1.10.0`, is unaffected, and that is proven the way 1.11.0 was.
|
||||
Planned as 1.12.0; that number went to Events' `progress()` (website#210) while this plan waited for
|
||||
RunicNPC, so these are 1.13.0. Additions only, so Module-uo, declared `^1.10.0`, is unaffected, and that is
|
||||
proven the way 1.11.0 was.
|
||||
|
||||
- `registerEventTemplates` (§2.5).
|
||||
- A param's optional `duration: 'minutes'` (§2.2).
|
||||
@@ -828,7 +853,10 @@ Additions only, so Module-uo, declared `^1.10.0`, is unaffected, and that is pro
|
||||
|
||||
## 9. Order of building
|
||||
|
||||
Each item is built on `edge`, walked on both rigs, and PR'd with its spec, like steps 1 and 2:
|
||||
Each item is built on `edge` and PR'd with its spec, like steps 1 and 2. Items 1–4 were also walked as they
|
||||
were built; **from item 6 on, nothing is walked until every item is coded (D331)**. Code that runs in the
|
||||
game is still compiled on both rigs before its PR, and a rig spike that a design depends on (§11's source
|
||||
pulls) is research, not a walk, so it still comes first:
|
||||
|
||||
1. **The permission manager** (§1). It is the largest, and §3's exemptions point at it.
|
||||
2. **Chat titles** (§5), including the mission hook.
|
||||
@@ -841,7 +869,9 @@ Each item is built on `edge`, walked on both rigs, and PR'd with its spec, like
|
||||
7. **The first-class optional plugins** (§11): Economics, then Backpacks, then RaidableBases, each starting
|
||||
with its source pull and rig spike.
|
||||
|
||||
Then PLAN_FIXES §8's re-walk on Oxide and Carbon, and the cutover.
|
||||
**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
|
||||
is fixed, protocol 14 is released, and the cutover follows.
|
||||
|
||||
## 10. Decisions of record
|
||||
|
||||
@@ -853,7 +883,7 @@ The plan asked eleven questions. The org lead answered them on 2026-09-27, the d
|
||||
| **D189** | **A group belongs to one server unless an admin shares it** with chosen servers or the whole fleet. The import makes one group per server, even for identical names. The same group across servers is allowed but never assumed. | One group name fleet-wide with per-server contents (the plan's first proposal). | 1.4 |
|
||||
| **D190** | **An in-game change affects that server only, and auto-adopt applies it without asking.** A grant that reaches more servers gains an exception for that server; a shared group is split, and that server gets its own copy. | Holding a change to a multi-server row for a person under every policy. | 1.6 |
|
||||
| **D191** | **ZoneManager's `ignoreflag` permissions are listed like any other permission.** | One collapsed "exempt from zone flags" section. | 1.7 |
|
||||
| **D192** | **Core gains event templates** (`registerEventTemplates`, MODULE_API 1.12.0), and the kit weekend is the first. | A Rust-only kit-weekend button. | 2.5 |
|
||||
| **D192** | **Core gains event templates** (`registerEventTemplates`, MODULE_API 1.13.0 — planned as 1.12.0, §8), and the kit weekend is the first. | A Rust-only kit-weekend button. | 2.5 |
|
||||
| **D193** | **A zone's enter and leave messages and a player's reward message get the Chat / Popup choice**, as announcements have. The bridge sends zone messages itself for its own zones. | Popups for announcements only in this step. | 2.4 |
|
||||
| **D194** | **ZoneDomes stays the optional dependency (D167 stands).** A domes helper makes its API safe without a player; the bridge re-adds domes after re-creating zones and removes them at expiry and teardown. | The bridge drawing the dome itself (the plan's first proposal). | 3.2 |
|
||||
| **D195** | **Zone presets are the admins' own**, saved for one server, several, or the fleet. None ship. | Shipped presets (Arena, Safe zone, No building). | 3.1 |
|
||||
@@ -903,6 +933,15 @@ The §4 build raised one more, answered on 2026-09-29:
|
||||
| **D219** | **Rust's navmesh is used;** a custom navigation mesh is a later stage, only if needed. | NpcSpawn-style point meshes from the start. | 6, RunicNPC §8 |
|
||||
| **D220** | **RunicNPC is built and tested in stages before this plan resumes, then `module-rust` requires it.** | Building it alongside items 6 and 7. | 9, RunicNPC §9 |
|
||||
|
||||
The plan resumed on 2026-10-09, after RunicNPC v1.0.0, with four more:
|
||||
|
||||
| # | Decision | Rejected | § |
|
||||
|---|---|---|---|
|
||||
| **D331** | **Every item left (§2, §11) is coded before anything is walked; then one walk covers it all**, with the walks §3 and §5 still owe and PLAN_FIXES §8's re-walk, and what it finds is fixed before the release. Rig spikes a design depends on, and compiling on both rigs, still happen as each item is built. | Walking each item as it is built, as items 1–4 were. | 9 |
|
||||
| **D332** | **§2 and §11 open protocol 14 on `edge`, released together once after the end walk.** Protocol 13 shipped on 2026-10-09. | Protocol 14 for §2 alone and 15 for §11; dropping `kits.uses` to keep §2 off the wire. | 7, 11.5 |
|
||||
| **D333** | **A kit reward can tell its player in game.** `rust.kit.entitle` gains an optional `message` and `delivery`; the notice rides `perm.sync` and is told once, at once or on the player's next wake; a blank message tells nobody. | The engagement notification as the only notice. | 2.4 |
|
||||
| **D334** | **An optional boolean param is three buttons, [Not set] [Yes] [No]; a required one is a toggle.** | A two-state toggle everywhere, which saves No for a field nobody touched. | 2.1 |
|
||||
|
||||
## 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
|
||||
@@ -1177,6 +1216,5 @@ The org lead answered §11.4.4's three questions the same day:
|
||||
|
||||
### 11.5 Protocol
|
||||
|
||||
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.
|
||||
These are new verbs, events and hello fields. **They join protocol 14 (D332)**, which §2 opens: protocol 13
|
||||
shipped on 2026-10-09, before §9 reached item 7.
|
||||
|
||||
Reference in New Issue
Block a user