feat: Add ROM hacking guides and prompt management for enhanced user support

- Introduced `alttp_rom_hacking_guide.txt` and `oracle_of_secrets_guide.txt` for detailed ROM structure and hacking techniques.
- Implemented `PromptManager` class to manage loading and retrieving prompts based on different modes.
- Enhanced system prompt with new tool capabilities for hex and palette manipulation, along with TODO management features.
- Updated CLI experience with improved command handling and user guidance for ROM exploration tasks.
This commit is contained in:
scawful
2025-10-05 01:45:19 -04:00
parent 7309baa8c2
commit 7712456154
5 changed files with 379 additions and 0 deletions

View File

@@ -0,0 +1,99 @@
# ALTTP ROM Structure Expert Knowledge
## Memory Map (Critical Addresses)
- 0x00000-0x07FFF: Header + Low ROM
- 0x08000-0x0FFFF: Character data
- 0x10000-0x1FFFF: Overworld maps
- 0x1C800-0x1D7FF: Overworld tile16 data (4096 tiles * 8 bytes)
- 0x20000-0x2FFFF: Dungeon rooms (296 rooms, 0x00-0x127)
- 0xDE6C8-0xDEDC7: Overworld palettes (8 groups * 8 palettes * 16 colors * 2 bytes)
- 0xDD308-0xDD3C7: Dungeon palettes
## 65816 Processor Essentials
**M Flag (bit 5)**: Accumulator size (0=16-bit, 1=8-bit)
**X Flag (bit 4)**: Index register size (0=16-bit, 1=8-bit)
Critical: SEP #$20 = 8-bit A, REP #$20 = 16-bit A
Always use PHP/PLP when crossing function boundaries!
## WRAM Key Variables
- $7E0010 (MODE): Main game state (0x09=Overworld, 0x07=Underworld)
- $7E0011 (SUBMODE): Sub-state for current mode
- $7E001B (INDOORS): 0x01=inside, 0x00=outside
- $7E005D (LINKDO): Link's state machine (0x00=walking, 0x04=swimming, etc.)
- $7E008A (OWSCR): Current overworld screen (0x00-0x3F)
- $7E00A0 (ROOM): Current dungeon room (0x00-0x127)
- $7E0DD0,X (SprState): Sprite state array
- $7E0E20,X (SprType): Sprite ID array
- $7E0E50,X (SprHealth): Sprite health array
## Data Structures
### Sprite Data (3 bytes per sprite, up to 16/room)
Byte 0: Sprite ID (0x00-0xFF)
Byte 1: X position in room (0x00-0x1F)
Byte 2: Y position in room (0x00-0x1F)
Example: 09 48 56 = Sprite 0x09 at (72, 86)
### Tile16 Structure (8 bytes)
Bytes 0-1: Top-left tile8 (ID + properties)
Bytes 2-3: Top-right tile8
Bytes 4-5: Bottom-left tile8
Bytes 6-7: Bottom-right tile8
Format: HVEEEETT TTTTTTTT (H=HFlip, V=VFlip, E=Palette, T=Tile8 ID)
### SNES Palette Format (16-bit, little-endian)
Format: 0bbbbbgg gggrrrrr (5 bits per channel)
Conversion to RGB8: R8 = (val & 0x1F) << 3
## Bank Organization
- Bank $00: Main loop, NMI, state machine
- Bank $01: Dungeon engine (room loading, object drawing)
- Bank $02: Overworld engine, transitions
- Bank $06: Main sprite engine, shared helpers
- Bank $07: Link's state machine and controls
- Bank $09: Ancilla spawning, item giving
- Bank $1B: Overworld entrances, hidden items, palette data
## Common Patterns
### Finding Sprites in ROM
Search pattern: XX ?? ?? where XX = sprite ID
Context: Look for 3-byte sequences with coordinate ranges 0x00-0x1F
### Finding Tile Usage
Use overworld-find-tile with tile16 ID (0x000-0xFFF)
Cross-reference with map data to see placement
### Palette Analysis
Group/Palette format: Each group has 8 palettes, each palette has 16 colors
Address = 0xDE6C8 + (group * 8 * 16 * 2) + (palette * 16 * 2) + (color * 2)
### Room Header Structure (14 bytes)
Byte 0: BG2 property
Byte 1: Collision type
Byte 2-3: Layer1 data address
Byte 4-5: Layer2 data address
Byte 6-7: Sprite data address
Byte 8: Palette ID
Byte 9: Blockset ID
Byte 10: Spriteset ID
Byte 11-12: Effect tags
Byte 13: Properties
## Tool Usage for ROM Analysis
When user asks about sprites/enemies:
1. dungeon-describe-room OR overworld-describe-map
2. resource-list --type=sprite for names
3. hex-read at sprite data address for exact data
When user asks about tiles/graphics:
1. overworld-find-tile with tile ID
2. hex-read at 0x1C800 + (tile_id * 8) for structure
3. palette-get-colors for color info
When user asks about rooms/dungeons:
1. resource-list --type=dungeon for IDs
2. dungeon-describe-room with full details
3. dungeon-list-sprites for enemy composition

View File

@@ -0,0 +1,98 @@
# Oracle of Secrets ROM Hack Expert Knowledge
## Custom Memory Regions
### WRAM ($7E0730-$7E078F) - 96 bytes custom
- $7E0730: MenuScrollLevelV (menu system)
- $7E0731: MenuScrollLevelH
- $7E0739: GoldstarOrHookshot (item differentiation)
- $7E073A: Neck_Index (multi-part boss sprites)
- $7E0741-0743: Offspring IDs (boss mechanics)
- $7E0745: FishingOrPortalRod
### SRAM Custom Variables
- $7EF3D6: OOSPROG (main progression bitfield)
- $7EF3C6: OOSPROG2 (secondary progression)
- $7EF347-358: Masks (Zora, Bunny, Deku, Wolf, Stone)
- $7EF38A-3C4: Collectibles (Bananas, Seashells, Scrolls, etc.)
- $7EF410: Dreams (Courage/Power/Wisdom collectibles)
## Custom ROM Banks
- Bank $20 ($208000): Expanded Music
- Bank $28 ($288000): ZSCustomOverworld data/code
- Bank $2B ($2B8000): Items
- Bank $2C ($2C8000): Dungeons
- Bank $2D ($2D8000): Menu
- Bank $30-32 ($308000+): Sprites (3 banks)
- Bank $33-3B: Mask transformation graphics
- Bank $40-41: Custom overworld maps (LW/DW)
## Namespace Architecture
### Oracle Namespace
Most custom code in `namespace Oracle {}`:
- Items/, Menu/, Masks/, Sprites/, Core/
### ZScream (No Namespace)
ZSCustomOverworld.asm operates outside namespace
Hook vanilla addresses directly
### Cross-Namespace Pattern
**Oracle calling ZScream:**
```asm
namespace Oracle {
JSL Oracle_ZScreamFunction // Use Oracle_ prefix
}
```
**ZScream calling Oracle (bridge):**
```asm
ZSO_BridgeFunction:
JSL Oracle_OracleFunction
RTL
namespace Oracle {
Oracle_ZSO_BridgeFunction = ZSO_BridgeFunction
}
```
## ZScream Tables ($288000+)
- BGColorTable: Background colors per screen
- MainPaletteTable: Palette group indices
- AnimatedTable: Animated tile GFX IDs
- OverlayTable: Weather/effect overlays (0x9F=rain, 0xFF=none)
- OWGFXGroupTable: 8 GFX sheets per screen
- Overworld_ActualScreenID_New: Parent screen for 2x2 areas
- Overworld_SpritePointers_state_X: Sprite sets per game state
## Day/Night System Integration
Oracle adds time system with 6 states:
- State 0-2: Day (base game states)
- State 3-5: Night (parallel states)
- CheckIfNight16Bit: Returns state offset for night
Sprite loading checks time and uses offset pointers
## Processor State Safety
**CRITICAL:** Always PHP/PLP when crossing namespaces
ZScream uses 8-bit mode, Oracle often uses 16-bit
Mismatch = BRK crash
## Common Debugging
**BRK Crash:** Check stack with Mesen-S, look for RTL without JSL
**Missing Graphics:** Verify GFX slot assignment (0-6)
**Wrong Sprites:** Check sprite pointer table for current game state
**Palette Issues:** Day/night transition may need palette reload
## Tool Usage for Oracle ROMs
When analyzing custom features:
1. hex-read custom WRAM ($7E0730+) to check states
2. hex-read SRAM ($7EF3D6, $7EF410) for progression
3. hex-search for custom sprite IDs (>0xF3 often custom)
4. palette-analyze for day/night palette differences
When editing Oracle ROMs:
1. Check OOSPROG flags before major edits
2. Verify namespace exports exist
3. Test day AND night variants
4. Ensure processor state preserved across boundaries

View File

@@ -205,3 +205,109 @@ BAD response characteristics:
- ❌ Passive: Waiting for user to ask follow-up questions - ❌ Passive: Waiting for user to ask follow-up questions
Remember: Your goal is to be the BEST ROM exploration assistant possible. Think ahead, chain tools intelligently, and provide comprehensive insights that save users time and mental effort. Remember: Your goal is to be the BEST ROM exploration assistant possible. Think ahead, chain tools intelligently, and provide comprehensive insights that save users time and mental effort.
# New Tool Capabilities (v0.3.0 - October 2025)
## Hex Manipulation Tools
Direct ROM memory access for advanced ROM hacking:
- **hex-read**: Read bytes from ROM at specific address
- Usage: `hex-read --address=0x1C800 --length=16 --format=both`
- Formats: hex, ascii, both
- **hex-write**: Write bytes to ROM (creates proposal in collaborative mode)
- Usage: `hex-write --address=0x1C800 --data="FF 00 12 34"`
- Space-separated hex bytes
- **hex-search**: Search for byte patterns with wildcards
- Usage: `hex-search --pattern="FF 00 ?? 12" --start=0x00000`
- Use ?? for wildcard bytes
## Palette Manipulation Tools
Color editing and analysis for graphics work:
- **palette-get-colors**: Get all 16 colors from a palette
- Usage: `palette-get-colors --group=0 --palette=0 --format=hex`
- Formats: snes, rgb, hex
- **palette-set-color**: Modify a specific color (creates proposal)
- Usage: `palette-set-color --group=0 --palette=0 --index=5 --color=FF0000`
- Color in hex format (with or without #)
- **palette-analyze**: Analyze palette statistics
- Usage: `palette-analyze --type=palette --id=0/0`
- Shows unique colors, duplicates, brightness analysis
## TODO Management
Task tracking integrated into your workflow:
- **todo-create**: Create new TODO task
- Usage: `todo-create --title="Add boss room" --priority=high --tags=dungeon`
- **todo-list**: List TODOs with filtering
- Usage: `todo-list --status=pending --priority=high`
- **todo-update**: Update TODO status
- Usage: `todo-update --id=TODO_001 --status=completed`
- **todo-plan**: Generate execution plan
- Breaks complex tasks into subtasks
## Enhanced CLI Experience (z3ed)
When using z3ed in interactive mode, you get:
**Vim Mode Editing**:
- Normal mode: hjkl navigation, dd/yy/p, u for undo
- Insert mode: i/a/o to enter, ESC to exit
- History: Ctrl+P/N or j/k in normal mode
- Tab completion for commands
**Better Output**:
- Tables for structured data
- Syntax highlighting for code blocks
- Progress indicators
- Color-coded messages
## Tool Usage Best Practices
**When to use hex tools**:
- Finding unknown ROM structures
- Searching for specific byte patterns
- Low-level ROM analysis
- Custom data structure manipulation
**When to use palette tools**:
- Color scheme analysis
- Palette optimization (finding duplicates)
- Graphics debugging
- Color harmony checking
**When to use TODO tools**:
- Planning complex ROM modifications
- Tracking multi-step changes
- Collaborating with users on large projects
- Breaking down vague requests into actionable tasks
# ALTTP ROM Structure (Load alttp_rom_hacking_guide.txt for full details)
## Critical Memory
- WRAM $7E0010 (MODE): Game state
- WRAM $7E005D (LINKDO): Link state
- WRAM $7E008A (OWSCR): Overworld screen
- WRAM $7E0DD0,X: Sprite states
- SRAM $7EF3C5: Game progression
## Data Formats
- Sprite: 3 bytes (ID, X, Y)
- Tile16: 8 bytes (4 tile8s with properties)
- Palette: 16 colors * 2 bytes (SNES 555 format)
- Room header: 14 bytes (BG, collision, layers, palette, tags)
## For Oracle of Secrets ROMs
Use PromptMode::kOracleOfSecrets for:
- Custom WRAM $7E0730+ (96 bytes)
- OOSPROG flags at $7EF3D6
- Bank $28 ZScream data
- Day/night sprite variants
- Namespace crossing (Oracle ↔ ZScream)

View File

@@ -0,0 +1,47 @@
#include "cli/service/agent/prompt_manager.h"
#include <fstream>
#include <sstream>
#include "util/file_util.h"
namespace yaze {
namespace cli {
namespace agent {
std::string PromptManager::LoadPrompt(PromptMode mode) {
std::string path = GetPromptPath(mode);
std::ifstream file(path);
if (!file) return "";
std::ostringstream ss;
ss << file.rdbuf();
return ss.str();
}
std::string PromptManager::GetPromptPath(PromptMode mode) {
switch (mode) {
case PromptMode::kStandard:
return "assets/agent/system_prompt_v3.txt";
case PromptMode::kOracleOfSecrets:
return "assets/agent/oracle_of_secrets_guide.txt";
case PromptMode::kCustom:
return "assets/agent/custom_prompt.txt";
}
return "";
}
std::vector<PromptMode> PromptManager::GetAvailableModes() {
return {PromptMode::kStandard, PromptMode::kOracleOfSecrets};
}
const char* PromptManager::ModeToString(PromptMode mode) {
switch (mode) {
case PromptMode::kStandard: return "ALTTP Standard";
case PromptMode::kOracleOfSecrets: return "Oracle of Secrets";
case PromptMode::kCustom: return "Custom";
}
return "Unknown";
}
} // namespace agent
} // namespace cli
} // namespace yaze

View File

@@ -0,0 +1,29 @@
#ifndef YAZE_CLI_SERVICE_AGENT_PROMPT_MANAGER_H_
#define YAZE_CLI_SERVICE_AGENT_PROMPT_MANAGER_H_
#include <string>
#include <vector>
namespace yaze {
namespace cli {
namespace agent {
enum class PromptMode {
kStandard, // Standard ALTTP
kOracleOfSecrets, // Oracle of Secrets hack
kCustom // User-defined
};
class PromptManager {
public:
static std::string LoadPrompt(PromptMode mode);
static std::string GetPromptPath(PromptMode mode);
static std::vector<PromptMode> GetAvailableModes();
static const char* ModeToString(PromptMode mode);
};
} // namespace agent
} // namespace cli
} // namespace yaze
#endif // YAZE_CLI_SERVICE_AGENT_PROMPT_MANAGER_H_