Crusader_Decomp/docs/map_renderer/editor-object-survey.md
2026-04-05 09:55:21 +02:00

10 KiB

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.

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.