exit logic corrected from in-game debugging: the leveldoor only sets g101-g105, the llama's script ends the level (material 16, exit cell, near the floor); stale floor record after a position jump explains the hover exit skip in jungle day 2

This commit is contained in:
MineTec committed 2026-11-07 20:57:15 +01:00
1 parent 64259ea15b
commit 0568ae7f24
3 files changed
+82 -15

No files matched your search

Binary file not shown.

After

Width:  |  Height:  |  Size: 157 KiB

+45
View File
@@ -173,6 +173,11 @@ stairs, platforms register as shadow casters (`solids`). 1.0 = texture colour
## Exit (LevelDoor) – how it works
> **Corrected 2026-11-07 (in game, Jungle Day 2):** the listing below was the first reading. The
> LevelDoor only sets g101–g105 and checks global 0x21 *once*; the level is ended by the **Llama's
> script** (material 16 + exit cell + at most ~0.6 above the floor). See "Exit via stale floor
> material" further down and docs/reference/objects.md.
Strat bytecode (village, STPC 0x430332, 3 parameters, invisible, no model), decoded via the
VM `FUN_0054d180` (opcode < 0x45: table 0x5796bc with 16-bit operand, otherwise 0x578ff4+op·4):
```
@@ -199,6 +204,46 @@ loop: if g21 == 3 ; game state "running"
(zone teleport). t1l3m003: 2 of the 4 doors (cells 71,48/71,49) have no pad at all.
* Second path (strat code at 0x4252aa, player logic [likely]): floor material 16 and cell =
g104/g105 (set by the LevelDoor at start, Llama sets them to −1) → level change(g101..g103).
### Exit via stale floor material (hover + position jump, t1l4m002) – checked 2026-11-07
Speedrun video (position/hover hack): Kuzco hovers above a house-door stump, is moved to the exit and
the level ends. Reproduced in game (apptest, gdb through `winedbg --gdb`, position written by gdb):
* **Jungle Day chapter 2 = t1l4m002** (LNFO 95 coins / 2 secrets; tally "Dschungeltag Kapitel 2,
0/95, 0/2"). LevelDoor at 44.5/25.5 (cell 44,25), params (1,4,3); RubyIdolDoor in the same
cell. Cell 44,25 (tile 255) has material 16 **only in swap model 95** (pad x 44.67–45.0,
z 25.25–25.75, y 2.25); main model 94 has none → with the door closed the exit cannot fire.
House-door pads (material 16, main models) in cells 38,20 / 51,0 / 52,5 / 41,24 / 44,27 /
50,27 / 41,29 / 57,55 / 41,38 / 41,44 plus swap pads in 22,21 / 26,21 / 23,23 / 50,1 / 43,21 /
46,30 / 58,49 / 31,50; the zones pair them (e.g. 44,27 → 50.5/27.5, 50,27 → 44.5/27.5).
* **Floor test (FUN_004036d0):** only tiles of the player's own cell; per upward polygon the plane
height at (x,z) is compared with a probe point (y + 0.25, or y + (floor record +0x18)/2 with
+0xe8 flag 0x200000 as for the llama);
the **nearest floor below the probe wins, with no distance limit**. Material 17 is skipped for
the llama (+0xe8 = 0x24882a, no 0x8000000). If nothing is below: for the llama (+0xe8 & 0x40000)
material/height are **not** updated (stale) and x/z go back to the previous position.
In game: llama held at 44.9/**6.0**/27.5 (3.7 above the pad of the stump at 44,27) → floor
record h 2.30, **material 16**, tile 282 poly 15, every frame.
* **Order per tick (FUN_0054c4a0):** all strat scripts (VM FUN_0054d180) first, then the
collision pass (FUN_00403020 for every strat with +0xe8 & 0x8000). A position written after the
collision pass is seen by the scripts of the next tick with the **old floor record**.
In game: after hovering above the 44,27 pad, llama set to 44.5/2.3/25.5 right after its floor
test → next event endLevel `FUN_0054d620` (called from the VM, floor record still 16), before
any new floor test → tally (twice with screenshot, once traced). Control: same jump from normal
ground (material 0) → no exit; jump written just *before* the floor test → record becomes 0, no exit.
* **Who ends the level here: the Llama, not the LevelDoor.** LevelDoor bytecode: wait 5 ticks,
g101..g105 = params + cell, then **once** `if global 0x21 != 3 → end` (so "g21 == 3" above is a
one-time check, and global 0x21 is not the game state 0x5846e4), then the per-tick loop. In
t1l4m002 the LevelDoor was gone from the strat list (scan of 0x6d9e38) while g101..g105 =
1,4,3,44,25 and global 0x21 = 0. The Llama block at STPC 0x39ff4c–0x3a0064: if floorMaterial
== 16 and health > 0 and (y < floorHeight + 0.6 and global 0x21 != 2, or y < floorHeight + 0.025
and (g1 == 0 or global 0x23)): cell == (g104, g105) → level change(g101..g103), else fade-out +
`getDoorPos` (op 0x100, zone teleport = house door) + `forceCollision`. The 0.6 limit is why
hovering high above a house pad does not trigger the house teleport (bytecode; not separately
tested), while landing at floor height in the exit cell with the stale record does.
* Not explained: in two sessions with a moved player start (boot-to-level `start` 43.3/25.5) the
same jump did not end the level (Llama script ran with record 16 in cell 44,25, no endLevel).
* Images: `img/debug/exit-hover-trick.jpg` (top: video; bottom: our pool/door platform, tally).
* Parameters in the originals: (1, world, chapter+1) = next chapter; in the last chapter of a
world **(7,7,7)** = "world completed" → back to the selection map, unlock the next world.
* `FUN_0054d620`: remembers the current level (0x585008..14), sets the next (0x584eb4/b8/bc), shows the