From 6e17f13141dc085dacb115fe49d24c4698a6a4c7 Mon Sep 17 00:00:00 2001 From: wtclaude Date: Tue, 6 Oct 2026 02:14:08 -0500 Subject: [PATCH] docs(runicnpc): stage 8 decisions D302-D305 and its design The org lead's answers on 2026-10-06: - D302: the map shows an event's NPCs (a boss's adds among them) and every boss. - D303: a marker says its name and event, and a boss is bigger; no health on the map. - D304: the event page has a line per Place NPCs step, with a boss as its health; a boss's adds are not counted. - D305: core may change, as long as it stays game-agnostic and the UO integration does not break. The design: MODULE_API 1.12.0 adds an optional `live` function to an event action, whose answers core puts in the public run. map.live's RunicNPC rows gain a name, the step key and boss/add flags. A boss placed outside an event goes in the world layer. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01E14m6SuuY6i1vASFeGDBeY --- runicnpc/PLAN.md | 50 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/runicnpc/PLAN.md b/runicnpc/PLAN.md index 96283f4..6031c29 100644 --- a/runicnpc/PLAN.md +++ b/runicnpc/PLAN.md @@ -122,6 +122,10 @@ architectural or design decision is implemented. | **D299** | **Stage 7 is one stage, opening with a spike on both rigs, walked once end to end**, as stages 5 and 6 were (D253, D282) (stage 7). | 7a (the table and corpse) and 7b (the crates), each walked and merged before the next. | | **D300** | **A corpse that starts with "nothing" (D290) is truly empty:** the clothes the NPC wore come off too, so it lies unclothed and holds nothing until its table is added (stage 7 build). | Keep the worn clothes, as on any Rust corpse. | | **D301** | **A dropped crate stays until it is emptied**, as Rust's own crates do. The locked crate still removes itself after Rust's own time unhacked (7,200 s) (stage 7 build). | The profile sets how long an unopened crate stays, 30 minutes by default. | +| **D302** | **The live map shows an event's NPCs, a boss's adds among them, and every boss**, a boss placed outside an event too. A placement's ordinary NPCs (guards at Outpost) are not shown (stage 8). | Event NPCs only; every RunicNPC NPC as its own layer. | +| **D303** | **An NPC's marker says its name and its event; a boss is a bigger marker.** No health on the map (stage 8). | A boss's health on its marker; unchanged "Event NPC" dots. | +| **D304** | **While an event runs, its page has a line per Place NPCs step, and a boss as its health:** "Bandits: 3 of 8 left", "The Juggernaut: 62%". A boss's adds are not counted (stage 8). | One total with the adds; bosses only. | +| **D305** | **Core may change as needed, as long as core stays game-agnostic and the UO integration does not break** (stage 8, the org lead, on how the line reaches core's event page and the app). | — | **Borrowing, not copying.** NpcSpawn states no licence at all, so its source grants us nothing and is read only as a description of *what* can be done in Rust. HumanNPC is MIT on uMod, which is GPL-compatible, but §1.2 rules out its @@ -1467,6 +1471,52 @@ in the Android app. **Tested by** a browser walk and an emulator walk. +**The org lead's answers on 2026-10-06 are D302–D305.** + +**What is there already.** + +- **The map.** `map.live`'s `events` layer lists what a run's steps placed, re-read where each thing stands on every + ask. An event NPC is already there, as `kind: "npc"` with its `prefab` (`profile:bandit` for a RunicNPC profile). + The site draws it as a plain dot whose tooltip is "Event NPC"; the app draws the same. +- **Missing from the map:** + - a boss's adds, which RunicNPC spawns itself, so no step ledgered them; + - a boss placed outside an event; + - any name. +- **The event page is core's** (`website/EVENTS.md` §I). It shows the run's state and its phase's label, and has no + place for anything a module knows. +- **RunicNPC already answers everything the map needs.** `RunicNpc_List` carries each NPC's name, owner (`run:` for + an event's), health and `boss`. The bridge's ledger keeps the step key each NPC was placed by. + +**The design (D305).** + +- **Core: `MODULE_API` 1.12.0, one optional function on an event action, `live`.** + - While a run is live, core calls `live` for each step whose action declares one, with the step's ledgered refs and + the viewer (signed in or not, staff or not). The answer is `null`, `{ label, left, of }` or `{ label, percent }`. + - Core puts the answers in the public run as `live`, in step order, and renders them as text it does not + interpret: "Bandits: 3 of 8 left", "The Juggernaut: 62%". The app does the same from the same field. + - A call has a deadline and never throws into the page: a module that is slow or down gives no line, not an error. + The answers are cached per run for a few seconds, so a busy page does not reach the game once per reader. + - **This is an addition, so it is a minor bump.** Module-uo declares `^1.10.0` and registers no action with `live`, + so its pages and actions are unchanged. The integration kit's pin (an equality check) goes red on the bump by + design, until the kit is read again and the pin moved. +- **The bridge (protocol 13, still unreleased): `map.live`'s rows for RunicNPC.** + - An event NPC's row gains `name`, `key` (the step that placed it) and `boss: true` for a boss. + - A boss's adds join the `events` layer under their boss's run, with `add: true`. + - A boss placed outside an event joins the **`world` layer** as `kind: "boss"`, with its `name`. It is in the open + world as cargo or a helicopter is, and is shown or hidden with them. + - For the event page, a step's live NPCs and a boss's health come from the same rows. RunicNPC's health is read + there, and the site's map drops it (D303). +- **Module-Rust.** + - The map: a marker's tooltip is its name and its event's title; a boss is bigger (D303). + - `rust.npc.place`'s `live`: the step's NPCs still standing, of the count it placed, labelled with the profile's + name; a boss step answers its health instead (D304). + - Each follows the map's events layer visibility, so a page never tells a viewer what the map would hide. +- **The app.** The map's markers as the site's. The event screen renders the run's `live` lines. +- **Docs.** + - `website/MODULE_API.md` 1.12.0 and `website/EVENTS.md` §I. + - `rust-link/PROTOCOL.md` §17.3. + - The integration kit, read again and its pin moved. + ### Stage 9 — Hardening and release - **Performance to the budget stage 1 measured:** 100 NPCs on a 6000 map without the frame time crossing it.