22 KiB
Zelda 3 (Link to the Past) Dungeon System Specification
Purpose: This document provides a comprehensive specification for the ALTTP dungeon/underworld system based on analysis of:
- yaze - C++ dungeon editor implementation (partial)
- ZScream - C# reference implementation (complete)
- usdasm - Assembly disassembly of bank_01.asm (ground truth)
Goal: Close the gaps in yaze's dungeon editor to achieve correct room rendering.
Table of Contents
- Room Data Structure
- Room Header Format
- Object System
- Layer System
- Door System
- Sprites
- Items and Chests
- Graphics and Tilesets
- Implementation Gaps in yaze
- ROM Address Reference
1. Room Data Structure
1.1 Overview
A dungeon room in ALTTP consists of:
- Room Header (14 bytes) - Metadata, properties, warp destinations
- Object Data - Tile objects for walls, floors, decorations
- Sprite Data - Enemies, NPCs, interactive entities
- Item Data - Chest contents, pot items, key drops
- Door Data - Connections between rooms
1.2 Total Rooms
Total Rooms: 296 (0x00 - 0x127)
Room Size: 512x512 pixels (64x64 tiles at 8x8 pixels each)
1.3 Room Memory Layout
Room Object Data:
+0x00: Floor nibbles (floor2 << 4 | floor1)
+0x01: Layout byte ((value >> 2) & 0x07)
+0x02+: Object stream (3 bytes per object)
Layer Separators:
- 0xFF 0xFF: Marks transition to next layer
- 0xF0 0xFF: Begin door list
- Layer 3 reached or 0xFF 0xFF at boundary: End of data
2. Room Header Format
2.1 Header Structure (14 bytes)
| Offset | Bits | Field | Description |
|---|---|---|---|
| 0x00 | 7-5 | bg2 | Background 2 / Layer merge type (0-7) |
| 0x00 | 4-2 | collision | Collision type (0-4) |
| 0x00 | 0 | light | Light flag (if set, bg2 = 0x08 Dark Room) |
| 0x01 | 5-0 | palette | Palette ID (0-63, masked 0x3F) |
| 0x02 | 7-0 | blockset | Tileset/Blockset ID (0-23) |
| 0x03 | 7-0 | spriteset | Spriteset ID (0-64) |
| 0x04 | 7-0 | effect | Room effect (0-7) |
| 0x05 | 7-0 | tag1 | Tag 1 trigger (0-64) |
| 0x06 | 7-0 | tag2 | Tag 2 trigger (0-64) |
| 0x07 | 1-0 | holewarp_plane | Pit warp plane (0-3) |
| 0x07 | 3-2 | staircase_plane[0] | Staircase 1 plane (0-3) |
| 0x07 | 5-4 | staircase_plane[1] | Staircase 2 plane (0-3) |
| 0x07 | 7-6 | staircase_plane[2] | Staircase 3 plane (0-3) |
| 0x08 | 1-0 | staircase_plane[3] | Staircase 4 plane (0-3) |
| 0x09 | 7-0 | holewarp | Hole warp destination room (0-255) |
| 0x0A | 7-0 | staircase_rooms[0] | Staircase 1 destination room |
| 0x0B | 7-0 | staircase_rooms[1] | Staircase 2 destination room |
| 0x0C | 7-0 | staircase_rooms[2] | Staircase 3 destination room |
| 0x0D | 7-0 | staircase_rooms[3] | Staircase 4 destination room |
2.2 Header Address Calculation
// Step 1: Get master pointer
int header_pointer = ROM[kRoomHeaderPointer, 3]; // 24-bit
header_pointer = SNEStoPC(header_pointer);
// Step 2: Index into pointer table
int table_offset = header_pointer + (room_id * 2);
int address = (ROM[kRoomHeaderPointerBank] << 16) | ROM[table_offset, 2];
// Step 3: Convert to PC address
int header_location = SNEStoPC(address);
2.3 Layer Merge Types (bg2 field)
| ID | Name | Layer2OnTop | Layer2Translucent | Layer2Visible |
|---|---|---|---|---|
| 0x00 | Off | true | false | false |
| 0x01 | Parallax | true | false | false |
| 0x02 | Dark | true | true | true |
| 0x03 | On top | true | true | false |
| 0x04 | Translucent | true | true | true |
| 0x05 | Addition | true | true | true |
| 0x06 | Normal | true | false | false |
| 0x07 | Transparent | true | true | true |
| 0x08 | Dark room | true | true | true |
Note: When light flag is set, bg2 is overridden to 0x08 (Dark room).
2.4 Collision Types
| ID | Name |
|---|---|
| 0 | One_Collision |
| 1 | Both |
| 2 | Both_With_Scroll |
| 3 | Moving_Floor_Collision |
| 4 | Moving_Water_Collision |
2.5 Room Effects
| ID | Name | Description |
|---|---|---|
| 0 | Nothing | No effect |
| 1 | One | Effect 1 |
| 2 | Moving_Floor | Animated floor tiles |
| 3 | Moving_Water | Animated water tiles |
| 4 | Four | Effect 4 |
| 5 | Red_Flashes | Red screen flashes |
| 6 | Torch_Show_Floor | Floor revealed by torches |
| 7 | Ganon_Room | Final boss room effect |
2.6 Room Tags (65 types)
Key tags include:
NW_Kill_Enemy_to_Open(1) - Kill all enemies in NW quadrantClear_Quadrant_to_Open(various) - Quadrant-based triggersPush_Block_to_Open(various) - Block puzzle triggersWater_Gate- Water level controlAgahnim_Room- Boss room setupHoles_0throughHoles_2- Pit configurations
3. Object System
3.1 Object Subtypes
ALTTP uses three object subtypes with different encoding and capabilities:
| Subtype | ID Range | Count | Scalable | Description |
|---|---|---|---|---|
| 1 | 0x00-0xF7 | 248 | Yes | Standard room objects |
| 2 | 0x100-0x13F | 64 | No | Fixed-size objects |
| 3 | 0xF80-0xFFF | 128 | No | Special/complex objects |
3.2 Object Encoding (3 bytes)
Subtype 1 (b3 < 0xF8):
Byte 1: xxxxxxss (x = X position bits 7-2, s = size X bits 1-0)
Byte 2: yyyyyyss (y = Y position bits 7-2, s = size Y bits 1-0)
Byte 3: iiiiiiii (object ID 0x00-0xF7)
Decoding:
posX = (b1 & 0xFC) >> 2
posY = (b2 & 0xFC) >> 2
sizeX = b1 & 0x03
sizeY = b2 & 0x03
sizeXY = (sizeX << 2) + sizeY
object_id = b3
Subtype 2 (b1 >= 0xFC):
Byte 1: 111111xx (x = X position bits 5-4)
Byte 2: xxxxyyyy (x = X position bits 3-0, y = Y position bits 5-2)
Byte 3: yyiiiiii (y = Y position bits 1-0, i = object ID low 6 bits)
Decoding:
posX = ((b2 & 0xF0) >> 4) + ((b1 & 0x03) << 4)
posY = ((b2 & 0x0F) << 2) + ((b3 & 0xC0) >> 6)
object_id = (b3 & 0x3F) | 0x100
Subtype 3 (b3 >= 0xF8):
Byte 1: xxxxxxii (x = X position bits 7-2, i = size/ID bits 1-0)
Byte 2: yyyyyyii (y = Y position bits 7-2, i = size/ID bits 3-2)
Byte 3: 11111iii (i = ID bits 6-4, marker 0xF8-0xFF)
Decoding:
posX = (b1 & 0xFC) >> 2
posY = (b2 & 0xFC) >> 2
object_id = ((b3 << 4) | 0x80 + (((b2 & 0x03) << 2) + (b1 & 0x03))) - 0xD80
// Results in 0x200-0x27E range
3.3 Object Data Tables (bank_01.asm)
Address | Size | Content
---------------|-------|------------------------------------------
$018000-$0181FE| 512B | Subtype 1 data offsets (256 entries x 2)
$018200-$0183EE| 494B | Subtype 1 routine pointers (256 entries)
$0183F0-$01846E| 128B | Subtype 2 data offsets (64 entries x 2)
$018470-$0184EE| 128B | Subtype 2 routine pointers (64 entries)
$0184F0-$0185EE| 256B | Subtype 3 data offsets (128 entries x 2)
$0185F0-$0186EE| 256B | Subtype 3 routine pointers (128 entries)
3.4 Drawing Routines
There are 24+ unique drawing patterns used by objects:
| Routine | Pattern | Multiplier | Objects Using |
|---|---|---|---|
| Rightwards2x2_1to15or32 | 2x2 horizontal | s*2 | Walls, floors |
| Rightwards2x4_1to15or26 | 2x4 horizontal | s*2 | Taller walls |
| Downwards2x2_1to15or32 | 2x2 vertical | s*2 | Vertical features |
| Downwards4x2_1to15or26 | 4x2 vertical | s*2 | Wide columns |
| DiagonalAcute_1to16 | Diagonal / | +1,+1 | Stairs up-right |
| DiagonalGrave_1to16 | Diagonal \ | +1,-1 | Stairs down-right |
| 4x4 | Fixed 4x4 | none | Type 2 objects |
| 3x4 | Fixed 3x4 | none | Doors, decorations |
| Single2x2 | Single 2x2 | none | Small decorations |
| Single2x3Pillar | Single 2x3 | none | Pillars |
3.5 Size Handling
// Default size when size byte is 0
if (size == 0) {
size = 32; // For most subtype 1 objects
}
// Some objects use size + 1 for iteration count
for (int s = 0; s < size + 1; s++) { ... }
// Size masking for some routines
int effective_size = size & 0x0F; // Use lower 4 bits only
3.6 Layer Assignment
Objects are assigned to layers via the object stream:
- Objects before first
0xFF 0xFFmarker: Layer 0 (BG1) - Objects after first
0xFF 0xFFmarker: Layer 1 (BG2) - Objects after second
0xFF 0xFFmarker: Layer 2 (BG3/Sprites)
Some objects have allBgs = true flag and draw to both BG1 and BG2.
3.7 Common Object IDs
Subtype 1 (Scalable):
| ID | Name |
|---|---|
| 0x00-0x07 | Wall segments (N/S/E/W) |
| 0x08-0x0B | Pit edges |
| 0x0C-0x20 | Diagonal walls |
| 0x21-0x30 | Rails and supports |
| 0x31-0x40 | Carpets and trim |
| 0xD0-0xD7 | Floor types (8 patterns) |
| 0xE0-0xE7 | Ceiling types |
| 0xF0-0xF3 | Conveyor belts (4 directions) |
Subtype 2 (Fixed):
| ID | Name |
|---|---|
| 0x100-0x107 | Corners (concave/convex) |
| 0x108-0x10F | Braziers and statues |
| 0x110-0x117 | Star tiles |
| 0x118-0x11F | Torches and furniture |
| 0x120-0x127 | Stairs (inter/intra room) |
| 0x128-0x12F | Blocks and platforms |
Subtype 3 (Special):
| ID | Name |
|---|---|
| 0x200-0x207 | Waterfall faces |
| 0x208-0x20F | Somaria paths |
| 0x210-0x217 | Item piles (rupees) |
| 0x218-0x21F | Chests (various) |
| 0x220-0x227 | Pipes and conveyors |
| 0x228-0x22F | Pegs and switches |
4. Layer System
4.1 Layer Architecture
ALTTP uses a 3-layer system matching SNES hardware:
| Layer | SNES Name | Memory | Purpose |
|---|---|---|---|
| BG1 | Background 1 | $7E2000 | Main room layout |
| BG2 | Background 2 | $7E4000 | Overlay layer |
| BG3 | Background 3 | Sprites | Sprites/effects |
4.2 Tilemap Memory Layout
Upper Layer (BG1/BG2): $7E2000-$7E27FF (2KB per layer)
Lower Layer (BG3): $7E4000-$7E47FF (2KB per layer)
Grid Structure: 4 columns x 3 rows of 32x32 blocks
Offset: $100 bytes per block horizontally
$1C0 bytes per block vertically
Each tilemap entry: 16-bit word
Bits [9:0]: Tile index (0-1023)
Bit [10]: Priority bit
Bits [13:11]: Palette select (0-7)
Bit [14]: Horizontal flip
Bit [15]: Vertical flip
4.3 Layer Merge Behavior
The bg2 field controls how layers are composited:
switch (bg2) {
case 0x00: // Off - BG2 hidden
case 0x01: // Parallax - BG2 scrolls differently
case 0x02: // Dark - Dark room effect
case 0x03: // On top - BG2 overlays BG1
case 0x04: // Translucent - BG2 semi-transparent
case 0x05: // Addition - Additive blending
case 0x06: // Normal - Standard display
case 0x07: // Transparent - BG2 transparent
case 0x08: // Dark room - Special dark room
}
4.4 Floor Rendering
Floor tiles are specified by the first byte of room object data:
uint8_t floor_byte = ROM[object_data_ptr];
uint8_t floor1 = floor_byte & 0x0F; // Low nibble
uint8_t floor2 = floor_byte >> 4; // High nibble
Floor patterns (0-15) reference tile graphics at tile_address_floor.
5. Door System
5.1 Door Data Format
Doors are encoded as 2-byte entries after the 0xF0 0xFF marker:
Byte 1: Door position (0-255)
Byte 2: Door type and direction
Bits [3:0]: Direction (0=North, 1=South, 2=West, 3=East)
Bits [7:4]: Door type/subtype
5.2 Door Types
| Type | Name | Description |
|---|---|---|
| 0x00 | Regular | Standard door |
| 0x02 | Regular2 | Standard door variant |
| 0x06 | EntranceDoor | Entrance from overworld |
| 0x08 | WaterfallTunnel | Behind waterfall |
| 0x0A | EntranceLarge | Large entrance |
| 0x0C | EntranceLarge2 | Large entrance variant |
| 0x0E | EntranceCave | Cave entrance |
| 0x12 | ExitToOW | Exit to overworld |
| 0x14 | ThroneRoom | Throne room door |
| 0x16 | PlayerBgChange | Layer toggle door |
| 0x18 | ShuttersTwoWay | Two-way shutter |
| 0x1A | InvisibleDoor | Hidden door |
| 0x1C | SmallKeyDoor | Requires small key |
| 0x20-0x26 | StairMaskLocked | Locked stair doors |
| 0x28 | BreakableWall | Bomb-able wall |
| 0x30 | LgExplosion | Large explosion door |
| 0x32 | Slashable | Sword-cuttable |
| 0x40 | RegularDoor33 | Regular variant |
| 0x44 | Shutter | One-way shutter |
| 0x46 | WarpRoomDoor | Warp tile door |
| 0x48-0x4A | ShutterTrap | Trap shutter doors |
5.3 Door Graphics Addresses
Direction | Graphics Pointer
----------|------------------
North | $014D9E (kDoorGfxUp)
South | $014E06 (kDoorGfxDown)
West | $014E66 (kDoorGfxLeft)
East | $014EC6 (kDoorGfxRight)
5.4 Door Rendering Dimensions
| Direction | Width | Height |
|---|---|---|
| North/South | 4 tiles | 3 tiles |
| East/West | 3 tiles | 4 tiles |
6. Sprites
6.1 Sprite Data Structure
struct Sprite {
uint8_t id; // Sprite type (0x00-0xF3)
uint8_t x; // X position (0-63)
uint8_t y; // Y position (0-63)
uint8_t subtype; // Subtype flags
uint8_t layer; // Layer (0-2)
uint8_t key_drop; // Key drop (0=none, 1=small, 2=big)
bool overlord; // Is overlord sprite
};
6.2 Sprite Encoding
Sprites are stored as 3-byte entries:
Byte 1: Y position (bits 7-1), Layer flag (bit 0)
Byte 2: X position (bits 7-1), Subtype high (bit 0)
Byte 3: Sprite ID (0x00-0xFF)
Special handling:
- Overlord check: (subtype & 0x07) == 0x07
- Key drop at sprite ID 0xE4:
- Position (0x00, 0x1E) = small key drop
- Position (0x00, 0x1D) = big key drop
6.3 Overlord Sprites
When (subtype & 7) == 7, the sprite is an "overlord" with special behavior.
Overlord IDs 0x01-0x1A have separate name tables.
6.4 Key Drop Mechanics
// Detection during sprite loading
if (sprite_id == 0xE4) {
if (x == 0x00 && y == 0x1E) {
key_drop = 1; // Small key
} else if (x == 0x00 && y == 0x1D) {
key_drop = 2; // Big key
}
}
7. Items and Chests
7.1 Chest Data
Chests are stored separately from room objects:
struct ChestData {
uint16_t room_id; // Room containing chest
uint8_t x; // X position
uint8_t y; // Y position
uint8_t item_id; // Item contained
bool is_big; // Big chest flag
};
7.2 Item Types (Pot Items)
| ID | Item | ID | Item |
|---|---|---|---|
| 0 | Nothing | 14 | Small magic |
| 1 | Rupee (green) | 15 | Big magic |
| 2 | Rock crab | 16 | Bomb refill |
| 3 | Bee | 17 | Arrow refill |
| 4 | Random | 18 | Fairy |
| 5 | Bomb | 19 | Key |
| 6 | Heart | 20 | Fairy*8 |
| 7 | Blue rupee | 21-22 | Various |
| 8 | Key*8 | 23 | Hole |
| 9 | Arrow | 24 | Warp |
| 10 | 1 bomb | 25 | Staircase |
| 11 | Heart | 26 | Bombable |
| 12 | Rupee (blue) | 27 | Switch |
| 13 | Heart variant |
7.3 Item Encoding
Items with ID >= 0x80 use special encoding:
if (id & 0x80) {
int actual_id = ((id - 0x80) / 2) + 23;
}
7.4 Item ROM Addresses
Chest Pointers: $01EBF6 (kChestsLengthPointer)
Chest Data: $01EBFB (kChestsDataPointer1)
Room Items: $01DB69 (kRoomItemsPointers)
8. Graphics and Tilesets
8.1 Graphics Organization
Sheet Count: 223 sheets
Uncompressed Size: 2048 bytes (0x800) per sheet
3BPP Size: 1536 bytes (0x600) per sheet
8.2 Key Graphics Addresses
Tile Address: $009B52 (kTileAddress)
Tile Address Floor: $009B5A (kTileAddressFloor)
Subtype 1 Tiles: $018000 (kRoomObjectSubtype1)
Subtype 2 Tiles: $0183F0 (kRoomObjectSubtype2)
Subtype 3 Tiles: $0184F0 (kRoomObjectSubtype3)
GFX Groups: $006237 (kGfxGroupsPointer)
8.3 Palette Configuration
Palettes Per Group: 16
Colors Per Palette: 16
Total Palette Size: 256 colors
Half Palette Size: 8 colors
Dungeon Main BG: $0DEC4B (kDungeonsMainBgPalettePointers)
Dungeon Palettes: $0DD734 (kDungeonsPalettes)
8.4 Tile Info Format
struct TileInfo {
uint16_t id; // Tile index (10 bits)
uint8_t palette; // Palette (3 bits)
bool h_flip; // Horizontal mirror
bool v_flip; // Vertical mirror
bool priority; // Priority bit
};
// Decode from 16-bit word
TileInfo decode(uint16_t word) {
TileInfo t;
t.id = word & 0x03FF;
t.priority = (word >> 10) & 1;
t.palette = (word >> 11) & 0x07;
t.h_flip = (word >> 14) & 1;
t.v_flip = (word >> 15) & 1;
return t;
}
9. Implementation Gaps in yaze
9.1 Critical Gaps (Must Fix for Correct Rendering)
| Gap | Severity | Description | ZScream Reference |
|---|---|---|---|
| Type 3 Objects | Critical | Stub implementation, simplified drawing | Subtype3_Draw.cs |
| Door Rendering | Critical | LoadDoors() is stub, no type handling | Doors_Draw.cs |
| all_bgs Flag Ignored | Critical | Uses hardcoded routine IDs (3,9,17,18) instead | Room_Object.cs allBgs |
| Floor Rendering | High | Floor values loaded but not rendered | Room.cs floor1/floor2 |
| Type 2 Complex Layouts | High | Missing column, bed, spiral stair handling | Subtype2_Multiple.cs |
| Layer Merge Effects | High | Flags exist but not applied during render | LayerMergeType.cs |
9.2 Missing Systems
| System | Status in yaze | ZScream Implementation |
|---|---|---|
| Pot Items | Not implemented | Items_Draw.cs (28 types) |
| Key Drop Visualization | Detection only, no draw | Sprite.cs DrawKey() |
| Door Graphics | Generic object render | Doors_Draw.cs (40+ types) |
| Item-Sprite Linking | Not implemented | PotItem.cs |
| Selection State | Not tracked | Room_Object.cs selected |
| Unique Sprite IDs | Not tracked | ROM.uniqueSpriteID |
9.3 Architectural Differences
| Aspect | yaze Approach | ZScream Approach | Recommendation |
|---|---|---|---|
| Object Classes | Single RoomObject class | Per-ID classes (object_00, etc.) | Keep unified, add type handlers |
| Draw Routines | 38 shared lambdas | 256+ override methods | Keep yaze approach |
| Tile Loading | On-demand parser | Pre-loaded static arrays | Keep yaze approach |
| Layer Selection | Binary choice (BG1/BG2) | Enum with BG3 | Add BG3 support |
9.4 Fix Priority List
Phase 1: Core Rendering
- Fix
all_bgs_flag usage instead of hardcoded routine IDs - Implement proper floor rendering from floor1/floor2 values
- Complete Type 3 object drawing (Somaria paths, etc.)
- Add missing Type 2 object patterns
Phase 2: Doors 5. Implement door type classification system 6. Add special door graphics (caves, holes, hidden walls) 7. Mirror effect for bidirectional doors 8. Layer-specific door rendering
Phase 3: Items & Sprites 9. Implement PotItem system (28 types) 10. Add key drop visualization 11. Link items to sprites for drops 12. Selection state tracking
Phase 4: Polish 13. Layer merge effect application 14. BG3 layer support 15. Complete bounds checking 16. Dimension calculation for complex objects
10. ROM Address Reference
10.1 Room Data
constexpr int kRoomObjectLayoutPointer = 0x882D;
constexpr int kRoomObjectPointer = 0x874C;
constexpr int kRoomHeaderPointer = 0xB5DD;
constexpr int kRoomHeaderPointerBank = 0xB5E7;
constexpr int kNumberOfRooms = 296;
10.2 Graphics
constexpr int kTileAddress = 0x001B52;
constexpr int kTileAddressFloor = 0x001B5A;
constexpr int kRoomObjectSubtype1 = 0x8000;
constexpr int kRoomObjectSubtype2 = 0x83F0;
constexpr int kRoomObjectSubtype3 = 0x84F0;
constexpr int kGfxGroupsPointer = 0x6237;
10.3 Palettes
constexpr int kDungeonsMainBgPalettePointers = 0xDEC4B;
constexpr int kDungeonsPalettes = 0xDD734;
10.4 Sprites & Items
constexpr int kRoomItemsPointers = 0xDB69;
constexpr int kRoomsSpritePointer = 0x4C298;
constexpr int kSpriteBlocksetPointer = 0x5B57;
constexpr int kSpritesData = 0x4D8B0;
constexpr int kDungeonSpritePointers = 0x090000;
10.5 Blocks & Features
constexpr int kBlocksLength = 0x8896;
constexpr int kBlocksPointer1 = 0x15AFA;
constexpr int kBlocksPointer2 = 0x15B01;
constexpr int kBlocksPointer3 = 0x15B08;
constexpr int kBlocksPointer4 = 0x15B0F;
10.6 Chests & Torches
constexpr int kChestsLengthPointer = 0xEBF6;
constexpr int kChestsDataPointer1 = 0xEBFB;
constexpr int kTorchData = 0x2736A;
constexpr int kTorchesLengthPointer = 0x88C1;
10.7 Pits & Doors
constexpr int kPitPointer = 0x394AB;
constexpr int kPitCount = 0x394A6;
constexpr int kDoorPointers = 0xF83C0;
constexpr int kDoorGfxUp = 0x4D9E;
constexpr int kDoorGfxDown = 0x4E06;
constexpr int kDoorGfxLeft = 0x4E66;
constexpr int kDoorGfxRight = 0x4EC6;
Appendix A: Object ID Quick Reference
Subtype 1 (0x00-0xF7) - Scalable
| Range | Category |
|---|---|
| 0x00-0x07 | Wall segments |
| 0x08-0x0B | Pit edges |
| 0x0C-0x20 | Diagonal walls (allBgs=true) |
| 0x21-0x30 | Rails and supports |
| 0x31-0x40 | Carpets and trim |
| 0x41-0x50 | Decorations |
| 0xD0-0xD7 | Floor patterns |
| 0xE0-0xE7 | Ceiling patterns |
| 0xF0-0xF3 | Conveyor belts |
Subtype 2 (0x100-0x13F) - Fixed Size
| Range | Category |
|---|---|
| 0x100-0x107 | Corners |
| 0x108-0x10F | Braziers/statues |
| 0x110-0x117 | Star tiles |
| 0x118-0x11F | Torches/furniture |
| 0x120-0x127 | Stairs |
| 0x128-0x12F | Blocks/platforms |
| 0x130-0x13F | Misc decorations |
Subtype 3 (0x200-0x27E) - Special
| Range | Category |
|---|---|
| 0x200-0x207 | Waterfall faces |
| 0x208-0x20F | Somaria paths |
| 0x210-0x217 | Item piles |
| 0x218-0x21F | Chests |
| 0x220-0x227 | Pipes/conveyors |
| 0x228-0x22F | Pegs/switches |
| 0x230-0x23F | Boss objects |
| 0x240-0x27E | Misc special |
Appendix B: Drawing Routine Reference
| ID | Routine Name | Pattern | Objects |
|---|---|---|---|
| 0 | Rightwards2x2_1to15or32 | 2x2 horizontal | 0x00, walls |
| 1 | Rightwards2x4_1to15or26 | 2x4 horizontal | 0x01-0x02 |
| 2 | Downwards2x2_1to15or32 | 2x2 vertical | vertical walls |
| 3 | Rightwards2x2_BothBG | 2x2 both layers | 0x03-0x04 |
| 4 | Rightwards2x4spaced4_1to16 | 2x4 spaced | 0x05-0x06 |
| 5 | DiagonalAcute_1to16 | Diagonal / | stairs |
| 6 | DiagonalGrave_1to16 | Diagonal \ | stairs |
| 7 | Downwards4x2_1to15or26 | 4x2 vertical | wide columns |
| 8 | 4x4 | Fixed 4x4 | Type 2 objects |
| 9 | Downwards4x2_BothBG | 4x2 both layers | special walls |
| 17 | DiagonalAcute_BothBG | Diagonal both | diagonal walls |
| 18 | DiagonalGrave_BothBG | Diagonal both | diagonal walls |
Document generated from analysis of yaze, ZScream, and usdasm codebases. Last updated: 2025-12-01