# Editor/Helper Object Survey This pass widened the renderer research beyond egg and NPC spawner objects and focused on editor/helper shapes that already carry useful classification data in the exported scene payload. ## Evidence Base - The renderer already exports `shapeDefinitions[*]` entries with `kind`, `family`, `dimensions`, `visibilityTags`, `traits`, and the matching catalog entry. - The public catalogs already distinguish many non-gameplay helper families that are currently easy to miss in the UI. - Representative catalog anchors in Remorse include: - `0x005A`, `0x005B`, `0x005C`, `0x005D`, `0x0066`-`0x0069`: invisible/editor wall objects - `0x01B8`: `camera` - `0x0290`, `0x0336`: `LIGHT_BRIDGE_*` - `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. - Editor/helper objects often carry meaningful `mapNum`, `npcNum`, `quality`, or `nextItem` values even when they are not DTABLE-backed NPC spawners. Those raw linkage values are worth exposing because they help separate placeholder geometry from logic markers. - Catalog names already identify several broad classes that deserve different handling in the UI: - invisible walls/editor walls - camera/helper markers - light bridge / forcefield / editor-authored bridge surfaces - placeholder cubes and placeholder UI markers - auto-derived helper shapes tied to specific USECODE families like `WALLGUN` ## Focused Caution: Suspicious Map Objects Are Not Always Helpers - The map-13 jump-start follow-up around the rare jump-through wall found one especially suspicious nearby placement: `fixed:4767`, shape `0x0135`, frame `0`, at world `47966,53598,97` in the decoded retail cache. - That object looks tempting as an editor/helper candidate when viewed only from map placement, but the decoded reference data says otherwise: `0x0135` is `shape:309`, a `terrain` item with dimensions `4 x 4 x 0` and traits `solid`, `fixed`, and `land`. - The useful classification came from USECODE rather than from the exported editor/helper buckets. In the extracted corpus, class `0x0135` is `FFFLOOR`, an environmental hazard/controller family with live `gotHit`, `equip`, and `unequip` bodies. - The nearby map-13 companion object is not an editor wall flag or a hidden collision override either. The closest local trigger on the same upper platform is the family-4 egg `fixed:4770` (`shape 17`, egg id `37`, subtype selector `QLo 4`), which currently resolves to `CHANGER`, not to a direct wall-solidity helper. - Practical renderer implication: when a placement looks suspicious in map context, do not assume it belongs in the editor/helper bucket just because it sits beside editor markers. `0x0135` is a good counterexample: it is a gameplay-side environmental floor tile that only becomes legible once the USECODE class is identified. ## Implemented UI Enrichment The tooltip now exposes generalized metadata for editor/helper objects instead of reserving extra detail almost entirely for NPC spawners: - `Dimensions`: shape dimensions from the exported shape definition - `Tags`: exported visibility tags such as `editor`, `helper`, `egg`, `roof`, and `oob` - `Traits`: exported rendering/collision traits such as `occluding`, `translucent`, `solid`, `fixed`, and nonzero animation type - `Role hint`: a cautious catalog-backed note for important helper families like invisible walls, cameras, light bridges, placeholders, `WALLGUN` helper shapes, `0x04D0` NPC spawners, and `0x024F` monster eggs - `Raw linkage`: `map`, `npc`, `quality`, and `next` fields for editor/helper/egg objects so unresolved objects still expose their control data ## Practical Next Targets - 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, 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. ## `0x0318` Frame `0`: `CRUMORPH` - The older `placeholder cube` label is no longer the best behavioral read for `0x0318`. Both extracted corpora now name class `0x0318` as `CRUMORPH`: Remorse `EUSECODE_extracted/class_event_index.tsv` entry `173` and Regret `REGRET_USECODE_extracted/class_event_index.tsv` entry `174` both expose a live `equip` body at slot `0x0A`. - The two recovered `equip` bodies differ slightly in helper naming, but they agree on the same high-level lane. Both scan nearby family-`6` actors, compare the pad `QLo` against mutable actor field `0x63`, reject dead actors, transfer control to the first live match, wait until control sticks, and then dispatch `TRIGGER.slot_20` lane `0` or `1` depending on whether that controlled actor is still alive. - Current best read is therefore `control-transfer morph pad`, not decorative cube and not DTABLE-backed NPC spawner. The object's authored low quality byte is the local control key; `npcNum` does not carry the actor target directly, and the actor-side match is not a stable exported scene field. - Static scene evidence is strongest in Regret, which is why the viewer promotion was first justified there. The decompressed `.cache` scenes repeatedly show nearby same-`QLo` `0x04B1` helpers close enough to expose a cautious local `CRUMORPH -> CMD_LINK` overlay rule. - The deeper actor-target side remains intentionally unexported. The same actor-key follow-up that covered `NPC_ONLY` still applies here: the compared actor byte is mutable field `0x63`, and recovered `TRIGGER.slot_29` / `slot_2B` lanes can rewrite it after load. That keeps `CRUMORPH -> actor` arrows out of the viewer for now. - Practical viewer implication: `0x0318` should be labeled `CRUMORPH`, should expose its `QLo` / `QHi` / `mapNum` / `npcNum` / `nextItem` bytes in tooltip metadata, should open `CRUMORPH::equip` from the USECODE action, and should keep only the already-evidenced nearby same-`QLo` `0x04B1` arrows. ## Newly Promoted Regret-Only Controllers - `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. ## Shared Trigger Follow-Up: `0x00A2`, `0x03C1`, And `0x04E7` ### `0x04E7` Frame `0`: `DEATHBOX` In Both Games - The `npc death` icon label now has a clean cross-game closure, not just a Remorse-side guess. Both extracted corpora expose class `0x04E7` as `DEATHBOX`, and both corpora keep the active exported body at slot `0x0A` (`equip` / `func0A`). - That means the Remorse equivalent is exact rather than approximate: same shape id, same class label, same nearby-`DEATHBOX` scan from `NPCDEATH.slot_20`, and the same practical viewer interpretation as an NPC-death helper/controller keyed by local `QLo`. - Practical viewer implication: Regret should no longer leave `0x04E7` as an anonymous editor object when the underlying usecode/export evidence already matches Remorse exactly. ### `0x00A2`: `PANELEW` - Both extracted corpora now close `0x00A2` directly as `PANELEW`, the east-west counterpart to `PANELNS`, not as a generic unnamed wall button. - Recovered body `PANELEW::use` is small but consistent across both games: - if `frame == 0`, it returns immediately - otherwise, if the panel's map byte is clear, it dispatches `TRIGGER.slot_20` lane `0` from the panel item itself - The handler does not need to read a second bespoke target field because the downstream trigger family already uses the panel's local `QLo` as the practical authored link id. - Practical viewer implication: `0x00A2` should be labeled `PANELEW`, should open `PANELEW::use` from the USECODE action, and should participate in the same cautious nearby same-`QLo` `0x04B1` helper-arrow rule already used for `PANELNS` and other local switch/controller shapes. ### `0x03C1`: `GENERATR` - The old `generator` hunch is directionally right, but the extracted name is now explicit in both games: class `0x03C1` is `GENERATR`. - The direct active lane is very small and decisive. `GENERATR::gotHit` does not contain a long custom destruction script; it simply excludes the source item and immediately spawns `TRIGGER.slot_20` lane `0` from that same item. - Current safest read is therefore `destroyable generator/controller` rather than `free-standing scripted puzzle object`: destroying it is useful because it forwards the object's local trigger key into the standard trigger network. - There is also a second, narrower set-piece lane in Remorse. Recovered `SATARG::use` explicitly scans nearby `shape=0x03C1` items during its countdown/shutdown sequence and drives them through `ITEM.slot_28` beside the related `0x03BF` bank, which fits authored generator-bank or power-node shutdown scenes rather than a different standalone class meaning. - Practical viewer implication: `0x03C1` should be labeled `GENERATR`, should open `GENERATR::gotHit` from the USECODE action, and should expose the same cautious nearby same-`QLo` `0x04B1` helper arrows as other trigger-source objects because its recovered destruction lane feeds directly into `TRIGGER`. ## 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.