Crusader_Decomp/docs/usecode-jelyhack-analysis.md
2026-04-07 17:16:44 +02:00

11 KiB

JELYHACK USECODE Analysis

Scope

This note focuses on the currently exported pseudocode and byte-level decode for JELYHACK class 277 / class id 0x04D3, especially its only non-zero event body: slot 0x01 (use).

Current generated pseudocode lives at:

  • USECODE/EUSECODE_extracted/pseudocode/JELYHACK/slot_01_use.txt
  • USECODE/EUSECODE_extracted/pseudocode/JELYH2/slot_01_use.txt

Plain-language answer

If you want the short version first:

  • JELYHACK does not look like the object that contains the real island gameplay script.
  • It looks more like a small anchor object that gives the engine a referent identity and a tiny shared use stub.
  • When the player uses it, the stub appears to register a generic interaction/info value (0x0207) and then immediately exits.
  • The richer gameplay behavior is more likely carried by nearby event-bearing records such as REE_BOOT, SURCAMEW, or SFXTRIG.

So in easy words: JELYHACK currently looks less like "the script that does the JELYHACK puzzle" and more like "the map object or anchor that other real trigger objects point at or work beside."

That also answers "what uses it" in the safest current sense:

  • the referent/owner side of the runtime uses it as an anchor-like record
  • the player can still use it, but that use body is tiny and generic
  • the surrounding event-bearing attachment records are the more likely carriers of the actual gameplay logic

Direct decompilation result

Current readable decompilation for JELYHACK::use:

function jelyhack_use() /* entry=277 class_id=0x04D3 slot=0x01 */
{
  entry:
    set_info(0x0207, *(arg_06));
    process_exclude();
    return;

}

Byte-faithful decode of the same body:

00D4: 5A init                     local_bytes=0x0
00D6: 5C symbol_info              symbol=JELYHACK
00E2: 0B push_word_immediate      value_u16=0x0207
00E5: 40 push_local_dword         [BP+06h]
00E7: 4C push_indirect            size=0x2
00E9: 77 set_info
00EA: 78 process_exclude
00EB: 5B line_number              line_number=0x00DB
00EE: 50 ret

That readable pseudocode is currently hiding one important detail: there is a small trailer after ret.

Pentagram's older disassembly shows the body like this:

Func_1 (Event 1) JELYHACK::use():
        0001: 5A init 00
        0003: 5C symbol info offset 001Ch = "JELYHACK"
        000F: 0B push 0207h
        0012: 40 push dword [BP+06h]
        0014: 4C push indirect 02h bytes
        0016: 77 set info
        0017: 78 process exclude
        0018: 5B line number 219 (00DBh)
        001B: 50 ret
00: 01 type=69 (i) [BP+00h] (00) 00 referent
        002A: 7A end

So the extra bytes are not currently best read as hidden live code. The strongest reading is:

  • executable body ends at ret
  • one post-return debug/local-symbol record follows
  • that record names one slot/argument as referent
  • then the body terminates with 0x7A end

That matters because it argues against the dramatic interpretation that we found a chopped-off second script. Right now the evidence fits "metadata trailer" much better than "cut content."

What the trailer most likely represents

Current best explanation of the bytes after ret:

  • they are post-return symbol/debug metadata, not a second reachable instruction stream
  • they preserve the name referent, which matches the descriptor-side picture where JELYHACK only exposes a referent field
  • they reinforce the idea that this class is an anchor/owner record, not a rich event script

In practical terms, the trailer is telling us something like: "this body knows about one meaningful value here, and that value is called referent."

That is useful evidence, but it is not new gameplay logic.

Suggested readable pseudocode form

For human reading, the most honest pseudocode form is probably this:

function jelyhack_use() /* entry=277 class_id=0x04D3 slot=0x01 */
{
    set_info(0x0207, *(arg_06));
    process_exclude();
    return;

    /* post-return metadata (not executable):
         debug_symbol referent [BP+00h] type=0x69
    */
}

That presentation keeps the important distinction visible:

  • the function really returns where it looks like it returns
  • there is still meaningful trailer data after that return
  • the trailer is metadata, not currently credible as reachable lost code

What is directly supported

  1. JELYHACK is not an active event hub in the same sense as EVENT, NPCTRIG, or _BOOT classes.
  2. Its only non-zero slot is 0x01 (use), with raw_event_entry_word = 0x002A, raw_code_offset = 0x00000001, and body range 0x00D4..0x00FE (42 bytes).
  3. The actual executable body is tiny: one set_info(0x0207, *(arg_06)), one process_exclude(), then return.
  4. JELYH2 is the same script body for practical purposes. The only pre-return differences are the symbol label string and line-number metadata; control flow and active ops are otherwise the same.
  5. A post-return trailer still preserves referent metadata, which lines up with the descriptor-side fact that JELYHACK only exposes referent.
  6. JELYHACK still exposes only the referent field on the descriptor side, which keeps it in the referent-anchor category rather than the event-bearing category.

Comparison against the exported pseudocode corpus

The JELYHACK::use body is not unique. Normalizing away only the function header, the exact same readable body currently appears in these seven exports:

  • AVATAR/slot_01_use.txt
  • GRAVITON/slot_01_use.txt
  • IONIC/slot_01_use.txt
  • JELYHACK/slot_01_use.txt
  • JELYH2/slot_01_use.txt
  • PLASMA/slot_01_use.txt
  • WEA_BOOT/slot_01_use.txt

That matters because it argues against a special-purpose JELYHACK event implementation. The more defensible reading is that this is one small generic use stub reused across several classes.

There is also a second useful comparison: other classes often start with the same set_info(...); process_exclude(); prologue and then continue into much richer logic. DATALINK::use is a good example: it begins with the same opening but then expands into a larger branch-heavy routine. So the set_info/process_exclude pair is best treated as a common preamble, not the whole semantic payload of a class family.

What JELYHACK::use most likely does

Current safest reading:

  • It performs a small generic use-entry setup using info id 0x0207 and the dereferenced word at arg_06.
  • It then marks the current process or handler for exclusion/suppression through process_exclude().
  • It does not itself implement the richer trigger logic one would expect from an active gameplay event script.

The unresolved part is the exact gameplay meaning of set_info(0x0207, *(arg_06)). The exported corpus shows this exact pattern in multiple unrelated classes, so 0x0207 currently looks more like a shared UI/message/interaction setup code than a JELYHACK-specific action.

That leads to the simplest current gameplay explanation:

  • the object can be "used"
  • the engine records a generic interaction fact about that use
  • the object then gets out of the way
  • anything interesting that happens next probably belongs to a neighboring event-bearing attachment, not to JELYHACK itself

What it probably does not do

The current evidence argues against several stronger claims:

  • It is probably not the main script that drives the JELYHACK gameplay behavior by itself.
  • It is probably not the actual event-bearing payload that reaches the richer runtime opcode lanes recovered around 000d:208b, 000d:21ed, and 000d:22bc.
  • It is probably not a unique script template specialized only for the JELYHACK object.
  • The bytes after ret are probably not a hidden reachable second branch or a simple "return was moved upward" cut-content remnant.

If this were cut executable content, we would want to see stronger signs such as:

  • a branch target that lands in the trailer
  • a sensible opcode stream after ret
  • different trailers between JELYHACK and JELYH2 that might hint at divergent behavior

At the moment we have the opposite pattern: a small named metadata record, a clean end, and strong similarity across the twin classes.

Relationship to JELYH2 and the surrounding island

JELYHACK and JELYH2 remain the clearest referent-anchor twins in the extracted USECODE data:

  • same lone live slot 0x01
  • same event-table row shape (0x002A / 0x00000001)
  • same 42-byte body length
  • same readable use body before return
  • same descriptor-side role: referent-anchor

This fits the broader neighborhood evidence already captured elsewhere:

  • JELYHACK / JELYH2 sit beside event-bearing neighbors such as REE_BOOT, SURCAMEW, and SFXTRIG
  • those neighbors expose event or eventTrigger fields and carry materially richer behavior bodies
  • the current best model is therefore still referent anchor + neighboring event-bearing attachment, not JELYHACK as a standalone active event core

Comparison with nearby event-bearing neighbors

The generated pseudocode reinforces that split.

REE_BOOT slot 0x0A and SFXTRIG slot 0x0A diverge immediately from the JELYHACK body:

  • they use set_info(0x0211, *(arg_06)) instead of 0x0207
  • they perform status checks, helper calls, spawns, waits/suspends, and other active logic
  • they therefore look like genuine event-bearing routines rather than passive anchor stubs

DATALINK slot 0x01 is also instructive in the other direction:

  • it starts with the same set_info/process_exclude preamble
  • but it then continues into a much larger routine
  • so the shared opening is not enough to classify a body as anchor-only or event-bearing by itself

Current best conclusion

The decompiled JELYHACK::use body is important mainly because it supports a negative result cleanly:

  • JELYHACK is not hiding a large active event script in its only live slot
  • its visible use handler is a minimal generic stub shared with several other classes
  • the bytes after ret look like a metadata trailer naming referent, not like secret live code
  • the interesting gameplay semantics around the JELYHACK island are still more likely to live in neighboring event-bearing descriptors attached to the same referent context

So the current best human-readable model remains:

anchor JELYHACK(referent)
anchor JELYH2(referent)

use:
    set_info(shared_use_code_0x0207, deref(arg_06))
    process_exclude()
    return

actual island behavior:
    likely carried by neighboring event-bearing attachments such as REE_BOOT / SURCAMEW / SFXTRIG

That is a stronger and cleaner claim than the older vague label referent anchor: the exported pseudocode now shows that the anchor really does have code, but the code is a tiny shared interaction stub, not the island's main behavior engine.