more docs

This commit is contained in:
Maddo 2026-04-05 09:55:21 +02:00
commit a70ec15899
21 changed files with 1357 additions and 25 deletions

View file

@ -10,9 +10,29 @@ This pass widened the renderer research beyond egg and NPC spawner objects and f
- `0x005A`, `0x005B`, `0x005C`, `0x005D`, `0x0066`-`0x0069`: invisible/editor wall objects
- `0x01B8`: `camera`
- `0x0290`, `0x0336`: `LIGHT_BRIDGE_*`
- `0x0251`, `0x0318`, `0x0337`, `0x0361`: placeholder cubes and placeholder UI/editor markers
- `0x0337`, `0x0361`: placeholder cubes and placeholder UI/editor markers
- `0x0108`, `0x0113`, `0x01B9`, `0x01BA`, `0x025F`, `0x0260`, `0x02F0`, `0x0373`, `0x0399`, `0x03A1`, `0x04C8`: `wallgun_shape_*` helper cluster
## `0x0251` Frame `0`: `VALUEBOX`
- The recovered usecode corpus now closes `0x0251` directly as `VALUEBOX` in both retail games, not as a generic placeholder cube.
- Current safest read is `local payload box`, not `world prop`: the object stores numeric or text-selection data for nearby authored controllers instead of behaving like a visible gameplay pickup.
- The caller side is much clearer than `VALUEBOX.slot_20(...)` itself. Checked bodies that explicitly scan nearby `shape=0x0251` items include:
- `MONITNS` (`0x0102`) and `MONITEW` (`0x0165`)
- `WALLMNS` (`0x0367`) and Regret `WALLMEW` (`0x0436`)
- Regret `SECURNS` (`0x03FB`) and `SECUREW` (`0x043D`)
- Regret `WATCHNS` (`0x04C6`) and `WATCHEW` (`0x04DE`)
- `KEYPAD` (`0x0A0E` in Remorse, `0x0A0D` in Regret)
- Those families usually match the box on shared `QLo`, then call `VALBOX.slot_20(valueBox)` to recover the stored value. Monitor, wall-display, and security-terminal paths also feed `Item.getQHi(valueBox)` into `TEXTFILE.slot_23(...)`, so `QHi` behaves like a second text/value selector rather than dead metadata.
- `VALUEBOX::cachein` also hints at a small self-initialization lane: when the decoded value is zero it calls `FREE.slot_20(0x0383)` and writes a replacement through `VALUEBOX.slot_20(...)`. The slot-20 decompilation is still weak, so the conservative read is `possible value initialization`, not a fully closed random-number claim.
- Decompressed `.cache` scenes back the helper role strongly:
- Remorse retail caches currently expose `299` frame-0 placements. The strongest nearby controller families in the local scan are `MONITEW` (`90` hits), `MONITNS` (`65`), and `WATCHEW` (`18`).
- Regret retail caches currently expose `171` frame-0 placements. The strongest nearby controller families are `MONITEW` (`32`), `MONITNS` (`21`), `WATCHEW` (`20`), `SECURNS` (`11`), `SECUREW` (`6`), and `WALLMNS` (`6`).
- Most frame-0 boxes still carry `quality = 0`, which is consistent with the common `QLo == 0` default-link path in the callers.
- Rare authored payloads do exist: Regret map `29` has a `VALUEBOX` with `quality 23` (`QLo 23`), and Remorse maps `25`, `26`, and `141` all contain a nonzero example at `53118,30558,96` with `quality 828` (`QLo 60`, `QHi 3`, `npcNum 2`).
- Many placements occur in small chained local clusters through `nextItem`, which fits a backing-store/helper role better than a standalone scene-prop interpretation.
- Practical renderer implication: `0x0251` should be labeled `VALUEBOX`, should keep `QLo`, `QHi`, and `nextItem` visible in tooltips, and should be treated as a local controller payload object rather than as a generic placeholder cube.
## What This Means For The Renderer
- A lot of the useful information is already present without more reverse-engineering. The main problem was presentation, not raw data availability.
@ -46,7 +66,26 @@ The tooltip now exposes generalized metadata for editor/helper objects instead o
- Add dedicated filters or list views for helper subfamilies such as invisible walls, camera markers, light bridges, and placeholder cubes.
- Add shape-family frequency summaries so repeated helper markers can be audited across a map.
- Decode more shape-specific field semantics for the still-unresolved editor objects, especially the remaining non-promoted invisible-wall, camera/helper, and music-controller families, and keep folding any new results back into the dedicated USECODE-link note.
- Decode more shape-specific field semantics for the still-unresolved editor objects, especially the remaining non-promoted invisible-wall, camera/helper, music-controller, and secret-door-switch families, and keep folding any new results back into the dedicated USECODE-link note.
- Find the No Regret replacement for the Remorse `0x024F` monster-egg workflow instead of assuming the same shape is reused.
## Newly Promoted Regret-Only Controllers
- `0x0318` is now promoted as `CRUMORPH`, not a blank placeholder cube. The recovered `equip` body scans nearby NPCs for a shared internal control key derived from the item's `QLo`, temporarily transfers player control to the first live match, and then brackets `TRIGGER.slot_20` with success or failure lanes.
- `0x0366` remains `NPC_ONLY`, but the latest decompressed `.cache` sweep tightens its practical viewer behavior: actor-target arrows are still not justified, while cautious local `NPC_ONLY -> 0x04B1` same-`QLo` arrows are now strong enough to expose.
- `0x04c6` / `0x04de` are now promoted as `WATCHNS` / `WATCHEW`, not generic editor leftovers. Their recovered `slot_20` bodies scan nearby `0x0510` posts by shared `QLo` and then bracket `TRIGGER.slot_20` around a watcher-specific follow-up lane.
- `0x0510` is now better treated as a `SECRET_DOOR_POST` helper target rather than an unresolved standalone controller. The strongest current viewer behavior is a cautious local arrow from `WATCHNS` / `WATCHEW` plus tooltip decoding of its `QLo`/`QHi` bytes.
- `0x05e1` is closed as `CRYOBOX`, and nearby `0x05df` / `0x05e0` pressure-barrier faces are now promoted out of the unresolved bucket as local arrow targets keyed by shared `QLo`.
- `0x0451` / `0x05ae` are now closed as `CRAZYEW` / `CRAZYNS`, small Regret-only hit-driven NPC wake-up relays rather than vague contextual map labels.
- `0x056d` is now closed as `VIDEOBOX`, a gated controller with a direct `equip` body, even though its higher-level gameplay meaning is still less explicit than the watcher and cryobox lanes.
## Actor-Key Family Follow-Up
- The latest actor-link follow-up did not justify exporting a stable `NPC_ONLY -> actor` or `CRUMORPH -> actor` overlay from static map/cache data alone.
- Current best read is that the compared value is mutable actor field `0x63`, not a DTABLE row and not a field that the current scene export already carries.
- A direct Regret DTABLE row check at byte offset `0x63` is not enough to rescue that idea: sampled rows still read as zero there, so the actor key is not simply a persistent `NPCDat` attribute that can be copied through the existing preview pipeline.
- The same corpus also shows why the field is unstable: `TRIGGER.slot_29` / `slot_2B` can rewrite actor field `0x63` on nearby matched NPCs, so the relevant actor-side link id can change after startup.
- The broader family using this same hidden actor-key mechanism is now clearer though: `CRUMORPH`, `NPC_ONLY`, `WATCHNS`, `WATCHEW`, `THRMBCKN`, `THRMBCKE`, `SURCAMNS`, and `SURCAMEW` all compare controller-local bytes against actor field `0x63` in one of their recovered lanes.
- Practical renderer stance stays conservative: keep only the already-evidenced local helper arrows in the overlay, and surface the actor-key behavior in metadata/tooltips until a runtime or spawn-time export can close field `0x63` directly.
`0x04B1` now has a stable `CMD_LINK -> TRIGGER.slot_20` viewer target, and `0x04E3` is already promoted as `SKILLBOX::equip`, so they no longer belong in the unresolved editor-object bucket here.

View file

@ -223,12 +223,15 @@ Scene evidence lines up with that lane in No Remorse map `1`:
So the public renderer now treats same-map `shape:542` frame-`0` placements as elevator-link sources when their checked `QLo` values map to a local destination egg id.
## Current Elevator Gap
No Regret now closes one additional elevator lane that the earlier Remorse-only rule missed.
- No Regret map `3` destination egg `102` does not sit on the same currently verified `ELEVATOR` (`shape:542`) or `LIFT` (`shape:307`) lanes.
- Current scene exports for that map show no nearby `shape:542` or `shape:307` objects at all.
- A nearby editor/helper record `item:1056:fixed:1201:0:41758:33694:0` carries `mapNum 102`, but there is not yet enough executable-side evidence to promote that into a viewer arrow rule.
- The map renderer therefore leaves egg `102` unresolved for now instead of hardcoding a speculative elevator source pattern.
- Regret also ships a separate elevator family at `shape:400` (`0x0190`), which the current shape catalog leaves unnamed but the recovered usecode closes as `ELEVATOR` through `ELEVATOR::slot_20`'s local `nearby_items(shape=0x0190, origin=global[0x001e])` scan.
- In Regret `ELEVATOR::gotHit`, the gate is different from the Remorse `shape:542` body: the object must have `QLo >= 100`, and the generic local-elevator lane is `QLo < 0x00c8`.
- That generic Regret lane dispatches `ELEVATOR::slot_20` with the current map and the source object's `QLo` as the destination egg id, while `QHi` still carries the direction/state argument.
- Regret map `3` now has a concrete same-map source for destination egg `102`: `item:664:fixed:400:0:44030:9662:0` with `quality 614` (`QLo 102`, `QHi 2`).
- Current scene exports for that map still show no `shape:542` or `shape:307` objects at all near destination egg `102`, and the nearby `0x04B1` cmd-link helpers instead carry unrelated local keys such as `7`, `9`, `41`, and `60`.
So the old Regret map-`3` egg-`102` gap is now closed: it is a same-map Regret `shape:400` elevator destination, not an unresolved `shape:542`/`shape:307` case and not a `0x04B1` helper lane.
## Adjacent Editor Objects: `0x04E3` And `0x04B1`
@ -601,9 +604,9 @@ Current best read:
- `0x0366` frame `0` is an idle NPC-only trigger pad
- `QLo` is the author-selected NPC-group key, but the executable compares it against actor field `0x63`, not against the scene-export `npcNum` or a simple DTABLE row
- current scene exports do not expose that actor-side field directly, so there is not yet enough evidence to draw trustworthy `NPC_ONLY -> actor` arrows in the renderer
- a follow-up scene-cache sweep also failed to produce a convincing generic `NPC_ONLY -> 0x04B1` helper pattern; shared-`QLo` local matches look incidental rather than like a dedicated authored link lane
- a decompressed `.cache` scene sweep does show repeated nearby same-`QLo` `0x04B1` cmd helpers in authored Regret maps, so the renderer can now safely expose cautious `NPC_ONLY -> cmd QLo` arrows while still keeping `NPC_ONLY -> actor` arrows out of the overlay
That means the safe editor improvement here is naming and field emphasis, not a target-arrow rule yet.
That means the safe editor improvement here is `NPC_ONLY` naming plus local `cmd QLo` arrows only; the actor-target lane still remains tooltip-only.
### `0x0403` frame `0`: `FLAMEBOX`

View file

@ -13,6 +13,7 @@ The implementation uses extracted `class_event_index.tsv` results plus existing
| `MONITNS` (`0x0102`) | `MONITNS::use` (`slot 0x01`) | Existing gameplay notes tie shape `258` / `0x0102` to a live monitor/computer-adjacent use handler, making it a strong non-editor first-view script target. |
| `MONITEW` (`0x0165`) | `MONITEW::use` (`slot 0x01`) | Disasm crosswalks shape `0x0165` to the east-west monitor variant, which keeps the same live computer-adjacent use handler family. |
| `PANELNS` (`0x00A1`) | `PANELNS::use` (`slot 0x01`) | Verified panel-switch wrapper for the same nearby trigger-helper chain. |
| `CRUMORPH` (`0x0318`) | `CRUMORPH::equip` (`slot 0x0A`) | Recovered control-transfer pad body scans nearby NPCs for a local-`QLo` control key match, temporarily hands control to the first live hit, and then dispatches `TRIGGER.slot_20` lane `0` or `1`. |
| `NPCTRIG` (`0x0363`) | `NPCTRIG::equip` (`slot 0x0A`) | Crosswalked shape/class match; the compact slot-`0x0A` body is still the strongest active-event frontier for this trigger family. |
| `CRUZTRIG` (`0x0365`) | `CRUZTRIG::gotHit` (`slot 0x06`) | Disasm crosswalks shape `0x0365` to CRUZTRIG, and `gotHit` is the recovered live body for this trigger/helper family. |
| `VMAIL` (`0x0367`) | `VMAIL::slot_0a` (`slot 0x0A`) | Disasm crosswalks shape `0x0367` to VMAIL; slot `0x0A` is the active helper body even though its final semantic label is still weaker than the slot number. |
@ -27,7 +28,7 @@ The implementation uses extracted `class_event_index.tsv` results plus existing
| `TIMER` (`0x04C9`) | `TIMER::enterFastArea` (`slot 0x0F`) | Fast-area timer helper; the first active body arms slot `0x20` from qHi enter/leave flags and the packed `mapNum:npcNum` delay payload. |
| `SPECIAL` (`0x04CA`) | `SPECIAL::enterFastArea` (`slot 0x0F`) | Fast-area phase helper; the active entry body reads `mapNum` / `npcNum` as phase bytes and `qHi` as the delay byte before fanning out through `TRIGGER.slot_20` and `SPECIAL.slot_21`. |
| `TRIGPAD` (`0x04CD`) | `TRIGPAD::gotHit` (`slot 0x06`) | Occupancy/surface-gated trigger-pad logic lives in the recovered `gotHit` body. |
| `NPC_ONLY` (`0x0366`) | `NPC_ONLY::gotHit` (`slot 0x06`) | Active hit-driven helper lane from the extracted class/event table. |
| `NPC_ONLY` (`0x0366`) | `NPC_ONLY::gotHit` (`slot 0x06`) | Active hit-driven helper lane; the body gates on an NPC-only actor key, then brackets `TRIGGER.slot_20` lane `0` / `1` from the pad itself. |
| `FLAMEBOX` (`0x0403`) | `FLAMEBOX::equip` (`slot 0x0A`) | Recovered flame-controller body scans nearby flame helper shapes by shared `QLo` and can swap helper markers into live flame actors. |
| `SFXTRIG` (`0x04E2`) | `SFXTRIG::slot_0a` (`slot 0x0A`) | Disasm crosswalks shape `0x04E2` to the compact event-bearing SFXTRIG helper; slot `0x0A` is the stable active body even though a precise semantic label is still weaker than the slot number. |
| `DEATHBOX` (`0x04E7`) | `DEATHBOX::slot_0a` (`slot 0x0A`) | The recovered helper body matches death-link `QLo` and forwards NPC death events into `TRIGGER` lanes, so opening the helper body is now more useful than leaving the shape unmapped. |
@ -52,8 +53,26 @@ That is why the viewer opens `TRIGGER.slot_20` for pinned `0x04B1` helpers inste
- Pinned controller objects and the small set of promoted gameplay objects now expose a `USECODE` action in the tooltip.
- The action switches the workspace to the USECODE tab.
- The USECODE viewer resolves the exact class/slot target against the generated cache index instead of relying on fuzzy filename search.
- `CRUMORPH` and `NPC_ONLY` now also participate in the same cautious local `... -> cmd QLo ...` overlay rule used for other `TRIGGER.slot_20` controller families, but only for nearby `0x04B1` helpers that actually share the source object's low `quality` byte.
- `0x0011` usecode-trigger eggs now decode their `npcNum` nibble-packed X/Y ranges, resolve `QLo` into the authored family-4 class, open the matching subtype body in the USECODE tab, and draw arrows only for the narrower subtype families whose local target scans are actually recovered.
## Actor-Key Family Blocker
- The current static scene/cache export still cannot support trustworthy `controller -> actor` arrows for the Regret actor-key family.
- The strongest current reason is that the compared value is mutable actor field `0x63`, not a stable DTABLE row or an already-exported scene field.
- A direct Regret DTABLE byte check on record offset `0x63` is not enough to close that gap: sampled rows are still zero there, so the actor key is not just a plain `NPCDat` byte copied into the runtime actor.
- The same recovered corpus shows why the value is unstable: `TRIGGER.slot_29` / `slot_2B` can rewrite actor field `0x63` on nearby matched NPCs, which means the practical link id can change after the map loads.
- Current safest viewer stance is therefore: keep actor-key families named and tooltip-decoded, allow only the already-evidenced local helper arrows, and leave actor-target arrows disabled until a runtime or spawn-time export closes field `0x63` directly.
### Known Actor-Key Families
- `CRUMORPH` (`0x0318`) compares nearby actor field `0x63` against the pad `QLo` before transferring control and bracketing `TRIGGER.slot_20`.
- `NPC_ONLY` (`0x0366`) compares the incoming NPC-like source's actor field `0x63` against the pad `QLo` before bracketing `TRIGGER.slot_20` lane `0` / `1`.
- `WATCHNS` / `WATCHEW` (`0x04c6` / `0x04de`) have a stronger current local `0x0510` post lane in the viewer, but their deeper watcher body also checks nearby actor field `0x63` against controller `QLo`.
- `THRMBCKN` / `THRMBCKE` (`0x0566` / `0x0567` classes) compare nearby Thermatron actor field `0x63` against controller `QLo`.
- `SURCAMNS` / `SURCAMEW` also scan nearby NPCs by actor field `0x63` and controller `QLo` in their camera/control lane.
- `TRIGGER.slot_29` / `slot_2B` are part of the same ecosystem because one subcommand explicitly rewrites actor field `0x63` on matched nearby NPCs.
`0x04F8` remains intentionally outside the `USECODE` target list for now. The current evidence says it is a destroyable-door helper scanned by `DOOR.slot_23`, not a proven standalone usecode class the viewer should open directly.
## Newly Decoded Field Notes
@ -157,14 +176,24 @@ No currently unresolved Remorse-only editor rows remain in this note after the `
|---|---|---|
| `0x00cf` | `HAND` | Needs examination for usecode-link integration |
| `0x01d6` | `MUTANT_HOOK_CONTROL` | Needs examination for usecode-link integration |
| `0x0451` | `GIMP_DISPENSER` | Needs examination for usecode-link integration |
| `0x0510` | `SECRET_DOOR_POST` | Needs examination for usecode-link integration |
| `0x0451` | `CRAZYEW` | Integrated: `CRAZYEW::gotHit` as a Regret-only NPC wake-up relay; tooltip now treats it as a hit-driven controller rather than a generic editor placeholder. |
| `0x0510` | `SECRET_DOOR_POST` | Integrated as a local arrow target for nearby `WATCHNS` / `WATCHEW` controllers that match it by `QLo`; no separate direct usecode body promoted yet. |
| `0x0548` | `SECRET_DOOR_SWITCH` | Needs examination for usecode-link integration |
| `0x056d` | `STEAM_COLLISION_SWITCH` | Needs examination for usecode-link integration |
| `0x05ae` | `VOLCANO_CONTROLLER` | Needs examination for usecode-link integration |
| `0x05df` | `PRESSURE_BARRIER_V` | Needs examination for usecode-link integration |
| `0x05e0` | `PRESSURE_BARRIER_H` | Needs examination for usecode-link integration |
| `0x05e1` | `PRESSURE_BARRIER_SWITCH` | Needs examination for usecode-link integration |
| `0x056d` | `VIDEOBOX` | Integrated: `VIDEOBOX::equip` as the recovered Regret-only gated controller body. |
| `0x05ae` | `CRAZYNS` | Integrated: `CRAZYNS::gotHit` as a Regret-only NPC wake-up relay; tooltip now treats it as a hit-driven controller rather than a generic editor placeholder. |
| `0x05df` | `PRESSURE_BARRIER_V` | Integrated as a local arrow target for nearby `CRYOBOX` controllers that match it by `QLo`. |
| `0x05e0` | `PRESSURE_BARRIER_H` | Integrated as a local arrow target for nearby `CRYOBOX` controllers that match it by `QLo`. |
| `0x05e1` | `CRYOBOX` | Integrated: `CRYOBOX::equip` plus local `QLo` arrows to nearby `0x05DF` / `0x05E0` pressure-barrier faces. |
### Regret-Only Batch: Watchers, Cryobox, And Wake-Up Relays
- `0x04c6` and `0x04de` are no longer anonymous shared editor rows in Regret scenes. The recovered corpus names them `WATCHNS` and `WATCHEW`, and both `slot_20` bodies scan nearby `shape=0x0510` placements before bracketing `TRIGGER.slot_20` around their watcher-specific follow-up lane.
- The scene-cache cross-check supports a cautious viewer arrow rule here. Across Regret maps `1`, `10`, `13`, `14`, `15`, `16`, `18`, `200`, `201`, `215`, `29`, `30`, and others, placed `WATCHNS` / `WATCHEW` objects repeatedly sit within local helper range of `0x0510` posts and share the same low quality byte even when the raw 16-bit quality differs.
- `0x0510` therefore belongs in the editor as a local secret-door post/helper target, not as an unresolved generic editor placeholder. The recovered watcher body only treats `qHi == 0` posts as the text/door-side lane, so the current viewer promotion stays conservative and only adds the local arrow plus tooltip decoding.
- `0x05e1` is now closed as `CRYOBOX`, not a vague pressure-barrier switch. Its `equip` body matches nearby `0x05DF` and `0x05E0` shapes by shared `QLo`, then hands off into `slot_20` / `slot_21` worker lanes that wait on animation state, flip `ITEM` control slots, and spawn the steam worker path.
- The paired faces `0x05DF` and `0x05E0` remain useful human-facing labels as `PRESSURE_BARRIER_V` and `PRESSURE_BARRIER_H`, but they no longer belong in the unresolved bucket. In the viewer they are now arrow targets of nearby `CRYOBOX` controllers instead of unlabeled editor debris.
- `0x0451` and `0x05AE` are now closed as `CRAZYEW` and `CRAZYNS`. The recovered `gotHit` bodies are small but concrete: when the incoming hit source is an actor handle (`>= 0x00FF`), they check `NPC.slot_2A` and, unless the target is already in activity `12`, spawn `NPC.slot_2C` to wake or re-arm that actor. That is enough to classify them as hit-driven NPC wake-up relays rather than dispensers or volcano-only map art.
- `0x056D` is also no longer an unresolved `STEAM_COLLISION_SWITCH`. The recovered class is `VIDEOBOX`, and its `equip` body is a thin global-latch gate that either falls straight into `ITEM.slot_21` or runs a short scripted helper loop first. That is enough for a direct usecode-view target even though the higher-level gameplay meaning is still thinner than the `WATCH*` and `CRYOBOX` lanes.
## Remaining Steps
@ -173,14 +202,14 @@ The next map-viewer USECODE passes should stay evidence-backed and prioritize it
### Highest Priority
1. Extend the `0x0011` subtype table beyond the currently promoted `TRIGEGG` / `ONCEEGG`, `FLOOR1`, `MHATCHER`, `DOOREGG`, `MISS1*`, and `VIDEOEGG` lanes only when the recovered pseudocode justifies a reusable viewer target or arrow rule.
2. Do the `SURCAMNS` / `SURCAMEW` placement crosswalk so the renderer can decide whether placed `0x04c6` / `0x04de` objects deserve a direct USECODE jump or should remain callback-holder-only families.
2. Revisit the remaining Regret-only door-side helpers around `WATCHNS` / `WATCHEW`, especially `0x0548`, to decide whether they form a second stable secret-door lane beyond the now-promoted `0x0510` post targets.
3. Finish the remaining `CMD_LINK` field write-up: the current tooltip now decodes `quality`, `mapNum`, and `npcNum`, but `nextItem` still lacks a stable standalone semantic beyond appearing in authored controller records.
### Catalog And Viewer Cleanup
1. Sweep the remaining shared editor/controller shapes in the catalog table and promote the next solid names instead of leaving `(unnamed)` placeholders where the disasm or extracted corpus already gives a stable class anchor.
2. Revisit the `0x05b2`-`0x05be` music-controller cluster and decide whether those shapes belong in the USECODE viewer backlog, a scene-audio note, or both.
3. Recheck the Regret-only controller shapes (`HAND`, `MUTANT_HOOK_CONTROL`, `GIMP_DISPENSER`, `SECRET_DOOR_*`, `STEAM_COLLISION_SWITCH`, `VOLCANO_CONTROLLER`, `PRESSURE_BARRIER_*`) against the extracted class/event table before adding any direct links.
3. Recheck the remaining unresolved Regret-only controller shapes (`HAND`, `MUTANT_HOOK_CONTROL`, `SECRET_DOOR_SWITCH`) against the extracted class/event table before adding any direct links.
### Gameplay Coverage Extensions