3#include "absl/strings/str_format.h"
22# ALTTP ROM Structure Deep Dive
25- 0x00000-0x07FFF: Header + Low ROM
26- 0x08000-0x0FFFF: Character data
27- 0x10000-0x1FFFF: Overworld maps
28- 0x1C800-0x1D7FF: Overworld tile16 data
29- 0x20000-0x2FFFF: Dungeon rooms (296 rooms)
30- 0xDE604-0xDEBB3: Overworld palettes (ow_animated + ow_main + ow_aux)
31- 0xDD734-0xDE543: Dungeon main palettes (dungeon_main, 20 sets x 180 bytes)
34- 64 maps (0x00-0x3F): Light world + Dark world
35- Each map: 32x32 tiles (1024 tile16s)
36- Tile16 address = 0x1C800 + (tile_id * 8 bytes)
37- Map data stored compressed
40- 296 rooms total (0x00-0x127)
41- Room header: 14 bytes
42- Sprite data: 3 bytes per sprite, up to 16 sprites
43- Layer 1/2 separate data
44- Object encoding: Layer/Size/X/Y format
47- Multiple palette groups with different shapes/sizes:
48 - Overworld main: 6 sets x 35 colors
49 - Overworld aux: 20 sets x 21 colors
50 - Overworld animated: 14 sets x 7 colors
51 - Dungeon main: 20 sets x 90 colors (6 banks x 15, transparent implicit)
52 - Global sprites: 2 sets x 60 colors (4 banks x 15, transparent implicit)
53- SNES CGRAM is organized as 16-color banks (BGR555). Color 0 of each bank is the transparent/backdrop slot.
54- Many ROM palette tables store 15 colors per bank and skip the implicit transparent slot.
55- $0000-$7FFF range (5 bits per R/G/B channel)
56- Conversion: RGB8 = (SNES_val & 0x1F) << 3
59- Sprite sheets: 0x80000+
60- Entrance table: 0x02C000
68# Hex Data Analysis Patterns
72### Sprite Data (3-byte pattern)
73- Byte 0: Sprite ID (0x00-0xFF)
74- Byte 1: X position in room
75- Byte 2: Y position in room
76- Example: "09 48 56" = Sprite 0x09 at (72, 86)
78### Tile16 Structure (8 bytes)
79- Bytes 0-1: Top-left tile8
80- Bytes 2-3: Top-right tile8
81- Bytes 4-5: Bottom-left tile8
82- Bytes 6-7: Bottom-right tile8
83- Format: tile8_id (lower byte) + properties (upper byte)
85### Pointers (Little Endian)
86- 2-byte pointer: Low byte first, high byte second
87- Example: "00 1C" = 0x1C00 (address 0x001C00)
88- SNES addressing: Add bank byte for 24-bit
92### Finding Unused Space
93- Pattern: "FF FF FF FF" (often unused)
94- Pattern: "00 00 00 00" (zeroed regions)
96### Finding Sprite Definitions
97- Search for known sprite IDs
98- Look for X/Y coordinate patterns (0x00-0x1F typical range)
100### Finding Compressed Data
101- Look for compression headers (0xE0-0xFF often signify compression)
102- Data density changes (sparse vs dense byte values)
108# Map Editing Workflow with Test Harness
110## Tile Placement Flow
1111. Parse natural language: "Place water tile at (5, 7)\"
113 a. overworld-find-tile to get water tile ID
114 b. Calculate screen coordinates from game coords
115 c. Generate GUI action: Click(overworld_canvas, x, y)
116 d. Generate GUI action: SelectTile(tile_id)
117 e. Generate GUI action: Click(target_x, target_y)
120- Game coords: Tile-based (0-31 for 32x32 map)
121- Screen coords: Pixel-based, depends on zoom/scroll
122- Conversion: screen_x = game_x * tile_size * zoom + canvas_offset_x
124## GUI Automation Best Practices
125- Always wait for UI updates (Wait(100ms) between actions)
126- Assert widget states before clicking
127- Screenshot before/after for verification
128- Use widget discovery to find exact IDs
130## Proposal System Integration
131- Read-only tools: Execute directly
132- Write operations: Submit as proposal first
133- Wait for approval before proceeding
134- Show user what will change (diff view)
140# Tool Usage Examples & Chaining
142## Example 1: Find and Analyze Sprites
143User: "What enemies are in Hyrule Castle?"
1451. resource-search --type=dungeon --query=hyrule
1462. dungeon-list-sprites --dungeon=hyrule_castle
1473. resource-list --type=sprite (to get sprite names)
148Result: "Hyrule Castle (dungeon 0) has 3 guards (sprite 0x41), 2 knights..."
150## Example 2: Palette Investigation
151User: "What colors are used for grass?"
1531. overworld-find-tile --tile_id=0x20 (grass tile)
1542. palette-get-colors --group=0 --palette=0
1553. palette-analyze --type=palette --id=0/0
156Result: "Grass uses palette 0/0 with colors: light green #98FB98..."
158## Example 3: Hex Pattern Search
159User: "Find all chests in the ROM"
1611. hex-search --pattern="20 ?? ??" (chest object code 0x20)
1622. For each match, hex-read context bytes
1633. Parse room numbers from addresses
164Result: "Found 50 chests across 30 rooms..."
166## Example 4: Complex Edit Planning
167User: "Add a new enemy to room 5"
1691. dungeon-describe-room --room_id=5 (check current sprites)
1702. resource-list --type=sprite (available enemies)
1713. todo-create --title="Add sprite to room 5" --steps="find_sprite,get_coords,write_data"
1724. hex-read --address=<room_5_sprite_addr> (check free slots)
1735. Submit proposal with hex-write
178 std::string prompt = "# Agent Pre-Training Session\n\n";
179 prompt +=
"You are being initialized with deep knowledge about this ROM.\n\n";
182 prompt += absl::StrFormat(
"## Current ROM: %s\n",
rom->
title());
183 prompt += absl::StrFormat(
"Size: %zu bytes\n",
rom->
size());
189 prompt += absl::StrFormat(
"## Module: %s\n", module.name);
190 prompt +=
module.content;
191 prompt +=
"\n---\n\n";
195## Your Capabilities After Training
198✓ ROM memory layout and addressing
199✓ How to chain tools for complex analysis
200✓ Hex pattern recognition and data structures
201✓ GUI automation for map editing
202✓ Proposal system for safe ROM modification
204**Test your knowledge**: When I ask about sprites, dungeons, or tiles,
205use multiple tools in one response to give comprehensive answers.
static std::vector< KnowledgeModule > GetModules()
Load all pre-training modules.
static std::string GetHexAnalysisKnowledge()
Get hex data analysis patterns.
static std::string GetToolUsageExamples()
Get tool usage examples.
static std::string GeneratePretrainingPrompt(Rom *rom)
Generate pre-training prompt for agent.
static std::string GetMapEditingKnowledge()
Get map editing workflow.
static std::string GetRomStructureKnowledge(Rom *rom)
Get ROM structure explanation.
Rom * rom()
Get the current ROM instance.