docs(rust): plan fixes — D169-D172, the org lead's answers
D169 every fix and redesign lands before Module-Rust's cutover. D170 an expired zone is marked expired on the site (F14 moves from "by design" to a fix, amending D96). D171 Steam sign-in moves to the website's own plan as part of the base website. D172 chat titles use all twenty-three listed conditions under new names: §4.6 is now a table of condition, title and the hook that feeds it, plus what the detailed plan must settle (best-value columns, weapon classes, vehicle-kill credit, heals of others, quests). PLAN.md §35 and the rust README follow. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01E14m6SuuY6i1vASFeGDBeY
This commit is contained in:
@@ -1,14 +1,15 @@
|
||||
# `module-rust` — plan fixes
|
||||
|
||||
**Status:** plan, awaiting the org lead's approval, 2026-09-26. **The gate before Module-Rust's cutover
|
||||
(phase 19, [`PLAN.md`](PLAN.md) §34, D145).** Everything here comes from the first walk of
|
||||
**Status:** plan, awaiting the org lead's approval, 2026-09-26; its four open questions were answered the same
|
||||
day (D169–D172). **Everything in it — fixes and redesigns alike — lands before Module-Rust's cutover
|
||||
(phase 19, [`PLAN.md`](PLAN.md) §34, D145; D169).** Everything here comes from the first walk of
|
||||
[`PLAYER_WALK.md`](../../rust-link/PLAYER_WALK.md) with a real player in the game — the Oxide pass, walked by
|
||||
the org lead on the `rust-oxide` rig with every frame checked on the console, the sidecar and the site's
|
||||
database. The Carbon pass has not been walked yet and may add to this document.
|
||||
|
||||
This is a companion to [`PLAN.md`](PLAN.md), not a replacement: its decisions continue PLAN.md's numbering
|
||||
(D159 onward), and where the two disagree this one is later and wins. It has three kinds of content, and
|
||||
they gate the cutover differently (§6):
|
||||
all of it lands before the cutover (D169, §6):
|
||||
|
||||
- **Fixes** (§2) — the plugin, the sidecar or the site does something other than what the plan and the
|
||||
protocol say. Fifteen, F1–F15.
|
||||
@@ -51,8 +52,10 @@ Taken by the org lead during and straight after the walk.
|
||||
| **D166** | **The zone step offers ZoneManager's own flags and settings**, read from the installed ZoneManager, not a hard-coded list. |
|
||||
| **D167** | **ZoneDomes is an optional dependency.** The zone step gains a "show a dome" option; the bridge adds the dome and removes it with the zone. |
|
||||
| **D168** | **When a plugin we depend on does not expose what we need, we may write a small helper plugin for it.** It ships from Rust-Plugins beside the bridge, is optional, and is detected at hello like the other integrations. The bridge keeps calling only public APIs (R2); the helper is where a gap in someone else's plugin gets bridged. |
|
||||
|
||||
**One more, leaning but not yet decided:** Steam as a first-class sign-in provider on the website (§4.8).
|
||||
| **D169** | **Every fix and every redesign in this document lands before Module-Rust's cutover (phase 19).** Rejected: cutting over after the fixes and following with the redesigns. |
|
||||
| **D170** | **An expired zone is marked expired on the site.** Once F13 makes `world.expired` recognisable, ingest marks the run's resource row `expired`. This amends D96's "the website maps it to nothing". F14. |
|
||||
| **D171** | **Steam sign-in belongs to the website's own plan and is part of the base website**, exposed to modules however they need it. It leaves this document (§4.8). |
|
||||
| **D172** | **Chat titles use all twenty-three conditions the org lead listed, under new names** (§4.6). Rejected: a first subset. |
|
||||
|
||||
## 2. Fixes
|
||||
|
||||
@@ -155,13 +158,11 @@ or map prefab to label on the site — whichever the killfeed page already expec
|
||||
empty for players other plugins spawn; the plugin already avoids it for `entity.destroyed`. Use
|
||||
`((ulong)player.userID).ToString()` at all 13 sites. Real connected players are unaffected.
|
||||
|
||||
### 2.4 By design — a question, not a fix
|
||||
|
||||
**F14 — the site never learns that a zone expired.** Expired zones stayed `confirmed` on the run console until
|
||||
the runs were cancelled, when teardown found them "already gone" and counted that a success. PROTOCOL.md §15
|
||||
says this is intended: "The website maps it to nothing. Core learns about it through `reconcile` and `revert`"
|
||||
(D96). **The question:** should ingest mark the row `expired` once F13 makes the frame recognisable, so the
|
||||
console stops showing a live zone that is gone? Recommended: yes.
|
||||
**F14 — the site never learns that a zone expired.** *(Module-Rust)* Expired zones stayed `confirmed` on the run
|
||||
console until the runs were cancelled, when teardown found them "already gone" and counted that a success. This
|
||||
was the design — PROTOCOL.md §15: "The website maps it to nothing. Core learns about it through `reconcile` and
|
||||
`revert`" (D96) — and D170 changes it. *Fix:* after F13, ingest maps `world.expired` to the run's resource row
|
||||
and marks it `expired`; teardown treats `expired` as already reverted; amend PROTOCOL.md §15.
|
||||
|
||||
## 3. Interface and walk-doc corrections
|
||||
|
||||
@@ -257,15 +258,50 @@ A per-type marker setting for staff, defaulting to the major monuments. Decide i
|
||||
monument sweep or the site does the filtering; the type (`monument_substation`, cave, …) is already in the
|
||||
monument data.
|
||||
|
||||
### 4.6 Chat titles: more conditions
|
||||
### 4.6 Chat titles: twenty-three conditions (D172)
|
||||
|
||||
The org lead's list, as inspiration (the names are examples): animal, bow, melee, blade, revolver, NPC, APC and
|
||||
helicopter kills; headshots; players killed; PvP and PvE kill distance; wood, ore and plants gathered; clothes
|
||||
and weapons crafted; structures built and repaired; players healed; rockets fired; explosives thrown; quests
|
||||
completed. Most need new counters in the plugin — the weapon class on a kill, headshots, crafting by category,
|
||||
heals, building and repair, explosives — each a hook, a tally field and a leaderboard column. D159's gathering
|
||||
counters feed the gathering titles. Quests need a quest plugin, and none is installed. The plan picks the first
|
||||
set; the rest follow.
|
||||
All of the conditions the org lead listed, each under a new title. The titles are proposals; the conditions are
|
||||
decided. Every hook below is in uMod's catalogue ([`HOOKS.md`](HOOKS.md)); each is declared `void`, as the read
|
||||
path requires (PROTOCOL.md §8.7), and each must be checked on Carbon, whose catalogue renames some.
|
||||
|
||||
| Condition | Title | Where the count comes from |
|
||||
|---|---|---|
|
||||
| Animal kills | **Beastbane** | `OnEntityDeath`, victim a `BaseAnimalNPC` — today folded into `npcKills`; split it |
|
||||
| NPC kills | **Exterminator** | `OnEntityDeath`, victim a human NPC (scientists, bandits) — the other half of that split |
|
||||
| Players killed | **Reaper** | the existing `kills` column (`player.death` with a player attacker) |
|
||||
| Bow kills | **Fletcher** | a kill whose weapon is a bow or crossbow — the weapon shortname the killfeed already carries |
|
||||
| Melee kills | **Brawler** | a kill with any `BaseMelee` weapon |
|
||||
| Blade kills | **Duelist** | a kill with a bladed melee weapon (machete, swords, knives) — a named list |
|
||||
| Revolver kills | **Outlaw** | a kill with the revolver or the python |
|
||||
| Headshots | **Crownbreaker** | a killing blow with `HitInfo.isHeadshot` |
|
||||
| PvP kill distance | **Longshot** | the *longest* single player kill — the `distance` the killfeed already carries |
|
||||
| PvE kill distance | **Marksman** | the longest single NPC or animal kill |
|
||||
| APC kills | **Tankbreaker** | `OnEntityDeath`, victim a `BradleyAPC`, credited to the killing player |
|
||||
| Helicopter kills | **Rotorbane** | `OnEntityDeath`, victim a patrol helicopter (and the CH47), credited to the killing player |
|
||||
| Wood gathered | **Timberwright** | `gathered.wood`, all three sources (D159) |
|
||||
| Ore gathered | **Prospector** | `gathered` metal, sulfur and high-quality ore, all three sources |
|
||||
| Plants gathered | **Greenhand** | `OnGrowableGathered` plus picked-up plants (hemp, berries, mushrooms, corn, potatoes, pumpkins) |
|
||||
| Clothes crafted | **Seamster** | `OnItemCraftFinished`, item category attire |
|
||||
| Weapons crafted | **Armorer** | `OnItemCraftFinished`, item category weapon |
|
||||
| Structures built | **Mason** | `OnEntityBuilt` placing a building block |
|
||||
| Structures repaired | **Tinkerer** | `OnStructureRepair` |
|
||||
| Players healed | **Mender** | healing *another* player — `OnHealingItemUse` on someone else, and `OnPlayerRevive` |
|
||||
| Rockets fired | **Artillerist** | `OnRocketLaunched` |
|
||||
| Explosives thrown | **Demolitionist** | `OnExplosiveThrown` and `OnExplosiveDropped` |
|
||||
| Quests completed | **Wayfarer** | a quest plugin — none is installed; choose one, or a D168 helper |
|
||||
|
||||
What the detailed plan has to settle before building:
|
||||
|
||||
- **Two kinds of column.** Every existing leaderboard column is a sum; the two distance titles need a *best* (the
|
||||
largest single value). The tally carries the interval's maximum, and the site keeps the running best.
|
||||
- **What a weapon-class kill counts.** Recommended: any kill the player is credited with — players, NPCs and
|
||||
animals — so Fletcher rewards a hunter as well as a raider. The weapon lists (bow, blade, revolver) are named
|
||||
sets in one place, so a Rust update adds a weapon by editing a list.
|
||||
- **Credit for a vehicle kill.** The APC and the helicopter are usually killed by several people. Credit the player
|
||||
who dealt the killing blow (`HitInfo.InitiatorPlayer`) — simple, and the rule the killfeed already uses.
|
||||
- **Healing someone else**, never yourself — otherwise Mender is earned by bandaging after every fight.
|
||||
- **Counters are aggregates** (rule 2): all of these ride on `player.tally`, never one frame per shot, craft or swing.
|
||||
- **Quests** wait on a quest plugin; the other twenty-two do not.
|
||||
|
||||
### 4.7 NPCs
|
||||
|
||||
@@ -273,12 +309,12 @@ Research before deciding: which free uMod NPC plugins are maintained and expose
|
||||
name and a behaviour, against extending `rust.npc.place` to dress the stock scientist from a Kits kit and give it
|
||||
a display name. The goal the org lead named is server customisation — NPCs with different kits and names.
|
||||
|
||||
### 4.8 Steam sign-in (website, not this module)
|
||||
### 4.8 Steam sign-in (moved to the website's plan, D171)
|
||||
|
||||
Steam as a provider beside Google and Discord. It is OpenID 2.0, not OAuth2/OIDC, so it needs its own adapter.
|
||||
Leaning toward both halves: link-only sign-in (SSO never provisions an account), and linking Steam also creates
|
||||
the Rust link, since it proves the Steam id more strongly than a code does. Belongs in `website/` with its own
|
||||
plan; noted here because it changes R1's identity story.
|
||||
Steam as a sign-in provider beside Google and Discord is part of the base website and is planned there, not
|
||||
here. What this module needs from it: a way to learn a signed-in account's verified Steam id, so linking by
|
||||
Steam can stand beside the in-game code (R1). Steam is OpenID 2.0, not OAuth2/OIDC, so the website needs its
|
||||
own adapter.
|
||||
|
||||
## 5. Protocol
|
||||
|
||||
@@ -290,20 +326,23 @@ once:
|
||||
- A plugin-loaded / unloaded frame (F8).
|
||||
- The permission inventory verb and its reply (§4.1).
|
||||
- ZoneManager's flags at hello, zone options on `world.zone`, the dome option (§4.4).
|
||||
- New tally fields for D159 and the first title counters (§4.6).
|
||||
- New tally fields: D159's gathering sources, the animal / NPC split, weapon-class kills, headshots, crafting,
|
||||
building, repairs, heals, rockets, explosives, and the two per-interval maxima for kill distance (§4.6).
|
||||
- `world.expired` handled by the site (F14, D170) — no wire change beyond F13's.
|
||||
|
||||
F15 changes no message shape and ships ahead of the bump.
|
||||
|
||||
## 6. Order, and what gates the cutover
|
||||
|
||||
1. **Before anything else:** F15 (data corruption), and F9 + F10 (it throws away edits). Small, no protocol change
|
||||
for F15.
|
||||
2. **Protocol 13 with the remaining fixes:** F13, F12, F1, F3, F8, F7, F2, F4, and F5/F6 in the module.
|
||||
3. **The redesigns** (§4.1, §4.3, §4.4) — each its own phase, planned in detail before code.
|
||||
**All of it lands before Module-Rust's cutover (D169).** The order inside that:
|
||||
|
||||
**Recommended gate:** steps 1 and 2 land before Module-Rust's cutover (phase 19); the redesigns follow it.
|
||||
Nobody outside the org runs module-rust yet, so the cutover should not carry known corruption or silent
|
||||
rollbacks, but it need not wait for the new screens. Open for the org lead.
|
||||
1. **First:** F15 (data corruption), and F9 + F10 (they throw away edits). Small; F15 changes no message shape.
|
||||
2. **Protocol 13 with the remaining fixes:** F13, F14, F12, F1, F3, F8, F7, F2, F4 in the bridge and the module,
|
||||
and F5/F6 in the module.
|
||||
3. **The redesigns**, each planned in detail before code and walked on both frameworks: the permission manager
|
||||
(§4.1), the event step editor with the kit-weekend template (§4.2, §4.3), zones and domes (§4.4), the map's
|
||||
marker types (§4.5), the chat title conditions (§4.6), and the NPC research (§4.7).
|
||||
4. **The cutover**, once the re-walk (§8) passes on Oxide and Carbon.
|
||||
|
||||
## 7. Helper plugins (D168)
|
||||
|
||||
@@ -327,12 +366,19 @@ After step 2 of §6, on both frameworks:
|
||||
- A zone restarted with a player standing in it, and a zone opened around a player (F12).
|
||||
- A zone left to expire, checked by `kind=world.expired` (F13).
|
||||
- A plugin unloaded, a grant made, the plugin loaded again — the grant lands within a minute (F8).
|
||||
- An expired zone reads `expired` on the run console (F14).
|
||||
- Each redesign's own walk, and every title condition earned at least once.
|
||||
- Then the steps still owed: the Carbon subset, player step 8 and the map walk with a second player, events step
|
||||
7 with several players, the phone walks.
|
||||
|
||||
## 9. Open questions for the org lead
|
||||
## 9. Answered, and what stays open
|
||||
|
||||
1. The cutover gate in §6 — fixes before phase 19, redesigns after?
|
||||
2. F14 — should ingest mark an expired zone `expired` (recommended), or keep D96's "maps it to nothing"?
|
||||
3. Steam sign-in (§4.8) — both halves, and does it belong to this workstream or to `website/`?
|
||||
4. Which title conditions form the first set (§4.6)?
|
||||
The four questions this plan first asked were answered on 2026-09-26: the gate (D169), F14 (D170), Steam sign-in
|
||||
(D171) and the title conditions (D172).
|
||||
|
||||
Left for the detailed plans of §6 step 3, none of them blocking the fixes:
|
||||
|
||||
1. The quest plugin behind Wayfarer — or a D168 helper.
|
||||
2. Whether the plugin or the site filters monument types (§4.5).
|
||||
3. The ZoneDomes default type and stack, chosen by looking at each on the rig (§4.4).
|
||||
4. The NPC route — a plugin, or extending `rust.npc.place` (§4.7).
|
||||
|
||||
Reference in New Issue
Block a user