diff --git a/modules/rust/PLAN_FIXES.md b/modules/rust/PLAN_FIXES.md index bafa70d..500c0db 100644 --- a/modules/rust/PLAN_FIXES.md +++ b/modules/rust/PLAN_FIXES.md @@ -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) diff --git a/modules/rust/PLAN_REDESIGNS.md b/modules/rust/PLAN_REDESIGNS.md index fb338a9..7c89a83 100644 --- a/modules/rust/PLAN_REDESIGNS.md +++ b/modules/rust/PLAN_REDESIGNS.md @@ -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: '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.