Crusader_Decomp/USECODE/EUSECODE_extracted/immortality_body_structure.md
MaddoScientisto daa363c3d2 Add 'annotate-usecode' command to import USECODE IR JSON annotations
- Introduced a new command 'annotate-usecode' to import USECODE IR JSON annotation hints as Ghidra comments on compiled anchors.
- Added argument parsing for multiple IR JSON files, comment type selection, and a dry-run option.
- Implemented logic to read annotation records from the provided IR files and set comments on the corresponding addresses in Ghidra.
- Enhanced JSON schema to include response structure for the new command.
2026-03-24 18:14:20 +01:00

5.7 KiB

Immortality Body Structure

This report decodes one layer deeper than the literal scan for the surviving EVENT and NPCTRIG frontier. It is still heuristic: the output is limited to repeatable byte grammar, subheader boundaries, field-tag trailers, and motif offsets that can be cross-checked against the 000d slot-backed runtime lane.

EVENT slot 0x0A

  • Body length: 8150 bytes.
  • Open header: 0x5A 0x2F 0x5C 0x1EF5 -> EVENT with embedded event-code byte 0x11.
  • Clause terminators (0x7A): 3; local labels (0x5B): 383.
  • Internal labeled subheaders (0x53 0x5C <u16> EVENT): 90 -> 0x0088->0x1E6E, 0x00F8->0x1DFE, 0x0123->0x1DD3, 0x0149->0x1DAD, 0x0174->0x1D82, 0x01CC->0x1D2A, 0x0210->0x1CE6, 0x0236->0x1CC0, 0x0261->0x1C95, 0x028E->0x1C68, 0x02B9->0x1C3D, 0x0361->0x1B95.
  • Tail field tags: 69:0000->referent, 69:000A->event, 24:02FE->item, 69:6574->m, 24:02FC->source, 24:02FA->dest, 24:02F8->door, 24:05F3->wp, 69:00F1->counter, 69:00EF->counter2, 24:02ED->n, 69:00EB->link, 69:00E9->cx, 69:00E7->cy, 69:00E5->ex, 69:00E3->ey, 69:00E1->time, 69:00DF->op, 69:00DD->opp, 24:02DB->post1, 24:02D9->post2, 24:02D7->floor, 69:00D5->dir, 69:00D3->qHi, 24:02D1->flicMan, 69:4D63->an.
Motif Count First Offsets
call_40_06_4c_02 47 0x0011,0x010F,0x0160,0x024D,0x02A5,0x034D,0x0396,0x03F2,0x0422,0x047C,...
call_40_06_0f_04 50 0x001A,0x003C,0x0045,0x00C6,0x00D4,0x01EB,0x01F4,0x032D,0x0374,0x03D2,...
subheader_53_5c 90 0x0088,0x00F8,0x0123,0x0149,0x0174,0x01CC,0x0210,0x0236,0x0261,0x028E,...
writeback_57_02 44 0x007A,0x00EA,0x013B,0x01BE,0x0228,0x068F,0x0708,0x0799,0x08EA,0x0949,...
branch_59_0a 61 0x0072,0x00E2,0x0108,0x0133,0x0159,0x01B6,0x0220,0x0246,0x029E,0x0346,...
branch_3f_0a 39 0x0025,0x0057,0x019B,0x0271,0x02D4,0x02EE,0x0308,0x0322,0x03C7,0x045E,...
field_4b_fe_0f 23 0x0408,0x0412,0x0439,0x044D,0x0493,0x04A3,0x04EF,0x04FF,0x055E,0x0587,...
field_4b_fc_0f 3 0x0569,0x0575,0x057E
push_24_51 51 0x0029,0x005B,0x019F,0x0275,0x02D8,0x02F2,0x030C,0x0326,0x033F,0x03CB,...
event_field_69_0a_00 1 0x1F09

NPCTRIG slot 0x0A

  • Body length: 373 bytes.
  • Open header: 0x5A 0x06 0x5C 0x013E -> NPCTRIG with embedded event-code byte 0x11.
  • Clause terminators (0x7A): 1; local labels (0x5B): 12.
  • Internal labeled subheaders (0x53 0x5C <u16> NPCTRIG): 5 -> 0x0064->0x00DB, 0x0093->0x00AC, 0x00C2->0x007D, 0x00F1->0x004E, 0x0120->0x001F.
  • Tail field tags: 69:0000->referent, 69:000A->event, 24:02FE->item, 69:6574->m, 24:02FC->item2, 69:6574->m2, 24:02FA->n.
Motif Count First Offsets
call_40_06_4c_02 1 0x0011
call_40_06_0f_04 1 0x001D
subheader_53_5c 5 0x0064,0x0093,0x00C2,0x00F1,0x0120
writeback_57_02 5 0x0056,0x0085,0x00B4,0x00E3,0x0112
branch_59_0a 0 -
branch_3f_0a 5 0x0045,0x0074,0x00A3,0x00D2,0x0101
field_4b_fe_0f 0 -
field_4b_fc_0f 0 -
push_24_51 5 0x0049,0x0078,0x00A7,0x00D6,0x0105
event_field_69_0a_00 1 0x0152

NPCTRIG slot 0x20

  • Body length: 345 bytes.
  • Open header: 0x5A 0x06 0x5C 0x0120 -> NPCTRIG with embedded event-code byte 0x01.
  • Clause terminators (0x7A): 1; local labels (0x5B): 19.
  • Internal labeled subheaders (0x53 0x5C <u16> NPCTRIG): 1 -> 0x00BA->0x0067.
  • Tail field tags: 69:0000->referent, 69:000A->typeNpc, 24:02FE->n, 24:02FC->item, 69:6574->m, 24:02FA->item2, 69:6574->m2.
Motif Count First Offsets
call_40_06_4c_02 2 0x0011,0x002C
call_40_06_0f_04 3 0x0085,0x008E,0x0097
subheader_53_5c 1 0x00BA
writeback_57_02 0 -
branch_59_0a 0 -
branch_3f_0a 1 0x0051
field_4b_fe_0f 10 0x0053,0x0060,0x006D,0x007A,0x00A0,0x00CC,0x00D9,0x00E6,0x0107,0x0119
field_4b_fc_0f 0 -
push_24_51 0 -
event_field_69_0a_00 1 0x0134

Current Read

  • EVENT 0x0A is the generic hub-shaped body: it has 90 internal labeled subheaders and the widest field trailer (69:0000->referent, 69:000A->event, 24:02FE->item, 69:6574->m, 24:02FC->source, 24:02FA->dest, 24:02F8->door, 24:05F3->wp, 69:00F1->counter, 69:00EF->counter2, 24:02ED->n, 69:00EB->link, 69:00E9->cx, 69:00E7->cy, 69:00E5->ex, 69:00E3->ey, 69:00E1->time, 69:00DF->op, 69:00DD->opp, 24:02DB->post1, 24:02D9->post2, 24:02D7->floor, 69:00D5->dir, 69:00D3->qHi, 24:02D1->flicMan, 69:4D63->an).
  • NPCTRIG 0x0A is the compact player-trigger candidate: it reuses the same class-labelled open header and subheader grammar, but it stays constrained to 69:0000->referent, 69:000A->event, 24:02FE->item, 69:6574->m, 24:02FC->item2, 69:6574->m2, 24:02FA->n instead of the wider EVENT field set.
  • NPCTRIG 0x20 keeps the same constrained field set as NPCTRIG 0x0A and changes only the embedded prolog event-code byte (0x01 vs 0x11), which fits a variant trigger/setup lane better than a separate generic hub.
  • The repeated 0x53 0x5C <u16> LABEL subheaders and dense 0x5B <u16> local labels make these bodies look like inline clause streams rather than single flat payloads, which is consistent with the 000d:21ed -> 000d:22bc runtime lane that copies variable-length inline bytes first and only then consumes compact metadata bytes plus streamed words.
  • The surviving slot focus is still 0x0A: both EVENT and NPCTRIG expose non-zero slot-0x0A bodies, and the runtime side has an exact offset-specialized masked wrapper for slot 0x0A at 0005:2c35 (entity_vm_context_try_create_mask_0400_slot0a_with_offset).