306 lines
No EOL
16 KiB
Markdown
306 lines
No EOL
16 KiB
Markdown
# Movable Wall Trigger Investigation
|
|
|
|
This note records the current evidence for movable walls that do not advertise their opener through the viewer's older helper-arrow rules.
|
|
|
|
## Result
|
|
|
|
The checked cases fit one local cluster pattern:
|
|
|
|
- a family-4 usecode trigger egg sits beside the wall
|
|
- a nearby `0x04B1` CMD_LINK helper uses the egg id from `mapNum` as its `QLo` link byte
|
|
- that helper is the practical local opener for the wall face
|
|
|
|
The viewer now draws that cluster as two links when the pattern is present:
|
|
|
|
- egg -> CMD_LINK
|
|
- CMD_LINK -> movable wall
|
|
|
|
The rule is intentionally narrow. It only applies to checked `TRIGEGG` / `ONCEEGG` style eggs when a nearby CMD helper and one of the verified movable-wall target shapes are both present.
|
|
|
|
## Checked Cases
|
|
|
|
### Map 13
|
|
|
|
- wall: `fixed:3964`
|
|
- visible wall face near `49790, 50206, 0`
|
|
- nearby trigger egg: `fixed:3970`, shape `0x0011`, `mapNum = 5`, near `49794, 50598, 0`
|
|
- second nearby trigger egg with the same egg id: `fixed:3955`, shape `0x0011`, `mapNum = 5`, near `49604, 50516, 0`
|
|
- stacked CMD helpers in the same local lane:
|
|
- `fixed:3972`, shape `0x04B1`, near `49790, 50558, 0`, `mapNum = 38`, `npcNum = 155`, `quality = 0x0105`
|
|
- `fixed:3956`, shape `0x04B1`, near `49790, 50558, 4`, `mapNum = 46`, `npcNum = 155`, `quality = 0x0005`
|
|
- `fixed:3976`, shape `0x04B1`, near `49790, 50558, 8`, `mapNum = 134`, `npcNum = 208`, `quality = 0x0005`
|
|
|
|
This is still the cleanest same-column movable-wall cluster, but the deeper map-13 pass shows that it is not just one egg wired straight to one wall.
|
|
|
|
#### Map 13: Proven Trigger Chain
|
|
|
|
The currently proven chain is:
|
|
|
|
- avatar crosses the hidden family-4 `TRIGEGG` footprint for egg id `5`
|
|
- leaving that footprint runs `TRIGEGG::unhatch`, not `hatch`
|
|
- `TRIGEGG::unhatch` spawns `TRIGGER.slot_20(..., 0x81, ...)`
|
|
- `TRIGGER.slot_20` scans nearby `0x04B1` CMD helpers and keeps only the phase-1 lane (`mapNum & 8`)
|
|
- in this local stack, that selects `fixed:3956`
|
|
- the selected CMD then routes into the item-targeting trigger worker path
|
|
|
|
So the wall-opening logic for `fixed:3964` is definitely tied to the `0x81` unhatch path, meaning the authored event fires when the player leaves the trigger region rather than when entering it.
|
|
|
|
#### Map 13: Why This Still Looks Like A Set Piece
|
|
|
|
Several nearby placements suggest a more specific authored sequence than a simple hidden strip trigger:
|
|
|
|
- there are two separate `TRIGEGG` items using the same egg id `5` in the same local area
|
|
- there are three stacked `0x04B1` helpers at the same `x/y` with different `z` values and different encoded payloads
|
|
- nearby helper/door-like pieces also sit in the same cluster, including shape `1278` and several `353` / `354` objects
|
|
|
|
That combination looks more like a local puzzle or staged control cluster than a generic walk-near-door opener.
|
|
|
|
#### Map 13: Current Open Gap
|
|
|
|
The last mutation step is still unresolved, but the current gap is narrower than before.
|
|
|
|
The relevant phase-1 CMD path does reach `TRIGGER.slot_23`, and the selected helper in the checked stack (`fixed:3956`, `mapNum = 46`, `quality = 0x0005`) now decompiles cleanly enough to read its top-level lane. Its `mapNum & 3` mode selects `slot_23` case `2`, and that case is not a hidden mutation body. It is currently just a scan over nearby decoded target-shape items with two filters:
|
|
|
|
- `Item.getQLo(item) == baseLink`
|
|
- `ref != item`
|
|
|
|
and no direct action on the matches.
|
|
|
|
That point is now supported by both the repaired high-level pseudocode and the lower semantic-layer output for `TRIGGER.slot_23`, `slot_24`, and `slot_26`: all three families still reduce their case-`2` lane to a bodyless match scan.
|
|
|
|
For the checked map-13 cluster, that scan target is now known more precisely:
|
|
|
|
- `fixed:3956` and its phase-0 sibling `fixed:3972` both decode to target shape `0x019B` (`shape:411`)
|
|
- the only nearby non-CMD object with low-byte link `5` is `fixed:3968`, a `shape:411` helper-geometry record at `49918, 50238, 48`
|
|
- the upper stacked helper `fixed:3976` decodes to target shape `0x04D0` (`shape:1232`), but there are no nearby `shape:1232` targets in this local cluster at all
|
|
|
|
So the local `QLo = 5` objects around the wall reduce to four items:
|
|
|
|
- `fixed:3972` phase-0 CMD helper
|
|
- `fixed:3956` phase-1 CMD helper
|
|
- `fixed:3976` upper CMD helper with no local target
|
|
- `fixed:3968` helper-geometry target
|
|
|
|
Current best interpretation:
|
|
|
|
- the local trigger source is known
|
|
- the relevant phase-1 helper is known
|
|
- the selected phase-1 helper now looks like an intentional scan-only selector aimed at helper target `fixed:3968`, not a direct wall mutator
|
|
- the upper stacked helper currently looks inactive for this cluster because it has no local `shape:1232` target to scan
|
|
- that makes the final wall mutation for `fixed:3964` more likely to live in a sibling helper, another usecode family that reacts to the scanned helper-geometry target, or a different edge/phase of the local trigger cluster, not inside this specific case-2 body
|
|
|
|
So map 13 should still be documented as a verified trigger cluster with an unresolved final mutation, but the strongest current read is no longer “empty loop probably means bad decompilation.” The stronger read is “the chosen phase-1 CMD helper appears to be a deliberate scan-only lane.”
|
|
|
|
#### Map 13: Current Best Gameplay Trigger Path
|
|
|
|
Even without the final helper-consumer body, the local egg geometry now narrows the likely player action down substantially.
|
|
|
|
The hidden family-4 trigger eggs beside the wall form an ordered west-to-east run by egg id:
|
|
|
|
- `fixed:3910` = egg id `1`
|
|
- `fixed:3945` = egg id `2`
|
|
- `fixed:3944` = egg id `3`
|
|
- `fixed:3959` = egg id `4`
|
|
- `fixed:3955` = egg id `5`
|
|
- `fixed:3970` = egg id `5`
|
|
|
|
The last two id-`5` eggs are narrow strips that sit directly in the northbound approach lane for wall `fixed:3964`.
|
|
|
|
- `fixed:3955` covers `x = 49540..49668`, `y = 50196..50836`
|
|
- `fixed:3970` covers `x = 49730..49858`, `y = 50278..50918`
|
|
- wall `fixed:3964` sits at `49790, 50206`, which lines up with the eastern strip and lies just beyond its north boundary
|
|
|
|
That means the most likely gameplay action is:
|
|
|
|
- approach the wall from the south side, not from the north
|
|
- enter the eastern id-`5` strip aligned with the wall face
|
|
- keep moving north toward the wall until the avatar leaves that strip across its north edge
|
|
|
|
That northbound exit is the exact movement that matches the proven `TRIGEGG::unhatch -> TRIGGER.slot_20(..., 0x81, ...) -> fixed:3956` chain.
|
|
|
|
So the current best practical trigger instruction is not just “walk through an egg.” It is “come up from the south, get into the narrow id-`5` lane in front of the wall, and cross out of that lane northward toward the wall.”
|
|
|
|
What is still not closed is whether the earlier id-`1..4` strips are mandatory setup for the wall or just sibling lanes in the same authored corridor. The current code evidence proves the final northbound id-`5` exit, but does not yet prove that ids `1..4` must be traversed first.
|
|
|
|
For gameplay testing, the screen-space direction should be stated more clearly:
|
|
|
|
- decreasing world `y` is not plain screen-up; in this isometric projection it reads as up-right on the screen
|
|
- increasing world `x` with roughly stable `y` reads as rightward on the screen
|
|
|
|
So the current best practical route on screen is:
|
|
|
|
- sweep left-to-right across the lower hidden trigger corridor for ids `1 -> 2 -> 3 -> 4`
|
|
- continue a little farther right into the first narrow id-`5` strip (`fixed:3955`)
|
|
- drift slightly down-right into the second narrow id-`5` strip (`fixed:3970`)
|
|
- then cut up-right out of that second strip toward the wall face at `fixed:3964`
|
|
|
|
This wording matches the actual screen anchors in the authored scene cache:
|
|
|
|
- id `4` strip anchor: `(15555, 11793)`
|
|
- first id `5` strip anchor: `(15645, 11796)`
|
|
- second id `5` strip anchor: `(15672, 11830)`
|
|
- wall face anchor: `(15741, 11781)`
|
|
|
|
That makes the final move leg visually specific: from the lower-left side of the wall, move up-right toward the wall after entering the second id-`5` strip.
|
|
|
|
#### Map 13: Practical Clarifications
|
|
|
|
##### Do the wall shooters matter?
|
|
|
|
Current best read: probably not for the wall opener itself.
|
|
|
|
The visible wall launcher near this setup is `fixed:3958` at `49246, 50942, 48`. Its low quality byte is `7`, while the checked movable-wall trigger lane uses local link ids `1..5` and the final wall-facing lane uses id `5`.
|
|
|
|
Nearby authored objects support that split:
|
|
|
|
- wall lane helpers: `fixed:3972`, `fixed:3956`, `fixed:3976` with local ids centered on the id-`5` corridor
|
|
- wall-facing helper target: `fixed:3968` with low byte `5`
|
|
- launcher object: `fixed:3958` with low byte `7`
|
|
|
|
No nearby id-`7` trigger egg or id-`7` `0x04B1` controller helper has been found in the same local corridor. So the current best interpretation is that the launcher is a sibling trap lane, not the wall-opening lane.
|
|
|
|
That means destroying the launcher should not be expected to disable the wall trigger path. This is still an evidence-backed inference rather than a fully closed runtime proof, but the current local link data points strongly that way.
|
|
|
|
##### Can the wall-trigger sequence be retried?
|
|
|
|
On the trigger side, yes.
|
|
|
|
The last two wall-facing id-`5` eggs are plain `TRIGEGG` subtype eggs (`quality low byte = 0`), not `ONCEEGG`. The live egg-hatcher runner sets the internal hatched flag when the avatar enters the trigger footprint and clears it again on exit, calling `hatch` and `unhatch` on those boundary crossings.
|
|
|
|
So the trigger geometry is inherently reusable:
|
|
|
|
- enter the strip -> `hatch`
|
|
- leave the strip -> `unhatch`
|
|
- walk back in and out again -> the same boundary logic can fire again
|
|
|
|
Also, the selected phase-1 helper `fixed:3956` uses `mapNum = 46`, which does not set the `0x10` low-priority self-clear bit in `TRIGGER.slot_20`. So the helper itself does not look one-shot from the currently recovered routing path.
|
|
|
|
The remaining caveat is only the still-unresolved final consumer after the scan lane. The trigger side is repeatable; the last unclosed world-change side might still have an authored one-shot elsewhere, but there is no current evidence for that in the id-`5` egg path itself.
|
|
|
|
##### How do the last two id-`5` eggs work if they are lines?
|
|
|
|
They are narrow trigger strips, not square areas.
|
|
|
|
For both wall-facing id-`5` eggs, `npcNum = 4`, which decodes to:
|
|
|
|
- `xRange = 0`
|
|
- `yRange = 4`
|
|
- `worldXRange = 0`
|
|
- `worldYRange = 256`
|
|
- `zWindow ~= +/- 48`
|
|
|
|
So in world-space they are centered on a single `x` line and extend along `y`. In the isometric screen projection that reads as a narrow diagonal strip running roughly down-left / up-right on screen.
|
|
|
|
The runner compares the avatar footprint against that trigger window, not just a single point. So a zero-width `xRange` does not mean the player has to hit one impossible exact pixel. It behaves like a thin line trigger that the avatar body can cross.
|
|
|
|
Practical movement consequence:
|
|
|
|
- if you move along the strip, you stay inside it and nothing new happens after the first entry
|
|
- if you cross into it, `hatch` fires
|
|
- if you cross back out of it, `unhatch` fires
|
|
|
|
For the wall case, the proven useful event is the `unhatch` on the second id-`5` strip. So the movement that matters is not "stand in the line" but "pass through the line and leave it on the wall-facing side."
|
|
|
|
##### Are ids `1..4` actually required?
|
|
|
|
Current best read: no, they do not look required.
|
|
|
|
This is now supported by the recovered trigger code and the authored local lane layout.
|
|
|
|
Locally, ids `1..4` are four copies of the same controller pattern:
|
|
|
|
- each egg is a plain `TRIGEGG` subtype egg
|
|
- each one routes into a pair of nearby `0x04B1` helpers with the same `mapNum` values as the id-`5` lane (`38` at `z=0`, `46` at `z=4`)
|
|
- each helper pair targets exactly one nearby `shape:411` helper-geometry object whose `QLo` matches the egg id
|
|
|
|
The code path for those helpers does not show any accumulating setup behavior.
|
|
|
|
- `TRIGEGG::hatch` and `unhatch` temporarily rewrite the egg item's local `QLo` to the egg id and call `TRIGGER.slot_20`
|
|
- `TRIGGER.slot_20` carries that id as the current `baseLink`
|
|
- the selected `slot_21 -> slot_23 case 2` path for ids `1..5` is a scan-only lane over nearby matching targets
|
|
- that lane returns `process_result = baseLink` unchanged
|
|
- none of the id-`1..4` helpers use the add/subtract cases that would roll the link id forward to the next lane
|
|
- none of the id-`1..4` helpers set the `mapNum & 16` self-clear bit either
|
|
|
|
So crossing ids `1..4` does not currently show any recovered mechanism that would arm id `5`, advance a shared link counter, or mutate a helper object.
|
|
|
|
The strongest current interpretation is:
|
|
|
|
- ids `1..4` are sibling scan lanes in the same authored corridor
|
|
- they are not the required setup for wall `fixed:3964`
|
|
- the only lane that still lines up with the wall is the paired id-`5` trigger near the wall face
|
|
|
|
So for practical gameplay testing, ids `1..4` can be dropped from the step list. If the wall opens at all through this local trigger cluster, the critical movement should be the paired id-`5` strip crossing beside the wall, not a full `1 -> 2 -> 3 -> 4 -> 5` sweep.
|
|
|
|
#### Map 13: Door-Family Closure And Remaining Gap
|
|
|
|
The wall face itself is now better closed than the opener.
|
|
|
|
- `fixed:3964` is shape `0x01AB`
|
|
- recovered `DOOR.slot_21` handles shape `0x01AB` by dispatching `DOOR2.slot_2C`
|
|
- `DOOR2.slot_2C` is the actual open animation for this wall family: it advances frames `1..11`, then changes the item to shape `0x0215`
|
|
- shape `0x0215` is a non-solid, non-drawn terrain state in the exported reference data, so this is a real hidden-wall-open transition rather than just a cosmetic frame swap
|
|
|
|
So the unresolved part is no longer what the wall does when opened. The unresolved part is still the caller that reaches `DOOR.slot_20 -> DOOR.slot_21 -> DOOR2.slot_2C` for this specific wall.
|
|
|
|
The most important newly ruled-out direct-caller families on map 13 are:
|
|
|
|
- no controller-family object near this wall room with local `QLo = 202`
|
|
- no family-4 egg on map 13 whose encoded egg id is `202`
|
|
- no nearby `SECRTEGG` or `DOOREGG` close enough to target this wall through the recovered secret-door scan radius
|
|
- no nearby watcher / secret-door-post family object in the wall room
|
|
|
|
That leaves the current state as:
|
|
|
|
- the local id-`5` trigger strip is proven to fire a real local trigger lane
|
|
- the wall face is proven to have a real hidden-door open path
|
|
- the exact authored bridge between those two facts is still not closed from the current recovered data
|
|
|
|
So the exact player steps for opening `fixed:3964` are still unresolved. The current local egg/CMD corridor remains evidence-bearing, but it can no longer be promoted to a verified opener sequence.
|
|
|
|
### Map 1
|
|
|
|
- wall: `fixed:6850`
|
|
- visible wall face near `53278, 61054, 96`
|
|
- nearby trigger egg: shape `0x0011`, `mapNum = 17`, near `53662, 61086, 104`
|
|
- nearby CMD helper: shape `0x04B1`, `quality = 0x0111`, near `53566, 61054, 96`
|
|
|
|
This case gives the strongest byte-level confirmation because the CMD helper `QLo` is `17`, which matches the egg id `mapNum = 17` exactly.
|
|
|
|
### Map 27
|
|
|
|
- wall: `fixed:6510`
|
|
- visible wall face near `20938, 23870, 3`
|
|
- nearby trigger egg: shape `0x0011`, `mapNum = 15`, near `19966, 23582, 0`
|
|
- nearby CMD helper: shape `0x04B1`, `quality low byte = 15`, near `19934, 23614, 0`
|
|
|
|
This is the loosest of the three examples, but it still fits the same egg-id -> CMD `QLo` neighborhood pattern and falls inside the wider movable-wall cluster distance used by the overlay.
|
|
|
|
## Viewer Rule
|
|
|
|
The current implementation does not try to solve every movable wall in the game. It only draws this verified cluster:
|
|
|
|
- source egg class: `TRIGEGG` or `ONCEEGG`
|
|
- match byte: egg `mapNum` == nearby CMD helper `QLo`
|
|
- CMD helper must be item-targeting and locally near the egg
|
|
- CMD helper must also be locally near one of the checked movable-wall face shapes
|
|
|
|
Current movable-wall target shape whitelist:
|
|
|
|
- `0x01AB`
|
|
- `0x0393`
|
|
- `0x03E8`
|
|
|
|
Those shapes came from the inspected examples above. If future investigations recover more walls using the same cluster, extend the whitelist only with checked placements.
|
|
|
|
## Why Not Reuse The Existing Door Rule
|
|
|
|
The older door overlay path expects a direct same-egg-id or same-`QLo` match against door-family targets.
|
|
|
|
These walls did not fit that assumption cleanly:
|
|
|
|
- the opener signal is carried by a nearby usecode egg id
|
|
- the local `0x04B1` helper is the observable routing object beside the wall
|
|
- at least one checked wall face does not expose the same `QLo` as the helper
|
|
|
|
That is why the viewer now treats this as a separate trigger-cluster overlay instead of quietly broadening the generic door whitelist. |