docs(rust): the chat-title conditions as built — PROTOCOL 19.10, PLAN_REDESIGNS 5.8 and D209

PROTOCOL.md §19.10 documents player.tally's new fields and the ten hooks
behind them. PLAN_REDESIGNS §5.8 records what the build settled (the
category ids, where each is read from, the empty-text rule, the admin
API, the plugin's counting choices) and what is left before the walk.
D209: a title rule's "NPC kills" ranks human NPCs only.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01E14m6SuuY6i1vASFeGDBeY
This commit is contained in:
2026-09-28 23:32:59 -05:00
parent 18a4a561e3
commit e3c5d7128c
2 changed files with 86 additions and 2 deletions

View File

@@ -4,7 +4,8 @@
On 2026-09-28 the org lead added the first-class optional plugins (§11, D199–D202), and after the RaidableBases spikes, D203–D208 (§11.4).
It is step 3 of [`PLAN_FIXES.md`](PLAN_FIXES.md) §6: the six changes the org lead decided during the first
player walk, each "planned in detail before code". The org lead asked for all six in one plan (2026-09-27), so
they can be read together. No code has been written for any of them yet.
they can be read together. **Built so far:** §1, walked 2026-09-28 (§1.9); §5, built 2026-09-28 with its
rig walk still to come (§5.8, D209).
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**.
@@ -526,6 +527,47 @@ shirt and a weapon; build and repair a wall; bandage and revive another player;
destroy an APC; shoot down a helicopter; finish a mission and abandon one. Each count is checked in the tally
frame and on the titles screen.
### 5.8 As built (2026-09-28; not yet walked)
Rust-Plugins `feat/title-conditions`, Module-Rust `feat/title-conditions`. The wire is
[`PROTOCOL.md`](../../rust-link/PROTOCOL.md) §19.10, and the admin API is the module's swagger fragment
(`/admin/rust/title-categories…`).
**One question the plan left open, answered (D209):** a rule's `npckills` now ranks **human NPCs only**,
every NPC kill less the animals. Titles had never shipped, so no live rule changes meaning; the rigs'
walk database held one such rule.
**What the build settled:**
- **The categories are ids a rule stores**, in `model/titles/titles.js`: `kills`, `npckills`,
`animalkills`, `bowkills`, `meleekills`, `bladekills`, `revolverkills`, `headshots`, `pvpdistance`,
`pvedistance`, `apckills`, `helikills`, `wood`, `ore`, `plants`, `attire`, `weapons`, `built`, `repaired`,
`healed`, `rockets`, `explosives`, `missions`, plus `playtime`, which predates them. **Playtime has no
default title**, so it cannot be renamed and a playtime rule always carries its own text.
- **Each category names where it is read from:** a summed column, a column's `MAX` (the two distances), a
difference (`npc_kills − animal_kills`, in signed arithmetic, since a row counted before `animal_kills`
existed would otherwise wrap), or a named list over `rust_weapon_kills` or `rust_gather_totals`. Every
standing is ordered by value, then by who was seen last, the leaderboard's own tie-break.
- **The lists are one file**, `model/titles/lists.js`: bow, melee, blade, revolver, wood, ore and plants.
Every blade is also melee. Plants include cloth, which is what hemp picks up as, and leave out seeds.
- **A rule's text may be empty**, meaning its category's title. **A text typed as only markup is still
refused** (§33.4 reading 3): brackets are a mistake, not a request for the default. The form shows the
category's current title as a placeholder and never saves it into the rule.
- **The category titles** are `GET /admin/rust/title-categories` and
`PUT /admin/rust/title-categories/:stat` (an empty `text` is the Reset). A change forgets every server's
cached answer, so the next push carries the new name. The servers list also returns them, so each
server's summary line names what its rules show.
- **The plugin's choices, each to be checked by the walk:** a repair counts only when the entity's health
rose by the next tick (the hook fires before the game decides there is anything to repair); a syringe
revive raises both the revive and the heal hook and counts once; an explosive is a `TimedExplosive` that
deals damage, which leaves out supply signals and smoke; the helicopter's last-hitter credit (§5.4) is
built rather than waiting for the walk, because proving it unnecessary needs a helicopter shot down
first.
**Still to do before the walk:** the weapon lists are from knowledge of the game, not yet read off the
rig's item list. A read-only probe that lists every held item's prefab and class is written, and it runs
once the rigs' storage is back (it was unmounted on 2026-09-28, §5.7's walk waits on it too).
---
## 6. NPCs (§4.7)
@@ -639,6 +681,12 @@ The org lead added §11 on 2026-09-28 and answered its questions the same day:
| **D207** | **A step places its base either where RaidableBases picks (the default, D203) or at an admin-given spot:** x and z, plus either a height adjustment or an exact height. The spot needs the raids helper; without it the step offers only the plugin's pick. | Only an admin-given spot; keeping D203 alone. | 11.4.5 |
| **D208** | **A blocked spot is refused, with the reason.** The step does not spawn when the plugin's area check fails or the helper's water and terrain test fails, and the run log says why ("player building", "raid base", "in water"). The editor runs the same check when the step is saved. | Falling back to the plugin's pick; spawning anyway. | 11.4.5 |
The §5 build raised one more, answered on 2026-09-28:
| # | Decision | Rejected | § |
|---|---|---|---|
| **D209** | **A title rule's "NPC kills" ranks human NPCs only** (scientists and bandits): every NPC kill less the animals, which Beastbane ranks. The public leaderboard's NPC column still counts both (§5.2). | Keeping the old all-NPC count as a 25th category beside Exterminator. | 5.8 |
## 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