Crusader_Decomp/docs/map_renderer/trigger-usecode-links.md
2026-04-02 01:15:16 +02:00

18 KiB

Map Viewer Object -> USECODE Links

This note records the current evidence-backed USECODE targets surfaced by the map viewer for pinned editor/controller objects and a small set of non-editor gameplay objects with verified active usecode lanes.

The implementation uses extracted class_event_index.tsv results plus existing controller notes rather than filename guesses. The viewer resolves an exact { className, slot / eventNameHint } pair against the generated usecode cache index and then opens the matching pseudocode body in the USECODE tab.

Stable Viewer Targets

Shape / class Viewer target Why this body is the right inspection point
BOX_EW (0x0080) BOX_EW::use (slot 0x01) Recovered switch body that dispatches the local QLo link into TRIGGER.slot_20.
0x0011 family-4 usecode egg Dynamic per QLo: TRIGEGG::hatch, ONCEEGG::hatch, FLOOR1::enterFastArea, MHATCHER::hatch, DOOREGG::hatch, and other authored subtype bodies The runtime resolves family-4 egg classes as 0x0900 + QLo, so the viewer now opens the exact subtype-selected body instead of treating every 0x0011 as one generic placeholder.
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.
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.
CARD_NS (0x031D) CARD_NS::use (slot 0x01) Thin wrapper into the downstream SWITCH / TRIGGER path. Regret also exposes cast, but use remains the stable first inspection point.
SPANEL (0x03AA) SPANEL::use (slot 0x01) Same local QLo-keyed switch/controller family as PANELNS and CARD_NS.
FASTSKIL (0x0120) FASTSKIL::enterFastArea (slot 0x0F) Difficulty-gated trigger router, including the verified QLo, QLo + 1, and QLo + 2 remap lane.
SKILLBOX (0x04E3) SKILLBOX::equip (slot 0x0A) Corpus-backed skill-gated controller body; this is the active recovered lane, not enterFastArea.
CHEST_NS (0x054F) CHEST_NS::use (slot 0x01) The live chest-open handler runs the animation/audio path and the same general FREE-backed content-spawn flow as the east-west chest family.
CHEST_EW (0x0550) CHEST_EW::use (slot 0x01) The live chest-open handler runs the animation/audio path and a FREE-backed content-spawn flow, making it a useful general gameplay object target even though it is not editor-centric.
EVENT (0x0361) EVENT::equip (slot 0x0A) Large multiplexer body used by the generic event-controller family.
NPC_SPAWNER_04D0 (0x04D0, frame 0) MONSTER::enterFastArea (slot 0x0F) Frame-0 spawners participate in the verified MONSTER auto-enter-area lane when map bit 0x08 is clear, so this is now the right first inspection point for authored 0x04D0 placements.
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.
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.
BRO_BOOT (0x04FE) BRO_BOOT::enterFastArea (slot 0x0F) Verified helper body scans nearby SPANEL items by shared QLo, applies ITEM control slots, and runs the boot animation loop.
STEAMBOX_HAZARD_CONTROLLER (0x0500) STEAMBOX::equip (slot 0x0A) Recovered hazard-controller body matches nearby steam helpers by shared QLo and routes them through event 0 / 1 control lanes.
ALARMHAT (0x0561) ALARMHAT::equip (slot 0x0A) Local alarm scan that walks nearby 0x04D0 helper items.
ALRMTRIG (0x0581) ALRMTRIG::equip (slot 0x0A) Alert relay that selects TRIGGER lanes from map-array and world-alert state.
CMD_LINK (0x04B1, TRIGGER) TRIGGER::slot_20 (slot 0x20) High-slot fan-out entry used by nearby controller families; the named low event slots are empty here, so the viewer jumps straight to the first verified active high slot.

Current Rule For TRIGGER

TRIGGER is the one intentional special case.

The extracted class/event tables show no active named slots in the 0x00..0x1f range for TRIGGER, but they do show populated higher slots 0x20..0x2b. Existing renderer notes and exported pseudocode both point to TRIGGER.slot_20 as the shared entry that nearby controller shapes keep spawning when they match on local QLo or phase lane.

That is why the viewer opens TRIGGER.slot_20 for pinned 0x04B1 helpers instead of trying to invent a named event label that the corpus does not support.

TRIGGER.slot_20 is still not fully decoded. The current body is the right landing point for inspection, but several loose or nearly empty branches remain in the recovered pseudocode, especially in the local_04 == 1, local_04 == 2, and parts of the local_04 == 3 fan-out.

Practical Result In The Viewer

  • 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.
  • 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.

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

0x0011 usecode-trigger egg

  • The active exported family-4 0x0011 records are proximity/usecode-trigger eggs, not DTABLE NPC spawners.
  • mapNum remains the egg id.
  • quality & 0xFF is the subtype selector for this family.
  • The runtime resolves the usecode class as 0x0900 + QLo.
  • Current authored subtype sets are:
    • Remorse: 0, 1, 2, 4, 13 -> TRIGEGG, ONCEEGG, FLOOR1, CHANGER, MISS1EGG
    • Regret: 0, 1, 2, 5, 8, 10, 13, 24 -> TRIGEGG, ONCEEGG, FLOOR1, MHATCHER, CHANGER, DOOREGG, MISS1, VIDEOEGG
  • npcNum packs xRange = high nibble and yRange = low nibble.
  • Crusader multiplies each nibble by 64 world units and uses a +/-48 Z window for the trigger test.
  • TRIGEGG and ONCEEGG route into TRIGGER.slot_20 on hatch/unhatch, so the renderer now draws local arrows to nearby 0x04B1 helpers by shared QLo.
  • Regret MHATCHER scans nearby frame-0 0x04D0 helpers whose QLo matches the egg id in mapNum, so the renderer now draws that local helper lane too.
  • Regret DOOREGG scans nearby family-1 door objects whose QLo matches the egg id in mapNum, so the renderer now exposes that local door lane.
  • Map-13 Remorse CHANGER example fixed:4770 now gives the subtype a concrete local read: egg id 37 (mapNum) sits beside roof tiles whose QLo is also 37, matching the extracted CHANGER::hatch body that destroys nearby roofs keyed by egg id.
  • FLOOR1, CHANGER, MISS1*, and VIDEOEGG remain subtype-aware in the tooltip and USECODE target, but they still do not justify a generic local-arrow rule.

0x04C9 TIMER

  • The disasm corpus identifies usecode class 1225 as TIMER.
  • enterFastArea and leaveFastArea only arm the worker lane; TIMER.slot_20 performs the wait loop and then fans out into TRIGGER.slot_20 with phases 0x80 or 0x81.
  • mapNum:npcNum pack the base timer payload as a 16-bit tick count.
  • qHi >> 5 selects one of the trim percentages 0, 10, 25, 40, 50, 60, 75, 90, and the worker subtracts that percentage from the packed delay before waiting.
  • The low qHi bits act as control flags: bit 0 controls repeat-vs-clear, bit 1 arms on enter-fast-area, bit 2 arms on leave-fast-area, while bits 3 and 4 steer later routing branches inside the worker.

0x04CA SPECIAL

  • The disasm corpus identifies usecode class 1226 as SPECIAL.
  • enterFastArea / leaveFastArea use mapNum and npcNum as small phase/control bytes rather than DTABLE rows.
  • qHi acts as the delay byte used by SPECIAL.slot_21, while QLo remains the local link byte.
  • SPECIAL.slot_21 can temporarily add 3 to QLo, route through TRIGGER.slot_20, then restore the original QLo.
  • This is enough evidence to promote SPECIAL::enterFastArea as the stable first-view body even though some higher-phase cases still live deeper in slot 0x21.
  • QLo is the local link id.
  • QHi low three bits choose subcommand 0..6, and the upper five bits carry the subcommand argument.
  • mapNum low bits decode mode, item-targeting flag, phase lane, and low-priority behavior.
  • mapNum high bits plus npcNum build the 11-bit target code used for exact-shape matching or family sentinels.
  • nextItem still appears in authored records, but this pass did not recover a stable standalone semantic for it beyond the existing TRIGGER fan-out path.

Editor Catalog Sweep

The viewer catalog currently marks 39 Remorse shapes and 48 Regret shapes as editor objects. The tables below record which entries already have a viewer integration target and which still need examination before they should grow a USECODE link.

Shared Editor Objects

Shape Catalog name Status
0x0011 (unnamed) Integrated: dynamic family-4 USECODE target from QLo, plus local arrows for the recovered TRIGEGG / ONCEEGG, MHATCHER, and DOOREGG lanes.
0x0060 INVISIBLE_WALL_UW Needs examination for usecode-link integration
0x0061 INVISIBLE_WALL_NS Needs examination for usecode-link integration
0x0062 INVISIBLE_WALL_EW Needs examination for usecode-link integration
0x00f1 BROKEN_OVERLAY Needs examination for usecode-link integration
0x0120 FASTSKIL Integrated: FASTSKIL::enterFastArea
0x017d PLACEHOLDER_KEY_CUBE Needs examination for usecode-link integration
0x0193 SPECIAL_FIRE_WALL Needs examination for usecode-link integration
0x01b0 LIGHT_BRIDGE_V Needs examination for usecode-link integration
0x01b1 LIGHT_BRIDGE_H Needs examination for usecode-link integration
0x0200 NUMBERS Needs examination for usecode-link integration
0x0361 EVENT Integrated: EVENT::equip
0x0403 FLAMEBOX Integrated: FLAMEBOX::equip
0x04b1 CMD_LINK Integrated: TRIGGER::slot_20
0x04c9 TIMER Integrated: TIMER::enterFastArea
0x04ca SPECIAL Integrated: SPECIAL::enterFastArea
0x04d0 NPC_SPAWNER_04D0 Integrated: MONSTER::enterFastArea for frame-0 placements
0x04e2 SFXTRIG Integrated: SFXTRIG::slot_0a
0x04e3 SKILLBOX Integrated: SKILLBOX::equip
0x04e7 DEATHBOX Integrated: DEATHBOX::slot_0a
0x04fe BRO_BOOT Integrated: BRO_BOOT::enterFastArea
0x0561 ALARMHAT Integrated: ALARMHAT::equip
0x0500 STEAMBOX_HAZARD_CONTROLLER Integrated: STEAMBOX::equip
0x0581 ALRMTRIG Integrated: ALRMTRIG::equip
0x05a0 HIDENSEEKR Needs examination for usecode-link integration
0x05a1 DOOMSDAY_COUNTER Needs examination for usecode-link integration
0x05b2 MUSIC_CONTROLLER_05B2 Needs examination for usecode-link integration
0x05b3 MUSIC_CONTROLLER_05B3 Needs examination for usecode-link integration
0x05b4 MUSIC_CONTROLLER_05B4 Needs examination for usecode-link integration
0x05b5 MUSIC_CONTROLLER_05B5 Needs examination for usecode-link integration
0x05b6 MUSIC_CONTROLLER_05B6 Needs examination for usecode-link integration
0x05b7 MUSIC_CONTROLLER_05B7 Needs examination for usecode-link integration
0x05b8 MUSIC_CONTROLLER_05B8 Needs examination for usecode-link integration
0x05b9 MUSIC_CONTROLLER_05B9 Needs examination for usecode-link integration
0x05ba MUSIC_CONTROLLER_05BA Needs examination for usecode-link integration
0x05bb MUSIC_CONTROLLER_05BB Needs examination for usecode-link integration
0x05bc MUSIC_CONTROLLER_05BC Needs examination for usecode-link integration
0x05bd MUSIC_CONTROLLER_05BD Needs examination for usecode-link integration
0x05be MUSIC_CONTROLLER_05BE Needs examination for usecode-link integration

Remorse-Only Editor Objects

No currently unresolved Remorse-only editor rows remain in this note after the NPCTRIG crosswalk promotion.

Regret-Only Editor Objects

Shape Catalog name Status
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
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

Remaining Steps

The next map-viewer USECODE passes should stay evidence-backed and prioritize items that either still appear as generic editor placeholders in the catalogs or already have partial reverse-engineering notes that are not yet promoted into the viewer.

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.
  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.

Gameplay Coverage Extensions

  1. Verify whether non-frame-0 0x04d0 placements have a second stable inspection target or should stay documented as paired/helper states only.
  2. Revisit helper families that already have partial notes but no viewer promotion yet, especially the invisible-wall/editor-wall lane and any camera/helper markers that forward into event-trigger classes rather than acting as pure geometry.
  3. When a family differs by game, keep the stable cross-game viewer target by default and only add game-specific fallback event names after the extracted corpus proves the divergence.

Validation Rules For Future Passes

  1. Keep renames grounded in a direct shape/class crosswalk, exported body evidence, or an existing note with clear provenance.
  2. After each promotion, rerun the renderer cache build and update this note's sweep tables in the same batch so the backlog stays current.
  3. Do not promote callback-holder families like SURCAMNS / SURCAMEW as ordinary active-event objects unless the placed-shape behavior is established, not just the class name.

Current limitation: if a future build changes the active body for a class in one game only, the viewer still prefers the stable cross-game target above and only uses explicit fallback event names where already justified by the extracted corpus.