Files

9.5 KiB
Raw Permalink Blame History

Objects, waypoints, zones and lights

Everything that is not static geometry lives in the second half of the MAP chunk: object instances ("strats"), their parameters, waypoint chains and environment zones. Lights are in their own chunk, LGHT. Full byte layouts: notes/objects.md.

Strats: objects are programs

An object – coin, enemy, door, camera, the player – is an instance of a strat: a script in the level's STPC code. A MAP record says where and which code; the code does the rest. There is no type id: the type is the code's byte offset in STPC. Type names come from the code itself (a debugName "Coin" instruction at the entry point). How the code works: Strats.

About 300 types are placed in the original levels, about 200 more are only spawned by other strats (splinters, effects, heads). The full list of which type appears in which level, with instance counts, is notes/strat_types_table.md (tools/strat_table.py).

The MAP object blocks

After the geometry blocks (Geometry):

Block Format
parameter pool u32 n, n × u32 – all object parameters of the level, referenced by index
environment zones u32 n, n × 90 bytes (below)
waypoints u32 n, n × 34 bytes {u32 next, u32, u16 rx, ry, rz, s32 x, y, z, u32, u32}; next ≠ 0 = the following entry belongs to the same chain
strats u32 nStrats, u32 poolExtra, nStrats × 58-byte records
optional tail paths (WFPC 0x200000, unused by the CD levels), a buffer size (WFPC 0x10), a u16

Strat record (58 bytes, certain unless noted)

Offset Field
0 rotation x, y, z (u16 each, 4096 = 360°; x/z almost always 0)
6 position x, y, z (s32, 20.12 fixed point, game space)
18 code offset in STPC = the type
22 / 26 parameter count / index into the parameter pool (−1 if none)
30 number of strat variables (fixed per type)
34 16-byte slots for event handlers (fixed per type, likely)
38 type flags: collision and physics setup (fixed per type)
42 extra memory words (collision bones; fixed per type)
46 first waypoint index or −1
54 flags; bit 1 = not created at level start

poolExtra is the number of strat slots beyond 30: the engine allocates poolExtra + 30 slots, which must cover all placed objects plus everything spawned at run time.

The type fields (variables, slots, flags, extra) come from the compiler and must be copied from an original instance of the same type; a type that uses collision but has type flags 0 crashes the game. Builders and the editor do this automatically.

Parameters

The n parameters of an instance are pushed onto the new strat's stack and become its variables v0 … v(n−1). Values are 20.12 fixed point by convention (0x1000 = 1.0), booleans 0 / 0x1000, counts and world/chapter numbers n << 12. The editor knows the meaning of the parameters of many types (schemas in editor/tools/objects/Schemas.java, findings in notes/editor-object-schemas.md); the others are shown raw with the values used in the original levels.

Waypoints

A waypoint chain is a list of positions used for patrol paths, moving platforms, camera paths – and for some types (guards, box walkers) as a pair of boxes the object must stand in, or the game removes it ("removing strat"). Guards also wait for an event bit (global variable 95) that another object sets (notes/editor-object-schemas.md).

The player's waypoint chain is the start camera: the camera takes the first node within 2.5 cells of the llama. A good start has one node about 2 cells behind the llama and 0.5 above it, and nothing solid right behind the llama (the camera moves aside).

Special objects

Role Type Notes
player start Llama exactly one per level (RollerCoaster, KuscoAndPachaTogetherOnATree, LlamaChase in special levels)
checkpoint CheckPointPost (spawns CheckPointHead), CheckPointBox the respawn point after a fall
exit LevelDoor invisible trigger, see below; variants VillageEndDoor, EndGameDoor
cameras CameraSide, CutSceneCameraDirectional, CutSceneTrigger camera zones and cut scenes
always present CheatTeleport, Wompy, CutSceneTrigger

The exit (LevelDoor)

An exit is two parts working together (decompiled strat code; the details below were checked in game in Jungle Day 2 with a debugger, the basic rule also in Village 1):

  • The LevelDoor object (no model) writes its three parameters – the next level (tribe, world, chapter) – to globals g101–g103 and its grid cell to g104/g105. It does not end the level itself in the cases we tested (see the details below).
  • Kuzco's own script ends the level when all of these hold:
floor material under Kuzco == 16              ; the remembered floor (see "floor test" below)
and floor(x), floor(z) == the cell in g104/g105   ; the exit's grid cell, any height
and Kuzco is at most ~0.6 above that floor's height
-> level change to g101..g103 (tally screen)

On a material-16 floor outside the exit cell the same check is a house door: fade-out and the teleport of the environment zone of that cell.

So a normal exit needs a floor with collision material 16 in the exit's grid cell. In several original levels that floor only exists after a tile swap opens the door (Village 1 and Jungle Day 2: the RubyIdolDoor swaps the tile to a model that has the material-16 pad; checked in game in Village 1). The parameters of the originals are (1, world, chapter + 1); (7, 7, 7) in the last chapter of a world means "world finished" – in TestLevel that crashes, so custom levels use (1, 9, chapter). The tally shows coins x / LNFO total and secrets and unlocks the next chapter. The arena sets g101–g105 itself to make its own exit (Arena).

Details checked in game (Jungle Day 2, t1l4m002, 2026-11-07):

  • The LevelDoor stores its parameters and cell in g101–g105, then checks global 0x21 once (after 5 ticks); if it is not 3 the door removes itself. In Jungle Day 2 it was gone after the start, so the Llama's check is what ends the level. That check needs floor material 16, the door's cell, and the llama no more than 0.6 above the recorded floor height. Off the exit cell the same material-16 check is the house door (fade-out and zone teleport).
  • The floor test only looks at tiles in the player's cell and takes the nearest upward floor below the player, at any distance. Material 17 is ignored for the llama. A llama hovering 3.7 units above a house-door pad records material 16.
  • Each tick runs all strat scripts first and then the floor tests. A position change made after the floor tests is seen by the next tick's scripts with the old floor record. So hovering above any house-door pad and then moving the llama straight to floor height in the exit cell ends the level, even though the exit cell has no material 16 yet (it appears only in the swap model when the RubyIdolDoor opens). Moving there from normal ground does nothing.

Environment zones (90 bytes, certain for the fields below)

A zone sets fog, colours, music and sky, and optionally teleports the player.

Field Meaning
cell x, y, z the trigger cell
target x, y, z, angle teleport target and facing
flags (+0x20) flag 8 = start zone (exactly one per level: the level begins with its settings); flag 4 = do not move the player
sky model STPC offset of a sky model (0 = none)
fog mode 0 none, 1 darkness with a light around the player, 2 table fog, 3 vertex fog
fog start / end two pairs (detail Minimum and Maximum); fog end = far clip = draw distance
colours ambient colour for object lighting, fog/backdrop colour
music id 1–39 (see Music), 0 stops the music

Teleports are triggered from strat code (opcode 0x100 looks up the zone of the calling object's cell). In the original levels the trigger cells hold exit floors (material 16) or door objects – this is how the village house doors work. The editor edits zones in the Environment panel (manual chapter 12).

Lights

LGHT: u32 n, then per light a type, a colour (×2/255) and direction or position (game space). Lights only light object models (ambient + all directional lights + the nearest point lights, at most 6). Tiles use baked vertex colours, so changing a light does not change the ground – bake the vertex colours again. Point lights are full up to radius a and fade to 0 at b; one byte makes them flicker.

Tools

Task Tool
list types, instances, parameters of a level tools/strats.py level.wad [--all], tools/map_dump.py --strats --tiles --lights
type × level table tools/strat_table.py
place objects from a script tools/levelbuild.py L.strat(...), Java LevelBuilder
place, edit, check objects visually the level editor (manual chapter 9, 10, 11)