task 5 report - xopherdeep/do-it-for-the-xp GitHub Wiki
Status: DONE_WITH_CONCERNS (all eight dungeons convert, 81/81 spec assertions pass, two overrides; a few brief rules could not be followed as written because the data does not support them, each listed under Concerns).
- Branch:
worktree-agent-a0c36dc212c21b2b0(isolated worktree/home/xopher/www/x/do-it-for-the-xp/.claude/worktrees/agent-a0c36dc212c21b2b0, offorigin/master61d7b718) - Commit:
2db3e8197545a85a3b185e62e0bfef3335678b1f—feat(tools): pinned LTTP sources and a converter that writes one JSON per dungeon - Run it:
python3 tools/temples/classic/convert.py [id ...](add--debugto print each area's evidence and every cell); check:chemx test tests/unit/ClassicDungeonJson.spec.ts
| Path (under the worktree) | What |
|---|---|
tools/temples/classic/classicDungeon.ts |
the schema, verbatim from the brief |
tools/temples/classic/convert.py |
the converter: stdlib only, deterministic (two runs give identical bytes), exits 1 naming anything it cannot place |
tools/temples/classic/dungeons/<id>.json |
the eight dungeons (storm, earth, light, water, shadow, ice, fire, moon) |
tools/temples/classic/overrides/shadow-temple.json, overrides/ice-temple.json
|
the only two overrides (below) |
tools/temples/classic/sources/ |
pinned copies + three MIT licence texts; SOURCES.md lists URLs, commit ids and SHA-256 prefixes |
tools/temples/classic/sources/vanilla/<Dungeon>.php |
sporchia V30 region classes, read for setVanilla() only |
tests/unit/ClassicDungeonJson.spec.ts |
the spec: every JSON under dungeons/ is checked |
-
aerinon/ALttPDoorRandomizer@6f390947159b6d2162b52a60aebfd969ccf9b922:Doors.py,Regions.py,source/dungeon/EnemyList.py(the three the brief named) plusDoorShuffle.py,RoomData.py,PotShuffle.py. The extra three are not optional:Doors.pyalone does not say which stairs, ladders, pits and warps connect (that isDoorShuffle.py'sspiral_staircases,ladders,falldown_pits,dungeon_warps,interior_doors,open_edges,default_door_connections,logical_connections); bomb/dash/trap/key door kinds live inRoomData.pybehind each door's.pos(n); and onlyPotShuffle.pyplaces pot keys and enemy key drops. -
TheVGLC/TheVGLC@0e86a8f31f20ecad4eaa5741ff061af88767f7fb:The Legend of Zelda/Graph Processed/LoZ_1.dot(for Task 6), licenceLicense.md. -
sporchia/alttp_vt_randomizer@8c043a4089e0a058ca8d7eafebea93f76b129ae6("V30", 2018-10-01) for vanilla chest contents, per the lead's ruling. Licence verified MIT (sporchia 2016) before use. Master and every commit after V30 have droppedsetVanilla()from the region classes, so V30 is the newest usable revision.
RED (spec written first, no JSON on disk):
$ chemx test tests/unit/ClassicDungeonJson.spec.ts
✖ Test Failures (1 failed out of 1)
✖ classic dungeon JSON › has one JSON per LTTP temple
Expected: ArrayContaining ["storm-temple", "earth-temple", "light-temple", "water-temple", "shadow-temple", "ice-temple", "fire-temple", "moon-temple"]
Received: []
GREEN (after the converter wrote all eight):
$ python3 tools/temples/classic/convert.py # exit 0
$ chemx test tests/unit/ClassicDungeonJson.spec.ts
✔ All tests passed (81 passed in 7831ms)
Determinism: the converter was run twice and sha256sum dungeons/*.json matched byte for byte.
The spec asserts, per JSON: cells inside rows × cols with no repeated position; both ends of every side agree and
edges are wall; only schema words; exactly one entrance and one boss; exactly one map and compass, and
(behind an isLttp guard on source.startsWith("LTTP"), per the ruling) exactly one Big Key and one big-chest;
every stairs/hole/teleport names a real cell; the cells of one room connect through open sides;
report.smallKeys equals the key-source cells; every cell reachable from the entrance through non-wall sides,
stairs, holes and teleports (Review Focus 3); plus report.cellsPerFloor matches the floors.
| id | source | cells / rooms | floors (grid, cells) | keys / locks | must-clear / side |
|---|---|---|---|---|---|
| storm-temple | Tower of Hera | 22 / 14 | B1 2x2 (4), 1F 2x2 (4), 2F 2x2 (4), 3F 17x2 (5), 4F 2x2 (4), 5F 1x1 (1) | 1 / 1 | 8 / 9 |
| earth-temple | Skull Woods | 31 / 22 | B1 1x1 (1), 1F 7x8 (30) | 5 / 5 | 8 / 15 |
| light-temple | Desert Palace | 33 / 24 | 1F 6x6 (25), 2F 5x2 (8) | 4 / 4 | 4 / 15 |
| water-temple | Swamp Palace | 45 / 28 | B2 4x2 (8), B1 9x9 (31), 1F 8x9 (6) | 6 / 6 | 11 / 25 |
| shadow-temple | Palace of Darkness | 39 / 27 | B1 13x6 (10), 1F 8x5 (29) | 6 / 6 | 1 / 26 |
| ice-temple | Ice Palace | 39 / 36 | B7 1x1 (1), B6 17x3 (5), B5 3x3 (6), B4 3x3 (6), B3 3x4 (6), B2 3x4 (7), B1 3x4 (6), 1F 1x2 (2) | 6 / 6 | 4 / 18 |
| fire-temple | Turtle Rock | 49 / 32 | B2 7x4 (15), B1 6x5 (19), 1F 6x3 (15) | 6 / 6 | 3 / 22 |
| moon-temple | Ganons Tower | 82 / 64 | B2 2x2 (4), B1 6x6 (35), 1F 2x2 (3), 2F 4x4 (9), 3F 4x4 (8), 4F 4x4 (11), 5F 4x3 (9), 6F 2x2 (3) | 8 / 8 | 18 / 23 |
Every dungeon has exactly one map, compass, big-key chest, big-chest, boss and entrance. Side kinds in
use: open, wall, small-key, big-key, bomb, shutter, item (item appears in Swamp (6 sides: flipper and
hookshot gaps) and Ganon's Tower (2); see concern 7 for Hera).
== storm-temple: LTTP Tower of Hera
cells per floor: B1 4, 1F 4, 2F 4, 3F 5, 4F 4, 5F 1
must-clear 8, side 9, small keys 1 against 1 locks
note: areas share screen 0x17 (0, 1): Hera 5F + Hera 5F Pot Block (one hall)
note: areas share screen 0x27 (0, 0): Hera 4F + Hera Big Chest Landing (one hall)
note: areas share screen 0x77 (1, 0): Hera Lobby + Hera Down Stairs Landing (one hall)
note: locked stairs (counted as a lock, the schema cannot lock stairs): Hera Tile Room Up Stairs <-> Hera Lobby Key Stairs
note: pit not drawn (no free cell): Hera Beetles Holes Landing -> Hera Up Stairs Landing
note: pit Hera 4F Holes drops 2 floor(s) to Hera Back: teleport
note: pit Hera Boss Inner Hole drops 2 floor(s) to Hera 4F: teleport
== earth-temple: LTTP Skull Woods
cells per floor: B1 1, 1F 30
must-clear 8, side 15, small keys 5 against 5 locks
note: areas share screen 0x56 (1, 0): Skull 2 West Lobby + Skull 2 West Lobby Ledge (one hall)
note: areas share screen 0x56 (1, 1): Skull Small Hall + Skull Back Drop (one hall)
note: areas share screen 0x58 (1, 0): Skull 1 Lobby + Skull Big Chest (one hall)
note: areas share screen 0x59 (1, 0): Skull 3 Lobby + Skull West Bridge Nook (one hall)
note: entrance ring: 1F (11, 16) -> 1F (11, 12) -> 1F (11, 14) -> 1F (11, 18) -> 1F (11, 16)
== light-temple: LTTP Desert Palace
cells per floor: 1F 25, 2F 8
must-clear 4, side 15, small keys 4 against 4 locks
note: areas share screen 0x74 (1, 0): Desert Dead End + Desert North Hall (one hall)
note: areas share screen 0x84 (0, 0): Desert Main Lobby + Desert Left Alcove (one hall)
note: areas share screen 0x84 (0, 1): Desert Main Lobby + Desert Right Alcove (one hall)
note: locked stairs (counted as a lock, the schema cannot lock stairs): Desert Tiles 1 Up Stairs <-> Desert Bridge Down Stairs
note: entrance ring: 1F (17, 8) -> 1F (17, 11) -> 1F (17, 6) -> 1F (13, 6) -> 1F (17, 8)
== water-temple: LTTP Swamp Palace
cells per floor: B2 8, B1 31, 1F 6
must-clear 11, side 25, small keys 6 against 6 locks
note: areas share screen 0x16 (0, 0): Swamp I + Swamp T (one hall)
note: areas share screen 0x16 (0, 1): Swamp C + Swamp I (one hall)
note: areas share screen 0x26 (0, 1): Swamp Left Elbow + Swamp Right Elbow (one hall)
note: areas share screen 0x28 (1, 0): Swamp Lobby + Swamp Entrance (one hall)
note: areas share screen 0x34 (0, 1): Swamp Barrier Ledge + Swamp Barrier (one hall)
note: areas share screen 0x34 (1, 0): Swamp West Shallows + Swamp West Block Path (one hall)
note: areas share screen 0x35 (0, 0): Swamp Trench 2 Alcove + Swamp Big Key Ledge (one hall)
note: areas share screen 0x35 (1, 0): Swamp Trench 2 Blocks + Swamp Trench 2 Departure (one hall)
note: areas share screen 0x35 (1, 1): Swamp Shortcut + Swamp Trench 2 Pots (one hall)
note: areas share screen 0x36 (0, 0): Swamp Hub + Swamp Hub Side Ledges (one hall)
note: areas share screen 0x36 (0, 0): Swamp Hub + Swamp Hub North Ledge (one hall)
note: areas share screen 0x36 (0, 1): Swamp Hub + Swamp Hub Dead Ledge (one hall)
note: areas share screen 0x37 (0, 0): Swamp Trench 1 Alcove + Swamp Hammer Switch (one hall)
note: areas share screen 0x37 (1, 0): Swamp Trench 1 Nexus + Swamp Trench 1 Key Ledge (one hall)
note: areas share screen 0x37 (1, 0): Swamp Trench 1 Nexus + Swamp Trench 1 Departure (one hall)
note: areas share screen 0x46 (0, 0): Swamp Donut Top + Swamp Compass Donut (one hall)
note: areas share screen 0x76 (0, 1): Swamp Drain Left + Swamp Drain Right (one hall)
note: areas share screen 0x76 (1, 1): Swamp Flooded Room + Swamp Flooded Spot (one hall)
note: locked stairs (counted as a lock, the schema cannot lock stairs): Swamp Pot Row Up Stairs <-> Swamp Entrance Down Stairs
note: parallel stairway skipped (its cells are already joined): Swamp Drain Right Up Stairs <-> Swamp Right Elbow Down Stairs
note: chest merged into a full cell: Swamp Palace - Flooded Room - Right
== shadow-temple: LTTP Palace of Darkness
cells per floor: B1 10, 1F 29
must-clear 1, side 26, small keys 6 against 6 locks
override: door PoD Compass Room SE pinned to 0x1a (0,1)
note: areas share screen 0x0b (0, 0): PoD Lonely Turtle + PoD Turtle Party (one hall)
note: areas share screen 0x0b (0, 1): PoD Dark Pegs Right + PoD Dark Pegs Middle (one hall)
note: areas share screen 0x0b (0, 1): PoD Dark Pegs Right + PoD Dark Pegs Left (one hall)
note: areas share screen 0x0b (0, 1): PoD Dark Pegs Right + PoD Callback (one hall)
note: areas share screen 0x1a (0, 0): PoD Falling Bridge Ledge + PoD Falling Bridge Mid (one hall)
note: areas share screen 0x1a (0, 0): PoD Falling Bridge Ledge + PoD Big Chest Balcony (one hall)
note: areas share screen 0x1a (1, 0): PoD Falling Bridge Mid + PoD Falling Bridge (one hall)
note: areas share screen 0x2a (0, 0): PoD Arena Main + PoD Arena North (one hall)
note: areas share screen 0x2a (0, 1): PoD Arena Main + PoD Arena Right (one hall)
note: areas share screen 0x2a (1, 1): PoD Arena Main + PoD Arena Bridge (one hall)
note: areas share screen 0x2a (1, 1): PoD Arena Main + PoD Arena Ledge (one hall)
note: areas share screen 0x3a (0, 0): PoD Pit Room + PoD Big Key Landing (one hall)
note: areas share screen 0x4a (0, 0): PoD Left Cage + PoD Middle Cage (one hall)
note: areas share screen 0x6a (0, 1): PoD Dark Basement + PoD Dark Alley (one hall)
note: locked stairs (counted as a lock, the schema cannot lock stairs): PoD Basement Ledge Up Stairs <-> PoD Big Key Landing Down Stairs
note: parallel stairway skipped (its cells are already joined): PoD Dark Basement E Up Stairs <-> PoD Compass Room E Down Stairs
note: chest merged into a full cell: Palace of Darkness - Dark Basement - Left
note: PoD Turtle Party is 2 rooms on B1: PoD Lonely Turtle, PoD Turtle Party
== ice-temple: LTTP Ice Palace
cells per floor: B7 1, B6 5, B5 6, B4 6, B3 6, B2 7, B1 6, 1F 2
must-clear 4, side 18, small keys 6 against 6 locks
override: door Ice Spike Room Down Stairs pinned to 0x5f (1,1)
note: areas share screen 0x1e (0, 1): Ice Bomb Drop + Ice Bomb Drop - Top (one hall)
note: areas share screen 0x1e (1, 1): Ice Cross Left + Ice Cross Bottom (one hall)
note: areas share screen 0x1e (1, 1): Ice Cross Left + Ice Cross Right (one hall)
note: areas share screen 0x1e (1, 1): Ice Cross Left + Ice Cross Top (one hall)
note: areas share screen 0x1f (1, 1): Ice Dead End + Ice Big Key (one hall)
note: areas share screen 0x3f (1, 0): Ice Right H + Ice Hammer Block (one hall)
note: areas share screen 0x4e (0, 0): Ice Bomb Jump Ledge + Ice Bomb Jump Catwalk (one hall)
note: areas share screen 0x7e (1, 0): Ice Freezors + Ice Freezors Ledge (one hall)
note: areas share screen 0x7f (0, 0): Ice Hookshot Ledge + Ice Hookshot Balcony (one hall)
note: areas share screen 0x9e (1, 1): Ice Crystal Right + Ice Crystal Left (one hall)
note: locked stairs (counted as a lock, the schema cannot lock stairs): Ice Floor Switch Up Stairs <-> Ice Jelly Key Down Stairs
note: locked stairs (counted as a lock, the schema cannot lock stairs): Ice Anti-Fairy Up Stairs <-> Ice Backwards Room Down Stairs
== fire-temple: LTTP Turtle Rock
cells per floor: B2 15, B1 19, 1F 15
must-clear 3, side 22, small keys 6 against 6 locks
note: areas share screen 0x04 (0, 0): TR Crystaroller Bottom + TR Crystaroller Middle (one hall)
note: areas share screen 0x04 (0, 0): TR Crystaroller Bottom + TR Crystaroller Top (one hall)
note: areas share screen 0x14 (0, 0): TR Lava Dual Pipes + TR Lava Escape (one hall)
note: areas share screen 0x14 (1, 0): TR Lava Dual Pipes + TR Lava Island (one hall)
note: areas share screen 0x15 (0, 1): TR Pipe Pit + TR Pipe Ledge (one hall)
note: areas share screen 0x24 (1, 1): TR Big View + TR Big Chest (one hall)
note: areas share screen 0x24 (1, 1): TR Big View + TR Big Chest Entrance (one hall)
note: areas share screen 0xb5 (0, 0): TR Dark Ride North Platform + TR Dark Ride Ledges (one hall)
note: areas share screen 0xb6 (0, 0): TR Chain Chomps Top + TR Chain Chomps Bottom (one hall)
note: areas share screen 0xc4 (0, 0): TR Crystal Maze Interior + TR Crystal Maze End (one hall)
note: areas share screen 0xc4 (1, 1): TR Crystal Maze Start + TR Crystal Maze Interior (one hall)
note: areas share screen 0xc6 (0, 0): TR Hub + TR Hub Ledges (one hall)
note: locked stairs (counted as a lock, the schema cannot lock stairs): TR Pipe Pit Up Stairs <-> TR Chain Chomps Down Stairs
note: locked stairs (counted as a lock, the schema cannot lock stairs): TR Dark Ride Up Stairs <-> TR Crystaroller Down Stairs
note: entrance ring: 1F (27, 13) -> B1 (5, 7) -> B2 (27, 10) -> B1 (5, 9) -> 1F (27, 13)
note: chest merged into a full cell: Turtle Rock - Eye Bridge - Top Left
note: chest merged into a full cell: Turtle Rock - Eye Bridge - Top Right
== moon-temple: LTTP Ganons Tower
cells per floor: B2 4, B1 35, 1F 3, 2F 9, 3F 8, 4F 11, 5F 9, 6F 3
must-clear 18, side 23, small keys 8 against 8 locks
note: areas share screen 0x3d (1, 0): GT Crystal Circles + GT Crystal Inner Circle (one hall)
note: areas share screen 0x6c (0, 0): GT Lanmolas 2 + GT Quad Pot (one hall)
note: areas share screen 0x7d (0, 0): GT Firesnake Room + GT Firesnake Room Ledge (one hall)
note: areas share screen 0x7d (1, 0): GT Warp Maze - Rail Choice + GT Warp Maze - Rando Rail (one hall)
note: areas share screen 0x7d (1, 0): GT Warp Maze - Rail Choice + GT Warp Maze - Main Rails (one hall)
note: areas share screen 0x7d (1, 1): GT Warp Maze - Pot Rail + GT Petting Zoo (one hall)
note: areas share screen 0x8b (0, 0): GT Hookshot East Platform + GT Hookshot Mid Platform (one hall)
note: areas share screen 0x8b (0, 0): GT Hookshot East Platform + GT Hookshot North Platform (one hall)
note: areas share screen 0x8b (0, 1): GT Conveyor Cross + GT Conveyor Cross Across Pits (one hall)
note: areas share screen 0x8b (1, 0): GT Hookshot Mid Platform + GT Hookshot South Platform (one hall)
note: areas share screen 0x8b (1, 0): GT Hookshot Mid Platform + GT Hookshot South Entry (one hall)
note: areas share screen 0x8c (1, 0): GT Big Chest + GT Blocked Stairs (one hall)
note: areas share screen 0x9b (0, 0): GT Double Switch Entry + GT Double Switch Pot Corners (one hall)
note: areas share screen 0x9b (0, 0): GT Double Switch Entry + GT Double Switch Exit (one hall)
note: areas share screen 0x9b (0, 1): GT Spike Crystal Left + GT Spike Crystal Right (one hall)
note: areas share screen 0x9b (1, 1): GT Warp Maze - Pit Section + GT Warp Maze Exit Section (one hall)
note: areas share screen 0x9d (0, 1): GT Crystal Conveyor + GT Crystal Conveyor Corner (one hall)
note: areas share screen 0x9d (0, 1): GT Crystal Conveyor + GT Crystal Conveyor Left (one hall)
note: second stairway in one screen moved within its hall: GT Lobby Up Stairs
note: second stairway in one screen moved within its hall: GT Lobby Right Down Stairs
note: warp not drawn (no free cell): GT Warp Maze - Mid Section Right Warp -> GT Warp Maze - Main Rails
note: warp not drawn (no free cell): GT Warp Maze - Rando Rail Warp -> GT Warp Maze - Mid Section
note: warp not drawn (no free cell): GT Warp Maze - Main Rails Best Warp -> GT Warp Maze - Pit Section
note: warp not drawn (no free cell): GT Warp Maze - Main Rails Mid Left Warp -> GT Warp Maze - Mid Section
note: warp not drawn (no free cell): GT Warp Maze - Main Rails Mid Right Warp -> GT Warp Maze - Mid Section
note: chest merged into a full cell: Ganons Tower - Hope Room - Right
note: chest merged into a full cell: Ganons Tower - Compass Room - Top Right
note: chest merged into a full cell: Ganons Tower - Compass Room - Bottom Left
note: chest merged into a full cell: Ganons Tower - Compass Room - Bottom Right
note: chest merged into a full cell: Ganons Tower - DMs Room - Top Right
note: chest merged into a full cell: Ganons Tower - DMs Room - Bottom Left
note: chest merged into a full cell: Ganons Tower - DMs Room - Bottom Right
note: chest merged into a full cell: Ganons Tower - Randomizer Room - Top Right
note: chest merged into a full cell: Ganons Tower - Randomizer Room - Bottom Left
note: chest merged into a full cell: Ganons Tower - Randomizer Room - Bottom Right
note: chest merged into a full cell: Ganons Tower - Big Key Room - Left
note: chest merged into a full cell: Ganons Tower - Big Key Room - Right
note: chest merged into a full cell: Ganons Tower - Mini Helmasaur Room - Right
note: no vanilla item for Ganons Tower - Validation Chest: other
note: GT Lanmolas 2 is 2 rooms on 3F: GT Lanmolas 2, GT Quad Pot
"areas share screen" notes are informational: a ledge, alcove or crystal-barrier sub-area that sits in the same
screen as its parent area becomes one hall with it (the room takes the larger area's name).
-
overrides/shadow-temple.json—doors: {"PoD Compass Room SE": ["0x1a", 0, 1]}. Doors.py slots this interior doorMidwhile its partnerPoD Harmless Hellway NEis slottedRight; under the brief's rule the two ends land in non-adjacent cells (the only such pair out of 206). RoomData gives the doorPosition.InteriorE(the east half), so the Compass Room end is pinned to the top-right screen of 0x1a. -
overrides/ice-temple.json—doors: {"Ice Spike Room Down Stairs": ["0x5f", 1, 1]}. The Spike Room holds an up and a down stairway in one screen; the schema allows onestairsper cell. The other three screens of 0x5f are empty, so the down stairway is pinned to the screen beside it and the room becomes two cells joined by an open side.
The override file format (documented in convert.py's header): areas (pin an area's screens), doors (pin a
door's screen), chests (pin a location's screen), sides (add or remove a side between two cells), note.
Cells, door slots, floor naming, Up/Dn ±1, pits down one floor, teleports for pits of two or more floors and for
warps, trimmed floor grids, room from the area, chest-with-no-screen to the area's first screen: as the brief says.
Pairings of doors, stairs, ladders (treated as stairs, ±1 by "Up"/"Down" in the name), open edges, pits and warps
come from DoorShuffle.py's vanilla tables; interior door pairs are also checked for adjacency under the slot rule.
-
Sprite screen split is 0x10, not 0x20.
EnemyList.pykeeps 5-bit tile coordinates (max x 0x1e, y 0x1c; about half the sprites are at or above 0x10). A split at 0x20 can never trigger and would put every enemy in the top-left screen. The converter splits at 0x10 (and the pot table at its own units: y in 16px tiles, x in 4px units modulo 128, derived from theRoomObjectbytes). Verified against Hera's rooms (beetles, torches, tile room). -
Shutters come from RoomData's
Trapkinds, not.trap(). In these eight dungeons no door carries.trap()where RoomData does not also mark a trap kind, and ~90 doors withTrap/Trap2/TrapTriggerablekinds (kill rooms, the Hera tile room) carry no.trap()at all (.trap()is a ROM target flag). The converter honours both. -
Three extra pinned sources (
DoorShuffle.py,RoomData.py,PotShuffle.py), same commit, same licence; listed inSOURCES.mdwith the reason. -
Locked stairways cannot be expressed. Eight stairways are small-key doors (
StairKeykinds): Hera Lobby Key Stairs, Desert Tiles 1, Swamp Entrance, PoD Big Key Landing, Ice Jelly Key, Ice Backwards Room, TR Chain Chomps, TR Crystaroller. They are counted inreport.smallLocks(so keys and locks balance) but thestairslink has no kind. The dress step may want to put the lock on the stairs' cell or drop it; the printout names each one. -
Entrance ring. With one teleport slot per cell, "each other entrance teleports to the main door and back" is
only exact for one other entrance. Desert (4 doors), Skull Woods (4) and Turtle Rock (4) get a ring: main → next →
… → main, in
create_portalsorder. Skull Woods' four overworld drop-ins are already reachable through its doors and are not in the ring. -
Multi-chest rooms. One
chestper cell: when an area has more chests than cells, dungeon items take the cells first and plain treasure ("other") merges into a full cell with a note (17 merged: PoD Dark Basement Left, Swamp Flooded Room Right, TR Eye Bridge Top Left/Right, and 13 in Ganon's Tower).Ganons Tower - Validation Chestis not in the V30 vanilla table (added later) and is treated as "other". -
Item gaps. Logical links whose door name mentions hookshot, boots/dash, torch or flippers become
itemsides; that gives 6 in Swamp and 2 in Ganon's Tower. Hera's hookshot gap to the Big Chest Landing vanishes because that ledge shares the 4F screen (same cell), so Hera has noitemside. - Ganon's Tower warp maze. Its sections sit in two supertiles; five of its warps could not be drawn because the cells' single teleport slots were taken. Every cell is still reachable (the spec proves it), so no override. Two of the lobby's three stairways were moved to neighbouring lobby cells for the same one-link-per-cell reason.
- Sparse floor grids. Cells keep LTTP's supertile positions, so a side room far away on the map makes a wide grid with few cells: Hera 3F 17x2 (the fairy room), Ice B6 17x3, PoD B1 13x6, Swamp 1F 8x9 / B1 9x9. The schema is fine with it; the dress step may want to compact or ignore empty columns.
-
Boss rooms entered by falling. Skull Woods and Ice Palace reach the boss by a pit and the boss room has no
door; its only screen evidence is the unlabelled boss sprite, so
BOSS_OF(dungeon → boss sprite) in the converter supplies it.enemiescounts sprites whoseEnemyStatsare neither static nor ignore-for-kill-room (so bumpers, sparks, beamos, fairies, statues do not count); boss sprites in non-boss rooms (GT's refights) count as one enemy each so those rooms are not empty. -
puzzleis set from crystal/pull/water switch sprites, pot switches, event locations (Trench switches, Swamp Drain, Skull Star Tile, Ice Block Drop) and room names containing Torch/Peg/Tile/Switch/Push.mustClearis the number of fight cells whose removal cuts the boss off from the entrance;sideis the other fight cells. - Split halls. When a sub-area that shares a screen with its parent is separated from the rest by a shutter, the hall is split into rooms named after the sub-area (PoD Lonely Turtle / Turtle Party, GT Quad Pot / Lanmolas 2).
/home/xopher/www/x/do-it-for-the-xp/.claude/worktrees/agent-a0c36dc212c21b2b0/tests/unit/ClassicDungeonJson.spec.ts/home/xopher/www/x/do-it-for-the-xp/.claude/worktrees/agent-a0c36dc212c21b2b0/tools/temples/classic/SOURCES.md/home/xopher/www/x/do-it-for-the-xp/.claude/worktrees/agent-a0c36dc212c21b2b0/tools/temples/classic/classicDungeon.ts/home/xopher/www/x/do-it-for-the-xp/.claude/worktrees/agent-a0c36dc212c21b2b0/tools/temples/classic/convert.py/home/xopher/www/x/do-it-for-the-xp/.claude/worktrees/agent-a0c36dc212c21b2b0/tools/temples/classic/dungeons/{storm,earth,light,water,shadow,ice,fire,moon}-temple.json/home/xopher/www/x/do-it-for-the-xp/.claude/worktrees/agent-a0c36dc212c21b2b0/tools/temples/classic/overrides/{shadow,ice}-temple.json-
/home/xopher/www/x/do-it-for-the-xp/.claude/worktrees/agent-a0c36dc212c21b2b0/tools/temples/classic/sources/{Doors,Regions,EnemyList,DoorShuffle,RoomData,PotShuffle}.py,LoZ_1.dot,LICENSE-ALttPDoorRandomizer.txt,LICENSE-TheVGLC.md,LICENSE-alttp_vt_randomizer.txt /home/xopher/www/x/do-it-for-the-xp/.claude/worktrees/agent-a0c36dc212c21b2b0/tools/temples/classic/sources/vanilla/{TowerOfHera,SkullWoods,DesertPalace,SwampPalace,PalaceOfDarkness,IcePalace,TurtleRock,GanonsTower}.php
Not touched: docs/, the lead's worktree (other than this report), the shared checkout. No chemx typecheck, lint,
verify, build, or bare test run; only chemx test tests/unit/ClassicDungeonJson.spec.ts.
Commit 5491b30fe on worktree-agent-a0c36dc212c21b2b0 (on top of 2db3e819):
fix(tools): LTTP converter round 1: edge conflicts stop, locked stairs recorded, shutter on the trap's own cell.
-
Two doors on one cell edge (convert.py
apply_doors). Each edge remembers the door pair that drew it. A second pair with a different non-openkind stops the run with an error naming both pairs, their Doors.py slots and their RoomData positions, unless asidesoverride settles that edge (then it is a note). Anopendoorway beside a locked one keeps the lock; two identical kinds are fine. The three conflicts the review found were each settled by moving theMidpair to the half RoomData's position names (the key doors sit atInteriorN/EastN, the top half, and were already there):-
overrides/water-temple.json(new):Swamp Waterway N-> 0x16 (1,1),Swamp I S-> 0x16 (0,1) (bomb wall,InteriorV, the middle; the key doorSwamp Waterway NW <-> Swamp T SWstays in the west half). -
overrides/shadow-temple.json:PoD Turtle Party ES-> 0x0b (1,0),PoD Callback WS-> 0x0b (1,1) (trap door,InteriorS);PoD Dark Maze E-> 0x19 (1,1),PoD Big Chest Balcony W-> 0x1a (1,0) (bomb wall, plainEast/West). The Callback becomes its own cell (PoD B1 is now 11 cells) and the big chest balcony joins the Falling Bridge's bottom landing. Result: Palace of Darkness keeps both small-key doors (smallLocks 6 = 5 sides + 1 locked stairway), Swamp keeps its bomb wall (bomb sides 4 -> 6).
-
-
Locked stairways.
ClassicLinkgainslock?: "small-key" | "big-key"(doc comment inclassicDungeon.ts: it sits on thestairslink of the one cell that holds the locked stairway door, never on the other end). The converter sets it from.small_key()/.big_key()or the RoomDataStairKey*/BigKeykind of that door (no big-key stairway exists in the eight). The eight locked stairways are now in the JSON: Hera Lobby Key Stairs (1F), Desert Tiles 1 Up Stairs, Swamp Entrance Down Stairs, PoD Basement Ledge Up Stairs, Ice Jelly Key Down Stairs, Ice Backwards Room Down Stairs, TR Chain Chomps Down Stairs, TR Crystaroller Down Stairs. The spec assertsreport.smallLocks= small-key side pairs (each once) + links withlock: "small-key", and the converter now countssmallLocksfrom the final sides and links (after the overrides), not while drawing doors. -
report.mustClear= the number of distinctroomids with a cell that hasenemies > 0and (shutterorkeyDrop);side= the other rooms with such a fight cell. The boss cell and cells whose only enemies are boss-kind sprites (the Ganon's Tower refights) count for neither. The old cut-vertex count is gone. -
shutterflag is set only on the cell whose own door carries.trap(...)or a RoomData Trap kind (the side staysshutteron both ends). Candidates are gathered while drawing doors and flagged after the side overrides, only if the edge is stillshutter. PoD Conveyor, Skull Compass Room, Ice Tall Hint, TR Roller Room, GT Tile Room, GT Speed Torch Upper, GT Crystal Conveyor and GT Invisible Bridges lost the flag; PoD Mimics 1 keeps it.
Also: run() now applies the side overrides before the shutter flags and the lock count
(apply_doors -> apply_links -> apply_side_overrides -> flag_shutters -> apply_contents -> finish); an override that
names an unknown door (doors) or chest (chests) is an error, like an unknown area. Not touched, per the ruling:
smallKeys from source locations, the pot hex-coordinate regex, floor-conflict warnings, the unplaced-main-door
crash, the stairs-reciprocal and hole-one-floor spec checks.
$ python3 tools/temples/classic/convert.py # before the overrides: the three conflicts, as errors
ERROR: two doors on one edge B1 (3, 12) north: Swamp Waterway N [Mid, InteriorV] <-> Swamp I S [Mid, InteriorV] is bomb, Swamp Waterway NW [Left, InteriorW] <-> Swamp T SW [Left, InteriorW] is small-key; move one door to the other screen of its supertile (overrides.doors) or pick the kind (overrides.sides)
ERROR: two doors on one edge B1 (0, 22) east: PoD Dark Pegs WN [Mid, InteriorN] <-> PoD Lonely Turtle EN [Mid, InteriorN] is small-key, PoD Turtle Party ES [Mid, InteriorS] <-> PoD Callback WS [Mid, InteriorS] is shutter; ...
ERROR: two doors on one edge 1F (2, 19) east: PoD Falling Bridge WN [Top, WestN] <-> PoD Dark Maze EN [Top, EastN] is small-key, PoD Dark Maze E [Mid, East] <-> PoD Big Chest Balcony W [Mid, West] is bomb; ...
(water-temple and shadow-temple not written; the other six wrote)
$ python3 tools/temples/classic/convert.py # with the overrides: exit 0, all eight written (printout below)
$ chemx test tests/unit/ClassicDungeonJson.spec.ts
✔ All tests passed (89 passed in 9848ms)
$ python3 tools/temples/classic/convert.py; sha256sum dungeons/*.json # twice
deterministic: identical bytes across two runs
Per dungeon after the fix (cells / rooms unchanged except PoD 40 cells / 28 rooms): keys/locks Hera 1/1, Skull 5/5, Desert 4/4, Swamp 6/6, PoD 6/6, Ice 6/6, TR 6/6, GT 8/8; must-clear/side Hera 3/6, Skull 6/12, Desert 6/6, Swamp 3/20, PoD 6/12, Ice 14/6, TR 7/9, GT 19/16; shutter flags Skull 6, Desert 13, Swamp 5, PoD 12, Ice 22, TR 11, GT 34, Hera 4.
== storm-temple: LTTP Tower of Hera
cells per floor: B1 4, 1F 4, 2F 4, 3F 5, 4F 4, 5F 1
must-clear 3, side 6, small keys 1 against 1 locks
note: areas share screen 0x17 (0, 1): Hera 5F + Hera 5F Pot Block (one hall)
note: areas share screen 0x27 (0, 0): Hera 4F + Hera Big Chest Landing (one hall)
note: areas share screen 0x77 (1, 0): Hera Lobby + Hera Down Stairs Landing (one hall)
note: locked stairway recorded on 1F (14, 14): Hera Lobby Key Stairs
note: pit not drawn (no free cell): Hera Beetles Holes Landing -> Hera Up Stairs Landing
note: pit Hera 4F Holes drops 2 floor(s) to Hera Back: teleport
note: pit Hera Boss Inner Hole drops 2 floor(s) to Hera 4F: teleport
== earth-temple: LTTP Skull Woods
cells per floor: B1 1, 1F 30
must-clear 6, side 12, small keys 5 against 5 locks
note: areas share screen 0x56 (1, 0): Skull 2 West Lobby + Skull 2 West Lobby Ledge (one hall)
note: areas share screen 0x56 (1, 1): Skull Small Hall + Skull Back Drop (one hall)
note: areas share screen 0x58 (1, 0): Skull 1 Lobby + Skull Big Chest (one hall)
note: areas share screen 0x59 (1, 0): Skull 3 Lobby + Skull West Bridge Nook (one hall)
note: entrance ring: 1F (11, 16) -> 1F (11, 12) -> 1F (11, 14) -> 1F (11, 18) -> 1F (11, 16)
== light-temple: LTTP Desert Palace
cells per floor: 1F 25, 2F 8
must-clear 6, side 6, small keys 4 against 4 locks
note: areas share screen 0x74 (1, 0): Desert Dead End + Desert North Hall (one hall)
note: areas share screen 0x84 (0, 0): Desert Main Lobby + Desert Left Alcove (one hall)
note: areas share screen 0x84 (0, 1): Desert Main Lobby + Desert Right Alcove (one hall)
note: locked stairway recorded on 1F (12, 6): Desert Tiles 1 Up Stairs
note: entrance ring: 1F (17, 8) -> 1F (17, 11) -> 1F (17, 6) -> 1F (13, 6) -> 1F (17, 8)
== water-temple: LTTP Swamp Palace
cells per floor: B2 8, B1 31, 1F 6
must-clear 3, side 20, small keys 6 against 6 locks
override: door Swamp Waterway N pinned to 0x16 (1,1)
override: door Swamp I S pinned to 0x16 (0,1)
note: areas share screen 0x16 (0, 0): Swamp I + Swamp T (one hall)
note: areas share screen 0x16 (0, 1): Swamp C + Swamp I (one hall)
note: areas share screen 0x26 (0, 1): Swamp Left Elbow + Swamp Right Elbow (one hall)
note: areas share screen 0x28 (1, 0): Swamp Lobby + Swamp Entrance (one hall)
note: areas share screen 0x34 (0, 1): Swamp Barrier Ledge + Swamp Barrier (one hall)
note: areas share screen 0x34 (1, 0): Swamp West Shallows + Swamp West Block Path (one hall)
note: areas share screen 0x35 (0, 0): Swamp Trench 2 Alcove + Swamp Big Key Ledge (one hall)
note: areas share screen 0x35 (1, 0): Swamp Trench 2 Blocks + Swamp Trench 2 Departure (one hall)
note: areas share screen 0x35 (1, 1): Swamp Shortcut + Swamp Trench 2 Pots (one hall)
note: areas share screen 0x36 (0, 0): Swamp Hub + Swamp Hub Side Ledges (one hall)
note: areas share screen 0x36 (0, 0): Swamp Hub + Swamp Hub North Ledge (one hall)
note: areas share screen 0x36 (0, 1): Swamp Hub + Swamp Hub Dead Ledge (one hall)
note: areas share screen 0x37 (0, 0): Swamp Trench 1 Alcove + Swamp Hammer Switch (one hall)
note: areas share screen 0x37 (1, 0): Swamp Trench 1 Nexus + Swamp Trench 1 Key Ledge (one hall)
note: areas share screen 0x37 (1, 0): Swamp Trench 1 Nexus + Swamp Trench 1 Departure (one hall)
note: areas share screen 0x46 (0, 0): Swamp Donut Top + Swamp Compass Donut (one hall)
note: areas share screen 0x76 (0, 1): Swamp Drain Left + Swamp Drain Right (one hall)
note: areas share screen 0x76 (1, 1): Swamp Flooded Room + Swamp Flooded Spot (one hall)
note: locked stairway recorded on 1F (4, 16): Swamp Entrance Down Stairs
note: parallel stairway skipped (its cells are already joined): Swamp Drain Right Up Stairs <-> Swamp Right Elbow Down Stairs
note: chest merged into a full cell: Swamp Palace - Flooded Room - Right
== shadow-temple: LTTP Palace of Darkness
cells per floor: B1 11, 1F 29
must-clear 6, side 12, small keys 6 against 6 locks
override: door PoD Dark Maze E pinned to 0x19 (1,1)
override: door PoD Big Chest Balcony W pinned to 0x1a (1,0)
override: door PoD Compass Room SE pinned to 0x1a (0,1)
override: door PoD Turtle Party ES pinned to 0x0b (1,0)
override: door PoD Callback WS pinned to 0x0b (1,1)
note: areas share screen 0x0b (0, 1): PoD Dark Pegs Right + PoD Dark Pegs Middle (one hall)
note: areas share screen 0x0b (0, 1): PoD Dark Pegs Right + PoD Dark Pegs Left (one hall)
note: areas share screen 0x1a (0, 0): PoD Falling Bridge Ledge + PoD Falling Bridge Mid (one hall)
note: areas share screen 0x1a (1, 0): PoD Falling Bridge Mid + PoD Falling Bridge (one hall)
note: areas share screen 0x1a (1, 0): PoD Falling Bridge Mid + PoD Big Chest Balcony (one hall)
note: areas share screen 0x2a (0, 0): PoD Arena Main + PoD Arena North (one hall)
note: areas share screen 0x2a (0, 1): PoD Arena Main + PoD Arena Right (one hall)
note: areas share screen 0x2a (1, 1): PoD Arena Main + PoD Arena Bridge (one hall)
note: areas share screen 0x2a (1, 1): PoD Arena Main + PoD Arena Ledge (one hall)
note: areas share screen 0x3a (0, 0): PoD Pit Room + PoD Big Key Landing (one hall)
note: areas share screen 0x4a (0, 0): PoD Left Cage + PoD Middle Cage (one hall)
note: areas share screen 0x6a (0, 1): PoD Dark Basement + PoD Dark Alley (one hall)
note: locked stairway recorded on B1 (0, 20): PoD Basement Ledge Up Stairs
note: parallel stairway skipped (its cells are already joined): PoD Dark Basement E Up Stairs <-> PoD Compass Room E Down Stairs
note: chest merged into a full cell: Palace of Darkness - Dark Basement - Left
== ice-temple: LTTP Ice Palace
cells per floor: B7 1, B6 5, B5 6, B4 6, B3 6, B2 7, B1 6, 1F 2
must-clear 14, side 6, small keys 6 against 6 locks
override: door Ice Spike Room Down Stairs pinned to 0x5f (1,1)
note: areas share screen 0x1e (0, 1): Ice Bomb Drop + Ice Bomb Drop - Top (one hall)
note: areas share screen 0x1e (1, 1): Ice Cross Left + Ice Cross Bottom (one hall)
note: areas share screen 0x1e (1, 1): Ice Cross Left + Ice Cross Right (one hall)
note: areas share screen 0x1e (1, 1): Ice Cross Left + Ice Cross Top (one hall)
note: areas share screen 0x1f (1, 1): Ice Dead End + Ice Big Key (one hall)
note: areas share screen 0x3f (1, 0): Ice Right H + Ice Hammer Block (one hall)
note: areas share screen 0x4e (0, 0): Ice Bomb Jump Ledge + Ice Bomb Jump Catwalk (one hall)
note: areas share screen 0x7e (1, 0): Ice Freezors + Ice Freezors Ledge (one hall)
note: areas share screen 0x7f (0, 0): Ice Hookshot Ledge + Ice Hookshot Balcony (one hall)
note: areas share screen 0x9e (1, 1): Ice Crystal Right + Ice Crystal Left (one hall)
note: locked stairway recorded on 1F (1, 28): Ice Jelly Key Down Stairs
note: locked stairway recorded on B5 (18, 29): Ice Backwards Room Down Stairs
== fire-temple: LTTP Turtle Rock
cells per floor: B2 15, B1 19, 1F 15
must-clear 7, side 9, small keys 6 against 6 locks
note: areas share screen 0x04 (0, 0): TR Crystaroller Bottom + TR Crystaroller Middle (one hall)
note: areas share screen 0x04 (0, 0): TR Crystaroller Bottom + TR Crystaroller Top (one hall)
note: areas share screen 0x14 (0, 0): TR Lava Dual Pipes + TR Lava Escape (one hall)
note: areas share screen 0x14 (1, 0): TR Lava Dual Pipes + TR Lava Island (one hall)
note: areas share screen 0x15 (0, 1): TR Pipe Pit + TR Pipe Ledge (one hall)
note: areas share screen 0x24 (1, 1): TR Big View + TR Big Chest (one hall)
note: areas share screen 0x24 (1, 1): TR Big View + TR Big Chest Entrance (one hall)
note: areas share screen 0xb5 (0, 0): TR Dark Ride North Platform + TR Dark Ride Ledges (one hall)
note: areas share screen 0xb6 (0, 0): TR Chain Chomps Top + TR Chain Chomps Bottom (one hall)
note: areas share screen 0xc4 (0, 0): TR Crystal Maze Interior + TR Crystal Maze End (one hall)
note: areas share screen 0xc4 (1, 1): TR Crystal Maze Start + TR Crystal Maze Interior (one hall)
note: areas share screen 0xc6 (0, 0): TR Hub + TR Hub Ledges (one hall)
note: locked stairway recorded on 1F (22, 12): TR Chain Chomps Down Stairs
note: locked stairway recorded on B1 (0, 8): TR Crystaroller Down Stairs
note: entrance ring: 1F (27, 13) -> B1 (5, 7) -> B2 (27, 10) -> B1 (5, 9) -> 1F (27, 13)
note: chest merged into a full cell: Turtle Rock - Eye Bridge - Top Left
note: chest merged into a full cell: Turtle Rock - Eye Bridge - Top Right
== moon-temple: LTTP Ganons Tower
cells per floor: B2 4, B1 35, 1F 3, 2F 9, 3F 8, 4F 11, 5F 9, 6F 3
must-clear 19, side 16, small keys 8 against 8 locks
note: areas share screen 0x3d (1, 0): GT Crystal Circles + GT Crystal Inner Circle (one hall)
note: areas share screen 0x6c (0, 0): GT Lanmolas 2 + GT Quad Pot (one hall)
note: areas share screen 0x7d (0, 0): GT Firesnake Room + GT Firesnake Room Ledge (one hall)
note: areas share screen 0x7d (1, 0): GT Warp Maze - Rail Choice + GT Warp Maze - Rando Rail (one hall)
note: areas share screen 0x7d (1, 0): GT Warp Maze - Rail Choice + GT Warp Maze - Main Rails (one hall)
note: areas share screen 0x7d (1, 1): GT Warp Maze - Pot Rail + GT Petting Zoo (one hall)
note: areas share screen 0x8b (0, 0): GT Hookshot East Platform + GT Hookshot Mid Platform (one hall)
note: areas share screen 0x8b (0, 0): GT Hookshot East Platform + GT Hookshot North Platform (one hall)
note: areas share screen 0x8b (0, 1): GT Conveyor Cross + GT Conveyor Cross Across Pits (one hall)
note: areas share screen 0x8b (1, 0): GT Hookshot Mid Platform + GT Hookshot South Platform (one hall)
note: areas share screen 0x8b (1, 0): GT Hookshot Mid Platform + GT Hookshot South Entry (one hall)
note: areas share screen 0x8c (1, 0): GT Big Chest + GT Blocked Stairs (one hall)
note: areas share screen 0x9b (0, 0): GT Double Switch Entry + GT Double Switch Pot Corners (one hall)
note: areas share screen 0x9b (0, 0): GT Double Switch Entry + GT Double Switch Exit (one hall)
note: areas share screen 0x9b (0, 1): GT Spike Crystal Left + GT Spike Crystal Right (one hall)
note: areas share screen 0x9b (1, 1): GT Warp Maze - Pit Section + GT Warp Maze Exit Section (one hall)
note: areas share screen 0x9d (0, 1): GT Crystal Conveyor + GT Crystal Conveyor Corner (one hall)
note: areas share screen 0x9d (0, 1): GT Crystal Conveyor + GT Crystal Conveyor Left (one hall)
note: second stairway in one screen moved within its hall: GT Lobby Up Stairs
note: second stairway in one screen moved within its hall: GT Lobby Right Down Stairs
note: warp not drawn (no free cell): GT Warp Maze - Mid Section Right Warp -> GT Warp Maze - Main Rails
note: warp not drawn (no free cell): GT Warp Maze - Rando Rail Warp -> GT Warp Maze - Mid Section
note: warp not drawn (no free cell): GT Warp Maze - Main Rails Best Warp -> GT Warp Maze - Pit Section
note: warp not drawn (no free cell): GT Warp Maze - Main Rails Mid Left Warp -> GT Warp Maze - Mid Section
note: warp not drawn (no free cell): GT Warp Maze - Main Rails Mid Right Warp -> GT Warp Maze - Mid Section
note: chest merged into a full cell: Ganons Tower - Hope Room - Right
note: chest merged into a full cell: Ganons Tower - Compass Room - Top Right
note: chest merged into a full cell: Ganons Tower - Compass Room - Bottom Left
note: chest merged into a full cell: Ganons Tower - Compass Room - Bottom Right
note: chest merged into a full cell: Ganons Tower - DMs Room - Top Right
note: chest merged into a full cell: Ganons Tower - DMs Room - Bottom Left
note: chest merged into a full cell: Ganons Tower - DMs Room - Bottom Right
note: chest merged into a full cell: Ganons Tower - Randomizer Room - Top Right
note: chest merged into a full cell: Ganons Tower - Randomizer Room - Bottom Left
note: chest merged into a full cell: Ganons Tower - Randomizer Room - Bottom Right
note: chest merged into a full cell: Ganons Tower - Big Key Room - Left
note: chest merged into a full cell: Ganons Tower - Big Key Room - Right
note: chest merged into a full cell: Ganons Tower - Mini Helmasaur Room - Right
note: no vanilla item for Ganons Tower - Validation Chest: other
note: GT Lanmolas 2 is 2 rooms on 3F: GT Lanmolas 2, GT Quad Pot
Files changed in the fix commit: tools/temples/classic/convert.py, tools/temples/classic/classicDungeon.ts,
tests/unit/ClassicDungeonJson.spec.ts, tools/temples/classic/overrides/water-temple.json (new),
tools/temples/classic/overrides/shadow-temple.json, and the eight tools/temples/classic/dungeons/*.json.