backend-infra-engineer: Release v0.3.9-hotfix7 snapshot
This commit is contained in:
328
docs/internal/plans/CLAUDE_TEST_HANDOFF.md
Normal file
328
docs/internal/plans/CLAUDE_TEST_HANDOFF.md
Normal file
@@ -0,0 +1,328 @@
|
||||
# Claude Test Handoff Document
|
||||
|
||||
**Date**: 2024-11-22
|
||||
**Prepared by**: Claude (Sonnet 4.5)
|
||||
**Previous agents**: Gemini 3, Claude 4.5 (build fixes)
|
||||
**Status**: Build passing, ready for testing
|
||||
|
||||
## TL;DR
|
||||
|
||||
All 6 feature branches from Gemini3's work have been merged to master and build issues are resolved. The codebase needs comprehensive testing across multiple areas: Overworld fixes, Dungeon E2E tests, Agent UI improvements, CI infrastructure, and debugger/disassembler features.
|
||||
|
||||
## Current State
|
||||
|
||||
```
|
||||
Commit: ed980625d7 fix: resolve build errors from Gemini3 handoff
|
||||
Branch: master (13 commits ahead of origin)
|
||||
Build: PASSING (mac-dbg preset)
|
||||
```
|
||||
|
||||
### Merged Branches (in order)
|
||||
1. `infra/ci-test-overhaul` - CI/CD and test infrastructure
|
||||
2. `test/e2e-dungeon-coverage` - Dungeon editor E2E tests
|
||||
3. `feature/agent-ui-improvements` - Agent UI and dev tools
|
||||
4. `fix/overworld-logic` - Overworld test fixes
|
||||
5. `chore/misc-cleanup` - Documentation and cleanup
|
||||
6. `feature/debugger-disassembler` - Debugger and disassembler support
|
||||
|
||||
### Build Fixes Applied
|
||||
- Added `memory_inspector_tool.cc` to `agent.cmake` (was missing, caused vtable linker errors)
|
||||
- Fixed API mismatches in `memory_inspector_tool.cc`:
|
||||
- `GetArg()` → `GetString().value_or()`
|
||||
- `OutputMap()`/`OutputTable()` → `BeginObject()`/`AddField()`/`EndObject()` pattern
|
||||
|
||||
---
|
||||
|
||||
## Testing Areas
|
||||
|
||||
### 1. Overworld Fixes (`fix/overworld-logic`)
|
||||
|
||||
**Files Changed**:
|
||||
- `test/integration/zelda3/overworld_integration_test.cc`
|
||||
- `test/unit/zelda3/overworld_test.cc`
|
||||
|
||||
**Test Commands**:
|
||||
```bash
|
||||
# Run overworld tests
|
||||
ctest --test-dir build -R "overworld" --output-on-failure
|
||||
|
||||
# Specific test binaries
|
||||
./build/bin/Debug/yaze_test_stable --gtest_filter="*Overworld*"
|
||||
```
|
||||
|
||||
**What to Verify**:
|
||||
- [ ] Overworld unit tests pass
|
||||
- [ ] Overworld integration tests pass
|
||||
- [ ] No regressions in overworld map loading
|
||||
- [ ] Multi-area map configuration works correctly
|
||||
|
||||
**Manual Testing**:
|
||||
```bash
|
||||
./build/bin/Debug/yaze.app/Contents/MacOS/yaze --rom_file=<path_to_rom> --editor=Overworld
|
||||
```
|
||||
- Load a ROM and verify overworld renders correctly
|
||||
- Test map switching between Light World, Dark World, Special areas
|
||||
- Verify entity visibility (entrances, exits, items, sprites)
|
||||
|
||||
---
|
||||
|
||||
### 2. Dungeon E2E Tests (`test/e2e-dungeon-coverage`)
|
||||
|
||||
**New Test Files**:
|
||||
| File | Purpose |
|
||||
|------|---------|
|
||||
| `dungeon_canvas_interaction_test.cc/.h` | Canvas click/drag tests |
|
||||
| `dungeon_e2e_tests.cc/.h` | Full workflow E2E tests |
|
||||
| `dungeon_layer_rendering_test.cc/.h` | Layer visibility tests |
|
||||
| `dungeon_object_drawing_test.cc/.h` | Object rendering tests |
|
||||
| `dungeon_visual_verification_test.cc/.h` | Visual regression tests |
|
||||
|
||||
**Test Commands**:
|
||||
```bash
|
||||
# Run all dungeon tests
|
||||
ctest --test-dir build -R "dungeon" -L stable --output-on-failure
|
||||
|
||||
# Run dungeon E2E specifically
|
||||
ctest --test-dir build -R "dungeon_e2e" --output-on-failure
|
||||
|
||||
# GUI tests (requires display)
|
||||
./build/bin/Debug/yaze_test_gui --gtest_filter="*Dungeon*"
|
||||
```
|
||||
|
||||
**What to Verify**:
|
||||
- [ ] All new dungeon test files compile
|
||||
- [ ] Canvas interaction tests pass
|
||||
- [ ] Layer rendering tests pass
|
||||
- [ ] Object drawing tests pass
|
||||
- [ ] Visual verification tests pass (may need baseline images)
|
||||
- [ ] Integration tests with ROM pass (if ROM available)
|
||||
|
||||
**Manual Testing**:
|
||||
```bash
|
||||
./build/bin/Debug/yaze.app/Contents/MacOS/yaze --rom_file=<path_to_rom> --editor=Dungeon
|
||||
```
|
||||
- Load dungeon rooms and verify rendering
|
||||
- Test object selection and manipulation
|
||||
- Verify layer toggling works
|
||||
- Check room switching
|
||||
|
||||
---
|
||||
|
||||
### 3. Agent UI Improvements (`feature/agent-ui-improvements`)
|
||||
|
||||
**Key Files**:
|
||||
| File | Purpose |
|
||||
|------|---------|
|
||||
| `src/cli/service/agent/dev_assist_agent.cc/.h` | Dev assistance agent |
|
||||
| `src/cli/service/agent/tools/build_tool.cc/.h` | Build system integration |
|
||||
| `src/cli/service/agent/tools/filesystem_tool.cc/.h` | File operations |
|
||||
| `src/cli/service/agent/tools/memory_inspector_tool.cc/.h` | Memory debugging |
|
||||
| `src/app/editor/agent/agent_editor.cc` | Agent editor UI |
|
||||
|
||||
**Test Commands**:
|
||||
```bash
|
||||
# Run agent-related tests
|
||||
ctest --test-dir build -R "tool_dispatcher" --output-on-failure
|
||||
ctest --test-dir build -R "agent" --output-on-failure
|
||||
|
||||
# Test z3ed CLI
|
||||
./build/bin/Debug/z3ed --help
|
||||
./build/bin/Debug/z3ed memory regions
|
||||
./build/bin/Debug/z3ed memory analyze 0x7E0000
|
||||
```
|
||||
|
||||
**What to Verify**:
|
||||
- [ ] Tool dispatcher tests pass
|
||||
- [ ] Memory inspector tools work:
|
||||
- `memory regions` - lists known ALTTP memory regions
|
||||
- `memory analyze <addr>` - analyzes memory at address
|
||||
- `memory search <pattern>` - searches for patterns
|
||||
- `memory compare <addr>` - compares memory values
|
||||
- `memory check [region]` - checks for anomalies
|
||||
- [ ] Build tool integration works
|
||||
- [ ] Filesystem tool operations work
|
||||
- [ ] Agent editor UI renders correctly
|
||||
|
||||
**Manual Testing**:
|
||||
```bash
|
||||
./build/bin/Debug/yaze.app/Contents/MacOS/yaze --rom_file=<path_to_rom> --editor=Agent
|
||||
```
|
||||
- Open Agent editor and verify chat UI
|
||||
- Test proposal drawer functionality
|
||||
- Verify theme colors are consistent (no hardcoded colors)
|
||||
|
||||
---
|
||||
|
||||
### 4. CI Infrastructure (`infra/ci-test-overhaul`)
|
||||
|
||||
**Key Files**:
|
||||
- `.github/workflows/ci.yml` - Main CI workflow
|
||||
- `.github/workflows/release.yml` - Release workflow
|
||||
- `.github/workflows/nightly.yml` - Nightly builds (NEW)
|
||||
- `test/test.cmake` - Test configuration
|
||||
- `test/README.md` - Test documentation
|
||||
|
||||
**What to Verify**:
|
||||
- [ ] CI workflow YAML is valid:
|
||||
```bash
|
||||
python3 -c "import yaml; yaml.safe_load(open('.github/workflows/ci.yml'))"
|
||||
python3 -c "import yaml; yaml.safe_load(open('.github/workflows/nightly.yml'))"
|
||||
```
|
||||
- [ ] Test labels work correctly:
|
||||
```bash
|
||||
ctest --test-dir build -L stable -N # List stable tests
|
||||
ctest --test-dir build -L unit -N # List unit tests
|
||||
```
|
||||
- [ ] Documentation is accurate in `test/README.md`
|
||||
|
||||
---
|
||||
|
||||
### 5. Debugger/Disassembler (`feature/debugger-disassembler`)
|
||||
|
||||
**Key Files**:
|
||||
- `src/cli/service/agent/disassembler_65816.cc`
|
||||
- `src/cli/service/agent/rom_debug_agent.cc`
|
||||
- `src/app/emu/debug/` - Emulator debug components
|
||||
|
||||
**Test Commands**:
|
||||
```bash
|
||||
# Test disassembler
|
||||
ctest --test-dir build -R "disassembler" --output-on-failure
|
||||
|
||||
# Manual disassembly test (requires ROM)
|
||||
./build/bin/Debug/z3ed disasm <rom_file> 0x008000 20
|
||||
```
|
||||
|
||||
**What to Verify**:
|
||||
- [ ] 65816 disassembler produces correct output
|
||||
- [ ] ROM debug agent works
|
||||
- [ ] Emulator stepping (if integrated)
|
||||
|
||||
---
|
||||
|
||||
## Quick Test Matrix
|
||||
|
||||
| Area | Unit Tests | Integration | E2E/GUI | Manual |
|
||||
|------|------------|-------------|---------|--------|
|
||||
| Overworld | `overworld_test` | `overworld_integration_test` | - | Open editor |
|
||||
| Dungeon | `object_rendering_test` | `dungeon_room_test` | `dungeon_e2e_tests` | Open editor |
|
||||
| Agent Tools | `tool_dispatcher_test` | - | - | z3ed CLI |
|
||||
| Memory Inspector | - | - | - | z3ed memory * |
|
||||
| Disassembler | `disassembler_test` | - | - | z3ed disasm |
|
||||
|
||||
---
|
||||
|
||||
## Full Test Suite
|
||||
|
||||
```bash
|
||||
# Quick smoke test (stable only, ~2 min)
|
||||
ctest --test-dir build -L stable -j4 --output-on-failure
|
||||
|
||||
# All tests (may take longer)
|
||||
ctest --test-dir build --output-on-failure
|
||||
|
||||
# ROM-dependent tests (if ROM available)
|
||||
cmake --preset mac-dbg -DYAZE_ENABLE_ROM_TESTS=ON -DYAZE_TEST_ROM_PATH=~/zelda3.sfc
|
||||
ctest --test-dir build -L rom_dependent --output-on-failure
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Known Issues / Watch For
|
||||
|
||||
1. **Linker warnings**: You may see warnings about duplicate libraries during linking - these are benign warnings, not errors.
|
||||
|
||||
2. **third_party/ directory**: There's an untracked `third_party/` directory that needs a decision:
|
||||
- Should it be added to `.gitignore`?
|
||||
- Should it be a git submodule?
|
||||
- For now, leave it untracked.
|
||||
|
||||
3. **Visual tests**: Some dungeon visual verification tests may fail if baseline images don't exist yet. These tests should generate baselines on first run.
|
||||
|
||||
4. **GUI tests**: Tests with `-L gui` require a display. On headless CI, these may need to be skipped or run with Xvfb.
|
||||
|
||||
5. **gRPC tests**: Some agent features require gRPC. Ensure `YAZE_ENABLE_REMOTE_AUTOMATION` is ON if testing those.
|
||||
|
||||
---
|
||||
|
||||
## Recommended Test Order
|
||||
|
||||
1. **First**: Run stable unit tests to catch obvious issues
|
||||
```bash
|
||||
ctest --test-dir build -L stable -L unit -j4
|
||||
```
|
||||
|
||||
2. **Second**: Run integration tests
|
||||
```bash
|
||||
ctest --test-dir build -L stable -L integration -j4
|
||||
```
|
||||
|
||||
3. **Third**: Manual testing of key editors (Overworld, Dungeon, Agent)
|
||||
|
||||
4. **Fourth**: E2E/GUI tests if display available
|
||||
```bash
|
||||
./build/bin/Debug/yaze_test_gui
|
||||
```
|
||||
|
||||
5. **Fifth**: Full test suite
|
||||
```bash
|
||||
ctest --test-dir build --output-on-failure
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Build Commands Reference
|
||||
|
||||
```bash
|
||||
# Configure (if needed)
|
||||
cmake --preset mac-dbg
|
||||
|
||||
# Build main executable
|
||||
cmake --build build --target yaze -j4
|
||||
|
||||
# Build all (including tests)
|
||||
cmake --build build -j4
|
||||
|
||||
# Build specific test binary
|
||||
cmake --build build --target yaze_test_stable -j4
|
||||
cmake --build build --target yaze_test_gui -j4
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Files Modified in Final Fix Commit
|
||||
|
||||
For reference, these files were modified in `ed980625d7`:
|
||||
|
||||
| File | Change |
|
||||
|------|--------|
|
||||
| `assets/asm/usdasm` | Submodule pointer update |
|
||||
| `src/app/editor/agent/agent_editor.cc` | Gemini3's UI changes |
|
||||
| `src/app/gui/style/theme.h` | Theme additions |
|
||||
| `src/cli/agent.cmake` | Added memory_inspector_tool.cc |
|
||||
| `src/cli/service/agent/emulator_service_impl.h` | Gemini3's changes |
|
||||
| `src/cli/service/agent/rom_debug_agent.cc` | Gemini3's changes |
|
||||
| `src/cli/service/agent/tools/memory_inspector_tool.cc` | API fixes |
|
||||
| `src/protos/emulator_service.proto` | Gemini3's proto changes |
|
||||
|
||||
---
|
||||
|
||||
## Success Criteria
|
||||
|
||||
Testing is complete when:
|
||||
- [ ] All stable tests pass (`ctest -L stable`)
|
||||
- [ ] No regressions in Overworld editor
|
||||
- [ ] No regressions in Dungeon editor
|
||||
- [ ] Agent tools respond correctly to CLI commands
|
||||
- [ ] Build succeeds on all platforms (via CI)
|
||||
|
||||
---
|
||||
|
||||
## Contact / Escalation
|
||||
|
||||
If you encounter issues:
|
||||
1. Check `docs/BUILD-TROUBLESHOOTING.md` for common fixes
|
||||
2. Review `GEMINI3_HANDOFF.md` for context on the original work
|
||||
3. Check git log for related commits: `git log --oneline -20`
|
||||
|
||||
Good luck with testing!
|
||||
752
docs/internal/plans/EDITOR_ROADMAPS_2025-11.md
Normal file
752
docs/internal/plans/EDITOR_ROADMAPS_2025-11.md
Normal file
@@ -0,0 +1,752 @@
|
||||
# Editor Development Roadmaps - November 2025
|
||||
|
||||
**Generated**: 2025-11-21 by Claude Code
|
||||
**Source**: Multi-agent analysis (5 specialized agents)
|
||||
**Scope**: Dungeon Editor, Overworld Editor, Message Editor, Testing Infrastructure
|
||||
|
||||
---
|
||||
|
||||
## 📊 Executive Summary
|
||||
|
||||
Based on comprehensive analysis by specialized agents, here are the strategic priorities for editor development:
|
||||
|
||||
### Current State Assessment
|
||||
|
||||
| Editor | Completion | Primary Gap | Est. Effort |
|
||||
|--------|-----------|-------------|-------------|
|
||||
| **Dungeon Editor** | 80% | Interaction wiring | 22-30 hours |
|
||||
| **Overworld Editor** | 95% | Theme compliance & undo/redo | 14-18 hours |
|
||||
| **Message Editor** | 70% | Translation features | 21 dev days |
|
||||
| **Testing Coverage** | 34% | Editor-specific tests | 4-6 weeks |
|
||||
|
||||
---
|
||||
|
||||
## 🎯 Dungeon Editor Roadmap
|
||||
|
||||
**Analysis**: imgui-frontend-engineer agent
|
||||
**Current State**: Solid architecture, component-based design, just needs interaction wiring
|
||||
|
||||
### Top 5 Milestones
|
||||
|
||||
#### **Milestone 1: Object Interaction Foundation** (4-6 hours)
|
||||
**Priority**: HIGHEST - Unlocks actual editing capability
|
||||
|
||||
**Tasks**:
|
||||
1. Wire object placement system
|
||||
- Complete `DrawObjectSelector()` with working preview
|
||||
- Connect `object_placed_callback_` in `DungeonObjectInteraction`
|
||||
- Implement `PlaceObjectAtPosition()` to write to room data
|
||||
- Add ghost preview when hovering with object selected
|
||||
|
||||
2. Complete object selection
|
||||
- Implement `CheckForObjectSelection()` with click/drag rectangle
|
||||
- Wire `DrawSelectionHighlights()` (high-contrast outline at 0.85f alpha)
|
||||
- Connect context menu to `HandleDeleteSelected()`
|
||||
- Add multi-select with Shift/Ctrl modifiers
|
||||
|
||||
3. Object drawing integration
|
||||
- Ensure `ObjectDrawer::DrawObjectList()` called during room rendering
|
||||
- Verify object outlines render with proper filtering
|
||||
- Add object info tooltip on hover (ID, size, coordinates)
|
||||
|
||||
4. Theme compliance audit
|
||||
- Replace all `IM_COL32()` calls with `AgentUI::GetTheme()` colors
|
||||
- Audit all dungeon editor files for hardcoded colors
|
||||
|
||||
**Files to Modify**:
|
||||
- `src/app/editor/dungeon/dungeon_object_selector.cc`
|
||||
- `src/app/editor/dungeon/dungeon_object_interaction.cc`
|
||||
- `src/app/editor/dungeon/dungeon_canvas_viewer.cc`
|
||||
- `src/app/editor/dungeon/dungeon_editor_v2.cc`
|
||||
|
||||
**Success Criteria**:
|
||||
- [ ] User can select object from selector panel
|
||||
- [ ] User can place object in room with mouse click
|
||||
- [ ] User can select placed objects (single + multi)
|
||||
- [ ] User can delete selected objects via context menu or Del key
|
||||
- [ ] Object tooltips show useful info on hover
|
||||
- [ ] No hardcoded colors remain
|
||||
|
||||
---
|
||||
|
||||
#### **Milestone 2: Clipboard Operations** (3-4 hours)
|
||||
**Priority**: Medium - Big productivity boost
|
||||
|
||||
**Tasks**:
|
||||
1. Implement copy/cut
|
||||
- Store selected objects in `clipboard_` vector
|
||||
- Serialize object properties (ID, position, size, layer)
|
||||
- Add "Copy" and "Cut" to context menu
|
||||
- Update status bar to show clipboard count
|
||||
|
||||
2. Implement paste
|
||||
- Deserialize clipboard data
|
||||
- Place objects at mouse cursor position (offset from original)
|
||||
- Support paste-with-drag for precise placement
|
||||
- Add "Paste" to context menu + Ctrl+V shortcut
|
||||
|
||||
3. Cross-room clipboard
|
||||
- Enable copying objects from one room and pasting into another
|
||||
- Handle blockset differences gracefully (warn if incompatible)
|
||||
- Persist clipboard across room switches
|
||||
|
||||
**Success Criteria**:
|
||||
- [ ] User can copy selected objects (Ctrl+C or context menu)
|
||||
- [ ] User can cut selected objects (Ctrl+X)
|
||||
- [ ] User can paste objects at cursor (Ctrl+V)
|
||||
- [ ] Paste works across different rooms
|
||||
- [ ] Clipboard persists across room tabs
|
||||
|
||||
---
|
||||
|
||||
#### **Milestone 3: Undo/Redo System** (5-7 hours)
|
||||
**Priority**: Medium - Professional editing experience
|
||||
|
||||
**Tasks**:
|
||||
1. Design command pattern
|
||||
- Create `DungeonEditorCommand` base class with `Execute()` / `Undo()` methods
|
||||
- Implement commands: `PlaceObjectCommand`, `DeleteObjectCommand`, `MoveObjectCommand`, `ModifyObjectCommand`
|
||||
- Add command stack (max 50 actions) with pruning
|
||||
|
||||
2. Integrate with object operations
|
||||
- Wrap all object modifications in commands
|
||||
- Push commands to history stack in `DungeonEditorV2`
|
||||
- Update UI to show "Undo: [action]" / "Redo: [action]" tooltips
|
||||
|
||||
3. Property edit undo
|
||||
- Track room property changes (blockset, palette, floor graphics)
|
||||
- Create `ModifyRoomPropertiesCommand` for batch edits
|
||||
- Handle graphics refresh on undo/redo
|
||||
|
||||
4. UI indicators
|
||||
- Gray out Undo/Redo menu items when unavailable
|
||||
- Add Ctrl+Z / Ctrl+Shift+Z keyboard shortcuts
|
||||
- Display undo history in optional panel (10 recent actions)
|
||||
|
||||
**Files to Create**:
|
||||
- `src/app/editor/dungeon/dungeon_command_history.h` (new file)
|
||||
|
||||
**Success Criteria**:
|
||||
- [ ] All object operations support undo/redo
|
||||
- [ ] Room property changes support undo/redo
|
||||
- [ ] Keyboard shortcuts work (Ctrl+Z, Ctrl+Shift+Z)
|
||||
- [ ] Undo history visible in debug panel
|
||||
- [ ] No memory leaks (command cleanup after stack pruning)
|
||||
|
||||
---
|
||||
|
||||
#### **Milestone 4: Object Properties Panel** (4-5 hours)
|
||||
**Priority**: Medium - Fine-tuned object customization
|
||||
|
||||
**Tasks**:
|
||||
1. Properties UI design
|
||||
- Create `ObjectPropertiesCard` (dockable, 300×400 default size)
|
||||
- Display selected object ID, coordinates, size, layer
|
||||
- Editable fields: X/Y position (hex input), size/length (numeric), layer (dropdown)
|
||||
- Show object preview thumbnail (64×64 pixels)
|
||||
|
||||
2. Live property updates
|
||||
- Changes to X/Y immediately move object on canvas
|
||||
- Changes to size/length trigger re-render via `ObjectDrawer`
|
||||
- Layer changes update object's BG assignment
|
||||
- Add "Apply" vs "Live Update" toggle for performance
|
||||
|
||||
3. Multi-selection properties
|
||||
- Show common properties when multiple objects selected
|
||||
- Support batch edit (move all selected by offset, change layer for all)
|
||||
- Display "Mixed" for differing values
|
||||
|
||||
4. Integration with ObjectEditorCard
|
||||
- Merge or coordinate with existing `ObjectEditorCard`
|
||||
- Decide if properties should be tab in unified card or separate panel
|
||||
- Follow OverworldEditor's pattern (separate MapPropertiesSystem)
|
||||
|
||||
**Files to Create**:
|
||||
- `src/app/editor/dungeon/object_properties_card.h` (new file)
|
||||
- `src/app/editor/dungeon/object_properties_card.cc` (new file)
|
||||
|
||||
**Success Criteria**:
|
||||
- [ ] Properties panel shows when object selected
|
||||
- [ ] All object properties editable (X, Y, size, layer)
|
||||
- [ ] Changes reflected immediately on canvas
|
||||
- [ ] Multi-selection batch edit works
|
||||
- [ ] Panel follows AgentUITheme standards
|
||||
|
||||
---
|
||||
|
||||
#### **Milestone 5: Enhanced Canvas Features** (6-8 hours)
|
||||
**Priority**: Lower - Quality-of-life improvements
|
||||
|
||||
**Tasks**:
|
||||
1. Object snapping
|
||||
- Snap to 8×8 grid when placing/moving objects
|
||||
- Snap to other objects' edges (magnetic guides)
|
||||
- Toggle snapping with Shift key
|
||||
- Visual guides (dotted lines) when snapping
|
||||
|
||||
2. Canvas navigation improvements
|
||||
- Minimap overlay (128×128 px) showing full room with viewport indicator
|
||||
- "Fit to Window" button to reset zoom/pan
|
||||
- Zoom to selection (fit selected objects in view)
|
||||
- Remember pan/zoom per room tab
|
||||
|
||||
3. Object filtering UI
|
||||
- Checkboxes for object type visibility (Type1, Type2, Type3)
|
||||
- Layer filter (show only BG1 objects, only BG2, etc.)
|
||||
- "Show All" / "Hide All" quick toggles
|
||||
- Filter state persists across rooms
|
||||
|
||||
4. Ruler/measurement tool
|
||||
- Click-drag to measure distance between two points
|
||||
- Display pixel distance + tile distance
|
||||
- Show angle for diagonal measurements
|
||||
|
||||
**Success Criteria**:
|
||||
- [ ] Object snapping works (grid + magnetic)
|
||||
- [ ] Minimap overlay functional
|
||||
- [ ] Object type/layer filtering works
|
||||
- [ ] Measurement tool usable
|
||||
- [ ] Canvas navigation smooth and intuitive
|
||||
|
||||
---
|
||||
|
||||
### Quick Wins (4 hours total)
|
||||
For immediate visible progress:
|
||||
1. **Theme compliance fixes** (1h) - Remove hardcoded colors
|
||||
2. **Object placement wiring** (2h) - Enable basic object placement
|
||||
3. **Object deletion** (1h) - Complete the basic edit loop
|
||||
|
||||
---
|
||||
|
||||
## 🎨 Overworld Editor Roadmap
|
||||
|
||||
**Analysis**: imgui-frontend-engineer agent
|
||||
**Current State**: Feature-complete but needs critical polish
|
||||
|
||||
### Top 5 Critical Fixes
|
||||
|
||||
#### **1. Eliminate All Hardcoded Colors** (4-6 hours)
|
||||
**Priority**: CRITICAL - Theme system violation
|
||||
|
||||
**Problem**: 22+ hardcoded `ImVec4` color instances, zero usage of `AgentUI::GetTheme()`
|
||||
|
||||
**Files Affected**:
|
||||
- `src/app/editor/overworld/map_properties.cc` (22 instances)
|
||||
- `src/app/editor/overworld/overworld_entity_renderer.cc` (entity colors)
|
||||
- `src/app/editor/overworld/overworld_editor.cc` (selector highlight)
|
||||
|
||||
**Required Fix**:
|
||||
```cpp
|
||||
// Add to AgentUITheme:
|
||||
ImVec4 entity_entrance_color; // Bright yellow-gold (0.85f alpha)
|
||||
ImVec4 entity_exit_color; // Cyan-white (0.85f alpha)
|
||||
ImVec4 entity_item_color; // Bright red (0.85f alpha)
|
||||
ImVec4 entity_sprite_color; // Bright magenta (0.85f alpha)
|
||||
ImVec4 status_info; // Info messages
|
||||
ImVec4 status_warning; // Warnings
|
||||
ImVec4 status_success; // Success messages
|
||||
|
||||
// Refactor all entity_renderer colors:
|
||||
const auto& theme = AgentUI::GetTheme();
|
||||
ImVec4 GetEntranceColor() { return theme.entity_entrance_color; }
|
||||
```
|
||||
|
||||
**Success Criteria**:
|
||||
- [ ] All hardcoded colors replaced with theme system
|
||||
- [ ] Entity colors follow visibility standards (0.85f alpha)
|
||||
- [ ] No `ImVec4` literals remain in overworld editor files
|
||||
|
||||
---
|
||||
|
||||
#### **2. Implement Undo/Redo System for Tile Editing** (6-8 hours)
|
||||
**Priority**: HIGH - #1 user frustration point
|
||||
|
||||
**Current State**:
|
||||
```cpp
|
||||
absl::Status Undo() override { return absl::UnimplementedError("Undo"); }
|
||||
absl::Status Redo() override { return absl::UnimplementedError("Redo"); }
|
||||
```
|
||||
|
||||
**Implementation Approach**:
|
||||
- Create command pattern stack for tile modifications
|
||||
- Track: `{map_id, x, y, old_tile16_id, new_tile16_id}`
|
||||
- Store up to 100 undo steps (configurable)
|
||||
- Batch consecutive paint strokes into single undo operation
|
||||
- Hook into existing `RenderUpdatedMapBitmap()` call sites
|
||||
- Add Ctrl+Z/Ctrl+Shift+Z keyboard shortcuts
|
||||
|
||||
**Success Criteria**:
|
||||
- [ ] Tile painting supports undo/redo
|
||||
- [ ] Keyboard shortcuts work (Ctrl+Z, Ctrl+Shift+Z)
|
||||
- [ ] Consecutive paint strokes batched into single undo
|
||||
- [ ] Undo stack limited to 100 actions
|
||||
- [ ] Graphics refresh correctly on undo/redo
|
||||
|
||||
---
|
||||
|
||||
#### **3. Complete OverworldItem Deletion Implementation** (2-3 hours)
|
||||
**Priority**: Medium - Data integrity issue
|
||||
|
||||
**Current Issue**:
|
||||
```cpp
|
||||
// entity.cc:319
|
||||
// TODO: Implement deleting OverworldItem objects, currently only hides them
|
||||
bool DrawItemEditorPopup(zelda3::OverworldItem& item) {
|
||||
```
|
||||
|
||||
**Problem**: Items marked as `deleted = true` but not actually removed from ROM data structures
|
||||
|
||||
**Required Fix**:
|
||||
- Implement proper deletion in `zelda3::Overworld::SaveItems()`
|
||||
- Compact the item array after deletion (remove deleted entries)
|
||||
- Update item indices for all remaining items
|
||||
- Add "Permanently Delete" vs "Hide" option in UI
|
||||
|
||||
**Files to Modify**:
|
||||
- `src/app/editor/overworld/entity.cc`
|
||||
- `src/zelda3/overworld/overworld.cc` (SaveItems method)
|
||||
|
||||
**Success Criteria**:
|
||||
- [ ] Deleted items removed from ROM data
|
||||
- [ ] Item array compacted after deletion
|
||||
- [ ] No ID conflicts when inserting new items
|
||||
- [ ] UI clearly distinguishes "Hide" vs "Delete"
|
||||
|
||||
---
|
||||
|
||||
#### **4. Remove TODO Comments for Deferred Texture Rendering** (30 minutes)
|
||||
**Priority**: Low - Code cleanliness
|
||||
|
||||
**Found 9 instances**:
|
||||
```cpp
|
||||
// TODO: Queue texture for later rendering.
|
||||
// Renderer::Get().UpdateBitmap(&tile16_blockset_.atlas);
|
||||
```
|
||||
|
||||
**Files Affected**:
|
||||
- `overworld_editor.cc` (6 instances)
|
||||
- `tile16_editor.cc` (3 instances)
|
||||
|
||||
**Required Fix**:
|
||||
- Remove all 9 TODO comments
|
||||
- Verify that `gfx::Arena` is handling these textures properly
|
||||
- If not, use: `gfx::Arena::Get().QueueDeferredTexture(bitmap, priority)`
|
||||
- Add documentation explaining why direct `UpdateBitmap()` calls were removed
|
||||
|
||||
**Success Criteria**:
|
||||
- [ ] All texture TODO comments removed
|
||||
- [ ] Texture queuing verified functional
|
||||
- [ ] Documentation added for future developers
|
||||
|
||||
---
|
||||
|
||||
#### **5. Polish Exit Editor - Implement Door Type Controls** (1 hour)
|
||||
**Priority**: Low - UX clarity
|
||||
|
||||
**Current State**:
|
||||
```cpp
|
||||
// entity.cc:216
|
||||
gui::TextWithSeparators("Unimplemented below");
|
||||
ImGui::RadioButton("None", &doorType, 0);
|
||||
ImGui::RadioButton("Wooden", &doorType, 1);
|
||||
ImGui::RadioButton("Bombable", &doorType, 2);
|
||||
```
|
||||
|
||||
**Problem**: Door type controls shown but marked "Unimplemented" - misleading to users
|
||||
|
||||
**Recommended Fix**: Remove the unimplemented door controls entirely
|
||||
```cpp
|
||||
ImGui::TextDisabled(ICON_MD_INFO " Door types are controlled by dungeon room properties");
|
||||
ImGui::TextWrapped("To configure entrance doors, use the Dungeon Editor.");
|
||||
```
|
||||
|
||||
**Success Criteria**:
|
||||
- [ ] Misleading unimplemented UI removed
|
||||
- [ ] Clear message explaining where door types are configured
|
||||
|
||||
---
|
||||
|
||||
## 💬 Message Editor Roadmap
|
||||
|
||||
**Analysis**: imgui-frontend-engineer agent
|
||||
**Current State**: Solid foundation, needs translation features
|
||||
|
||||
### Phased Implementation Plan
|
||||
|
||||
#### **Phase 1: JSON Export/Import** (Weeks 1-2, 6 dev days)
|
||||
**Priority**: HIGHEST - Foundation for all translation workflows
|
||||
|
||||
**Tasks**:
|
||||
1. Implement `SerializeMessages()` and `DeserializeMessages()`
|
||||
2. Add UI buttons for export/import
|
||||
3. Add CLI import support
|
||||
4. Write comprehensive tests
|
||||
|
||||
**Proposed JSON Schema**:
|
||||
```json
|
||||
{
|
||||
"version": "1.0",
|
||||
"rom_name": "Zelda3 US",
|
||||
"messages": [
|
||||
{
|
||||
"id": "0x01",
|
||||
"address": "0xE0000",
|
||||
"text": "Link rescued Zelda from Ganon.",
|
||||
"context": "Opening narration",
|
||||
"notes": "Translator: Keep under 40 characters",
|
||||
"modified": false
|
||||
}
|
||||
],
|
||||
"dictionary": [
|
||||
{"index": "0x00", "phrase": "Link"},
|
||||
{"index": "0x01", "phrase": "Zelda"}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
**Files to Modify**:
|
||||
- `src/app/editor/message/message_editor.h`
|
||||
- `src/app/editor/message/message_editor.cc`
|
||||
|
||||
**Success Criteria**:
|
||||
- [ ] JSON export creates valid schema
|
||||
- [ ] JSON import loads messages correctly
|
||||
- [ ] CLI supports `z3ed message export --format json`
|
||||
- [ ] Tests cover serialization/deserialization
|
||||
|
||||
---
|
||||
|
||||
#### **Phase 2: Translation Workspace** (Weeks 3-5, 9 dev days)
|
||||
**Priority**: High - Unlocks localization capability
|
||||
|
||||
**Tasks**:
|
||||
1. Create `TranslationWorkspace` class
|
||||
2. Side-by-side reference/translation view
|
||||
3. Progress tracking (X/396 completed)
|
||||
4. Context notes field for translators
|
||||
|
||||
**UI Mockup**:
|
||||
```
|
||||
┌────────────────────────────────────────────────────┐
|
||||
│ Translation Progress: 123/396 (31%) │
|
||||
├────────────────────────────────────────────────────┤
|
||||
│ Reference (English) │ Translation (Spanish) │
|
||||
├───────────────────────┼───────────────────────────┤
|
||||
│ Link rescued Zelda │ Link rescató a Zelda │
|
||||
│ from Ganon. │ de Ganon. │
|
||||
│ │ │
|
||||
│ Context: Opening │ Notes: Keep dramatic tone │
|
||||
├───────────────────────┴───────────────────────────┤
|
||||
│ [Previous] [Mark Complete] [Save] [Next] │
|
||||
└────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
**Files to Create**:
|
||||
- `src/app/editor/message/translation_workspace.h` (new file)
|
||||
- `src/app/editor/message/translation_workspace.cc` (new file)
|
||||
|
||||
**Success Criteria**:
|
||||
- [ ] Side-by-side view displays reference and translation
|
||||
- [ ] Progress tracker updates as messages marked complete
|
||||
- [ ] Context notes persist with message data
|
||||
- [ ] Navigation between messages smooth
|
||||
|
||||
---
|
||||
|
||||
#### **Phase 3: Search & Replace** (Week 6, 4 dev days)
|
||||
**Priority**: Medium - QoL improvement
|
||||
|
||||
**Tasks**:
|
||||
1. Complete the Find/Replace implementation
|
||||
2. Add batch operations
|
||||
3. Optional: Add regex support
|
||||
|
||||
**Success Criteria**:
|
||||
- [ ] Global search across all messages
|
||||
- [ ] Batch replace (e.g., "Hyrule" → "Lorule")
|
||||
- [ ] Search highlights matches in message list
|
||||
- [ ] Replace confirms before applying
|
||||
|
||||
---
|
||||
|
||||
#### **Phase 4: UI Polish** (Week 7, 2 dev days)
|
||||
**Priority**: Low - Final polish
|
||||
|
||||
**Tasks**:
|
||||
1. Integrate `AgentUITheme` (if not already done)
|
||||
2. Add keyboard shortcuts
|
||||
3. Improve accessibility
|
||||
|
||||
**Success Criteria**:
|
||||
- [ ] All colors use theme system
|
||||
- [ ] Keyboard shortcuts documented
|
||||
- [ ] Tooltips on all major controls
|
||||
|
||||
---
|
||||
|
||||
### Architectural Decisions Needed
|
||||
|
||||
1. **JSON Schema**: Proposed schema includes context notes and metadata - needs review
|
||||
2. **Translation Layout**: Side-by-side vs. top-bottom layout - needs user feedback
|
||||
3. **Dictionary Auto-Optimization**: Complex NP-hard problem - may need background threads
|
||||
|
||||
---
|
||||
|
||||
## 🧪 Testing Infrastructure Roadmap
|
||||
|
||||
**Analysis**: test-infrastructure-expert agent
|
||||
**Current State**: Well-architected (34% test-to-code ratio), uneven coverage
|
||||
|
||||
### Top 5 Priorities
|
||||
|
||||
#### **Priority 1: Editor Lifecycle Test Framework** (Week 1, 1-2 dev days)
|
||||
**Why**: Every editor needs basic lifecycle testing
|
||||
|
||||
**What to Build**:
|
||||
- `test/unit/editor/editor_lifecycle_test.cc`
|
||||
- Parameterized test for all editor types
|
||||
- Validates initialization, ROM binding, error handling
|
||||
|
||||
**Implementation**:
|
||||
```cpp
|
||||
class EditorLifecycleTest : public ::testing::TestWithParam<editor::EditorType> {
|
||||
// Test: InitializeWithoutRom_Succeeds
|
||||
// Test: LoadWithoutRom_ReturnsError
|
||||
// Test: FullLifecycle_Succeeds
|
||||
// Test: UpdateBeforeLoad_ReturnsError
|
||||
};
|
||||
|
||||
INSTANTIATE_TEST_SUITE_P(
|
||||
AllEditors,
|
||||
EditorLifecycleTest,
|
||||
::testing::Values(
|
||||
editor::EditorType::kOverworld,
|
||||
editor::EditorType::kDungeon,
|
||||
editor::EditorType::kMessage,
|
||||
editor::EditorType::kGraphics,
|
||||
editor::EditorType::kPalette,
|
||||
editor::EditorType::kSprite
|
||||
)
|
||||
);
|
||||
```
|
||||
|
||||
**Impact**: Catches 80% of editor regressions with minimal effort
|
||||
|
||||
---
|
||||
|
||||
#### **Priority 2: OverworldEditor Entity Operations Tests** (Week 2, 2-3 dev days)
|
||||
**Why**: OverworldEditor is 118KB with complex entity management
|
||||
|
||||
**What to Build**:
|
||||
- `test/unit/editor/overworld/entity_operations_test.cc`
|
||||
- Tests for add/remove/modify entrances, exits, items, sprites
|
||||
- Validation of entity constraints and error handling
|
||||
|
||||
**Success Criteria**:
|
||||
- [ ] Add entity with valid position succeeds
|
||||
- [ ] Add entity with invalid position returns error
|
||||
- [ ] Remove entity by ID succeeds
|
||||
- [ ] Modify entity updates graphics
|
||||
- [ ] Delete all entities in region works
|
||||
|
||||
---
|
||||
|
||||
#### **Priority 3: Graphics Refresh Verification Tests** (Week 3, 2-3 dev days)
|
||||
**Why**: Graphics refresh bugs are common (UpdateBitmap vs RenderBitmap, data/surface sync)
|
||||
|
||||
**What to Build**:
|
||||
- `test/integration/editor/graphics_refresh_test.cc`
|
||||
- Validates Update property → Load → Force render pipeline
|
||||
- Tests Bitmap/surface synchronization
|
||||
- Verifies Arena texture queue processing
|
||||
|
||||
**Success Criteria**:
|
||||
- [ ] Change map palette triggers graphics reload
|
||||
- [ ] Bitmap data and surface stay synced
|
||||
- [ ] WriteToPixel updates surface
|
||||
- [ ] Arena texture queue processes correctly
|
||||
- [ ] Graphics sheet modification notifies Arena
|
||||
|
||||
---
|
||||
|
||||
#### **Priority 4: Message Editor Workflow Tests** (Week 4, 1-2 dev days)
|
||||
**Why**: Message editor has good data parsing tests but no editor UI/workflow tests
|
||||
|
||||
**What to Build**:
|
||||
- `test/integration/editor/message_editor_test.cc`
|
||||
- E2E test for message editing workflow
|
||||
- Tests for dictionary optimization
|
||||
- Command parsing validation
|
||||
|
||||
**Success Criteria**:
|
||||
- [ ] Load all messages succeeds
|
||||
- [ ] Edit message updates ROM
|
||||
- [ ] Add dictionary word optimizes message
|
||||
- [ ] Insert command validates syntax
|
||||
- [ ] Invalid command returns error
|
||||
|
||||
---
|
||||
|
||||
#### **Priority 5: Canvas Interaction Test Utilities** (Week 5-6, 2-3 dev days)
|
||||
**Why**: Multiple editors use Canvas - need reusable test helpers
|
||||
|
||||
**What to Build**:
|
||||
- `test/test_utils_canvas.h` / `test/test_utils_canvas.cc`
|
||||
- Semantic helpers: Click tile, select rectangle, drag entity
|
||||
- Bitmap comparison utilities
|
||||
|
||||
**API Design**:
|
||||
```cpp
|
||||
namespace yaze::test::canvas {
|
||||
void ClickTile(ImGuiTestContext* ctx, const std::string& canvas_name, int tile_x, int tile_y);
|
||||
void SelectRectangle(ImGuiTestContext* ctx, const std::string& canvas_name, int x1, int y1, int x2, int y2);
|
||||
void DragEntity(ImGuiTestContext* ctx, const std::string& canvas_name, int from_x, int from_y, int to_x, int to_y);
|
||||
uint32_t CaptureBitmapChecksum(const gfx::Bitmap& bitmap);
|
||||
int CompareBitmaps(const gfx::Bitmap& bitmap1, const gfx::Bitmap& bitmap2, bool log_differences = false);
|
||||
}
|
||||
```
|
||||
|
||||
**Impact**: Makes E2E tests easier to write, more maintainable, reduces duplication
|
||||
|
||||
---
|
||||
|
||||
### Testing Strategy
|
||||
|
||||
**ROM-Independent Tests** (Primary CI Target):
|
||||
- Use `MockRom` with minimal test data
|
||||
- Fast execution (< 5s total)
|
||||
- No external dependencies
|
||||
- Ideal for: Logic, calculations, data structures, error handling
|
||||
|
||||
**ROM-Dependent Tests** (Secondary/Manual):
|
||||
- Require actual Zelda3 ROM file
|
||||
- Slower execution (< 60s total)
|
||||
- Test real-world data parsing
|
||||
- Ideal for: Graphics rendering, full map loading, ROM patching
|
||||
|
||||
**Developer Workflow**:
|
||||
```bash
|
||||
# During development: Run fast unit tests frequently
|
||||
./build/bin/yaze_test --unit "*OverworldEntity*"
|
||||
|
||||
# Before commit: Run integration tests for changed editor
|
||||
./build/bin/yaze_test --integration "*Overworld*"
|
||||
|
||||
# Pre-PR: Run E2E tests for critical workflows
|
||||
./build/bin/yaze_test --e2e --show-gui
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📈 Success Metrics
|
||||
|
||||
**After 4 Weeks**:
|
||||
- ✅ Dungeon editor functional for basic editing
|
||||
- ✅ Overworld editor theme-compliant with undo/redo
|
||||
- ✅ Message editor supports JSON export/import
|
||||
- ✅ Test coverage increased from 10% → 40% for editors
|
||||
- ✅ All editors have lifecycle tests
|
||||
|
||||
---
|
||||
|
||||
## 🎬 Recommended Development Order
|
||||
|
||||
### Week 1: Quick Wins
|
||||
**Goal**: Immediate visible progress (8 hours)
|
||||
|
||||
```bash
|
||||
# Dungeon Editor (4 hours)
|
||||
1. Fix theme violations (1h)
|
||||
2. Wire object placement (2h)
|
||||
3. Enable object deletion (1h)
|
||||
|
||||
# Overworld Editor (4 hours)
|
||||
4. Start theme system refactor (4h)
|
||||
```
|
||||
|
||||
### Week 2: Core Functionality
|
||||
**Goal**: Unlock basic editing workflows (18 hours)
|
||||
|
||||
```bash
|
||||
# Dungeon Editor (10 hours)
|
||||
1. Complete object selection system (3h)
|
||||
2. Implement clipboard operations (4h)
|
||||
3. Add object properties panel (3h)
|
||||
|
||||
# Overworld Editor (8 hours)
|
||||
4. Finish theme system refactor (4h)
|
||||
5. Implement undo/redo foundation (4h)
|
||||
```
|
||||
|
||||
### Week 3: Testing Foundation
|
||||
**Goal**: Prevent regressions (15 hours)
|
||||
|
||||
```bash
|
||||
# Testing Infrastructure
|
||||
1. Create editor lifecycle test framework (5h)
|
||||
2. Add overworld entity operation tests (5h)
|
||||
3. Implement canvas interaction utilities (5h)
|
||||
```
|
||||
|
||||
### Week 4: Message Editor Phase 1
|
||||
**Goal**: Unlock translation workflows (15 hours)
|
||||
|
||||
```bash
|
||||
# Message Editor
|
||||
1. Implement JSON serialization (6h)
|
||||
2. Add export/import UI (4h)
|
||||
3. Add CLI import support (2h)
|
||||
4. Write comprehensive tests (3h)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📚 Key File Locations
|
||||
|
||||
### Dungeon Editor
|
||||
- **Primary**: `src/app/editor/dungeon/dungeon_editor_v2.{h,cc}`
|
||||
- **Components**: `dungeon_canvas_viewer`, `dungeon_object_selector`, `dungeon_object_interaction`, `dungeon_room_loader`
|
||||
- **Core Data**: `src/zelda3/dungeon/room.{h,cc}`, `object_drawer.{h,cc}`
|
||||
- **Tests**: `test/integration/dungeon_editor_v2_test.cc`, `test/e2e/dungeon_editor_smoke_test.cc`
|
||||
|
||||
### Overworld Editor
|
||||
- **Primary**: `src/app/editor/overworld/overworld_editor.{h,cc}`
|
||||
- **Modules**: `map_properties.cc`, `overworld_entity_renderer.cc`, `entity.cc`
|
||||
- **Core Data**: `src/zelda3/overworld/overworld.{h,cc}`
|
||||
- **Tests**: `test/unit/editor/overworld/overworld_editor_test.cc`
|
||||
|
||||
### Message Editor
|
||||
- **Primary**: `src/app/editor/message/message_editor.{h,cc}`
|
||||
- **Tests**: `test/integration/message/message_editor_test.cc`
|
||||
|
||||
### Testing Infrastructure
|
||||
- **Main Runner**: `test/yaze_test.cc`
|
||||
- **Utilities**: `test/test_utils.{h,cc}`, `test/mocks/mock_rom.h`
|
||||
- **Fixtures**: `test/unit/editor/editor_test_fixtures.h` (to be created)
|
||||
|
||||
---
|
||||
|
||||
## 📝 Notes
|
||||
|
||||
**Architecture Strengths**:
|
||||
- Modular editor design with clear separation of concerns
|
||||
- Progressive loading via gfx::Arena
|
||||
- ImGuiTestEngine integration for E2E tests
|
||||
- Card-based UI system
|
||||
|
||||
**Critical Issues**:
|
||||
- Overworld Editor: 22 hardcoded colors violate theme system
|
||||
- All Editors: Missing undo/redo (user frustration #1)
|
||||
- Testing: 67 editor headers, only 6 have tests
|
||||
|
||||
**Strategic Recommendations**:
|
||||
1. Start with dungeon editor - quickest path to "working" state
|
||||
2. Fix overworld theme violations - visible polish, affects UX
|
||||
3. Implement message JSON export - foundation for translation
|
||||
4. Add lifecycle tests - catches 80% of regressions
|
||||
|
||||
---
|
||||
|
||||
**Document Version**: 1.0
|
||||
**Last Updated**: 2025-11-21
|
||||
**Next Review**: After completing Week 1 priorities
|
||||
326
docs/internal/plans/GEMINI3_HANDOFF.md
Normal file
326
docs/internal/plans/GEMINI3_HANDOFF.md
Normal file
@@ -0,0 +1,326 @@
|
||||
# Gemini 3 Handoff Document
|
||||
|
||||
**Date**: 2024-11-22
|
||||
**Prepared by**: Claude (Sonnet 4.5)
|
||||
**Previous agents**: Gemini 3 (interrupted), Claude 4.5, GPT-OSS 120
|
||||
|
||||
## TL;DR
|
||||
|
||||
Your work was interrupted and left ~112 uncommitted files scattered across the workspace. I've organized everything into 5 logical branches based on your original `branch_organization.md` plan. All branches are ready for review and merging.
|
||||
|
||||
## What Happened
|
||||
|
||||
1. You (Gemini 3) started work on multiple features simultaneously
|
||||
2. You created `docs/internal/plans/branch_organization.md` outlining how to split the work
|
||||
3. You were interrupted before completing the organization
|
||||
4. Claude 4.5 and GPT-OSS 120 attempted to help but left things partially done
|
||||
5. I (Claude Sonnet 4.5) completed the reorganization
|
||||
|
||||
## Current Branch State
|
||||
|
||||
```
|
||||
master (0d18c521a1) ─┬─► feature/agent-ui-improvements (29931139f5)
|
||||
├─► infra/ci-test-overhaul (aa411a5d1b)
|
||||
├─► test/e2e-dungeon-coverage (28147624a3)
|
||||
├─► chore/misc-cleanup (ed396f7498)
|
||||
├─► fix/overworld-logic (00fef1169d)
|
||||
└─► backup/all-uncommitted-work-2024-11-22 (5e32a8983f)
|
||||
```
|
||||
|
||||
Also preserved:
|
||||
- `feature/debugger-disassembler` (2a88785e25) - Your original debugger work
|
||||
|
||||
---
|
||||
|
||||
## Branch Details
|
||||
|
||||
### 1. `feature/agent-ui-improvements` (19 files, +5183/-141 lines)
|
||||
|
||||
**Purpose**: Agent UI enhancements and new dev assist tooling
|
||||
|
||||
**Key Changes**:
|
||||
| File | Change Type | Description |
|
||||
|------|-------------|-------------|
|
||||
| `agent_chat_widget.cc` | Modified | Enhanced chat UI with better UX |
|
||||
| `agent_editor.cc` | Modified | Editor improvements |
|
||||
| `proposal_drawer.cc` | Modified | Better proposal display |
|
||||
| `dev_assist_agent.cc/.h` | **New** | Development assistance agent |
|
||||
| `tool_dispatcher.cc/.h` | Modified | New tool dispatch capabilities |
|
||||
| `tools/build_tool.cc/.h` | **New** | Build system integration tool |
|
||||
| `tools/filesystem_tool.cc/.h` | **New** | File operations tool |
|
||||
| `tools/memory_inspector_tool.cc/.h` | **New** | Memory debugging tool |
|
||||
| `emulator_service_impl.cc/.h` | Modified | Enhanced emulator integration |
|
||||
| `prompt_builder.cc` | Modified | AI prompt improvements |
|
||||
| `tool_dispatcher_test.cc` | **New** | Integration tests |
|
||||
|
||||
**Dependencies**: None - can be merged independently
|
||||
|
||||
**Testing needed**:
|
||||
```bash
|
||||
cmake --preset mac-dbg
|
||||
ctest --test-dir build -R "tool_dispatcher"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 2. `infra/ci-test-overhaul` (23 files, +3644/-263 lines)
|
||||
|
||||
**Purpose**: CI/CD and test infrastructure modernization
|
||||
|
||||
**Key Changes**:
|
||||
| File | Change Type | Description |
|
||||
|------|-------------|-------------|
|
||||
| `ci.yml` | Modified | Improved CI workflow |
|
||||
| `release.yml` | Modified | Better release process |
|
||||
| `nightly.yml` | **New** | Scheduled nightly builds |
|
||||
| `AGENTS.md` | Modified | Agent coordination updates |
|
||||
| `CLAUDE.md` | Modified | Build/test guidance |
|
||||
| `CI-TEST-STRATEGY.md` | **New** | Test strategy documentation |
|
||||
| `CI-TEST-AUDIT-REPORT.md` | **New** | Audit findings |
|
||||
| `ci-and-testing.md` | **New** | Comprehensive CI guide |
|
||||
| `test-suite-configuration.md` | **New** | Test config documentation |
|
||||
| `coordination-board.md` | **New** | Agent coordination board |
|
||||
| `test/README.md` | Modified | Test organization guide |
|
||||
| `test/test.cmake` | Modified | CMake test configuration |
|
||||
|
||||
**Dependencies**: None - should be merged FIRST
|
||||
|
||||
**Testing needed**:
|
||||
```bash
|
||||
# Verify workflows are valid YAML
|
||||
python3 -c "import yaml; yaml.safe_load(open('.github/workflows/ci.yml'))"
|
||||
python3 -c "import yaml; yaml.safe_load(open('.github/workflows/nightly.yml'))"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 3. `test/e2e-dungeon-coverage` (18 files, +3379/-39 lines)
|
||||
|
||||
**Purpose**: Comprehensive dungeon editor test coverage
|
||||
|
||||
**Key Changes**:
|
||||
| File | Change Type | Description |
|
||||
|------|-------------|-------------|
|
||||
| `dungeon_canvas_interaction_test.cc/.h` | **New** | Canvas click/drag tests |
|
||||
| `dungeon_e2e_tests.cc/.h` | **New** | Full workflow E2E tests |
|
||||
| `dungeon_layer_rendering_test.cc/.h` | **New** | Layer visibility tests |
|
||||
| `dungeon_object_drawing_test.cc/.h` | **New** | Object rendering tests |
|
||||
| `dungeon_visual_verification_test.cc/.h` | **New** | Visual regression tests |
|
||||
| `dungeon_editor_system_integration_test.cc` | Modified | System integration |
|
||||
| `dungeon_object_rendering_tests.cc` | Modified | Object render validation |
|
||||
| `dungeon_rendering_test.cc` | Modified | Rendering pipeline |
|
||||
| `dungeon_room_test.cc` | Modified | Room data validation |
|
||||
| `object_rendering_test.cc` | Modified | Unit test updates |
|
||||
| `room.cc` | Modified | Minor bug fix |
|
||||
| `dungeon-gui-test-design.md` | **New** | Test design document |
|
||||
|
||||
**Dependencies**: Merge after `infra/ci-test-overhaul` for test config
|
||||
|
||||
**Testing needed**:
|
||||
```bash
|
||||
cmake --preset mac-dbg
|
||||
ctest --test-dir build -R "dungeon" -L stable
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 4. `chore/misc-cleanup` (39 files, +7924/-127 lines)
|
||||
|
||||
**Purpose**: Documentation, architecture docs, misc cleanup
|
||||
|
||||
**Key Changes**:
|
||||
| Category | Files | Description |
|
||||
|----------|-------|-------------|
|
||||
| Architecture Docs | `docs/internal/architecture/*` | dungeon_editor_system, message_system, music_system |
|
||||
| Plan Docs | `docs/internal/plans/*` | Various roadmaps and plans |
|
||||
| Dev Guides | `GEMINI_DEV_GUIDE.md`, `ai-asm-debugging-guide.md` | Developer guides |
|
||||
| Build System | `src/CMakeLists.txt`, `editor_library.cmake` | Build config updates |
|
||||
| App Core | `controller.cc`, `main.cc` | Application updates |
|
||||
| Style System | `src/app/gui/style/theme.h` | **New** UI theming |
|
||||
| Unit Tests | `test/unit/*` | Various test updates |
|
||||
|
||||
**Dependencies**: Merge LAST - may need rebasing
|
||||
|
||||
**Testing needed**:
|
||||
```bash
|
||||
cmake --preset mac-dbg
|
||||
ctest --test-dir build -L stable
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 5. `fix/overworld-logic` (2 files, +10/-5 lines)
|
||||
|
||||
**Purpose**: Small fixes to overworld tests
|
||||
|
||||
**Key Changes**:
|
||||
- `overworld_integration_test.cc` - Integration test fixes
|
||||
- `overworld_test.cc` - Unit test fixes
|
||||
|
||||
**Dependencies**: None
|
||||
|
||||
**Testing needed**:
|
||||
```bash
|
||||
ctest --test-dir build -R "overworld"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Recommended Merge Order
|
||||
|
||||
```
|
||||
1. infra/ci-test-overhaul # Sets up CI/test infrastructure
|
||||
↓
|
||||
2. test/e2e-dungeon-coverage # Uses new test config
|
||||
↓
|
||||
3. feature/agent-ui-improvements # Independent feature
|
||||
↓
|
||||
4. fix/overworld-logic # Small fix
|
||||
↓
|
||||
5. chore/misc-cleanup # Docs and misc (rebase first)
|
||||
```
|
||||
|
||||
### Merge Commands
|
||||
|
||||
```bash
|
||||
# 1. Merge CI infrastructure
|
||||
git checkout master
|
||||
git merge --no-ff infra/ci-test-overhaul -m "Merge infra/ci-test-overhaul: CI/CD and test infrastructure"
|
||||
|
||||
# 2. Merge dungeon tests
|
||||
git merge --no-ff test/e2e-dungeon-coverage -m "Merge test/e2e-dungeon-coverage: Dungeon E2E test suite"
|
||||
|
||||
# 3. Merge agent UI
|
||||
git merge --no-ff feature/agent-ui-improvements -m "Merge feature/agent-ui-improvements: Agent UI and tools"
|
||||
|
||||
# 4. Merge overworld fix
|
||||
git merge --no-ff fix/overworld-logic -m "Merge fix/overworld-logic: Overworld test fixes"
|
||||
|
||||
# 5. Rebase and merge cleanup (may have conflicts)
|
||||
git checkout chore/misc-cleanup
|
||||
git rebase master
|
||||
# Resolve any conflicts
|
||||
git checkout master
|
||||
git merge --no-ff chore/misc-cleanup -m "Merge chore/misc-cleanup: Documentation and cleanup"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Potential Conflicts
|
||||
|
||||
### Between branches:
|
||||
- `chore/misc-cleanup` touches `src/CMakeLists.txt` which other branches may also modify
|
||||
- Both `infra/ci-test-overhaul` and `chore/misc-cleanup` touch documentation
|
||||
|
||||
### With master:
|
||||
- If master advances, all branches may need rebasing
|
||||
- The `CLAUDE.md` changes in `infra/ci-test-overhaul` should be reviewed carefully
|
||||
|
||||
---
|
||||
|
||||
## Untracked Files (Need Manual Decision)
|
||||
|
||||
These were NOT committed to any branch:
|
||||
|
||||
| File/Directory | Recommendation |
|
||||
|----------------|----------------|
|
||||
| `.tmp/` | **Delete** - Contains ZScreamDungeon embedded repo |
|
||||
| `third_party/bloaty` | **Decide** - Should be submodule or in .gitignore |
|
||||
| `CIRCULAR_DEPENDENCY_ANALYSIS.md` | **Delete** - Temporary analysis |
|
||||
| `CIRCULAR_DEPENDENCY_FIX_REPORT.md` | **Delete** - Temporary report |
|
||||
| `FIX_CIRCULAR_DEPS.patch` | **Delete** - Temporary patch |
|
||||
| `debug_crash.lldb` | **Delete** - Debug artifact |
|
||||
| `fix_dungeon_colors.py` | **Delete** - One-off script |
|
||||
| `test_grpc_server.sh` | **Keep?** - Test utility |
|
||||
|
||||
### Cleanup Commands
|
||||
```bash
|
||||
# Remove temporary files
|
||||
rm -f CIRCULAR_DEPENDENCY_ANALYSIS.md CIRCULAR_DEPENDENCY_FIX_REPORT.md
|
||||
rm -f FIX_CIRCULAR_DEPS.patch debug_crash.lldb fix_dungeon_colors.py
|
||||
|
||||
# Remove embedded repos (careful!)
|
||||
rm -rf .tmp/
|
||||
|
||||
# Add to .gitignore if needed
|
||||
echo ".tmp/" >> .gitignore
|
||||
echo "third_party/bloaty/" >> .gitignore
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Stash Contents (For Reference)
|
||||
|
||||
```bash
|
||||
$ git stash list
|
||||
stash@{0}: WIP on feature/ai-test-infrastructure
|
||||
stash@{1}: WIP on feature/ai-infra-improvements
|
||||
stash@{2}: Release workflow artifact path fix
|
||||
stash@{3}: WIP on develop (Windows OpenSSL)
|
||||
stash@{4}: WIP on feat/gemini-unified-fix
|
||||
```
|
||||
|
||||
To view a stash:
|
||||
```bash
|
||||
git stash show -p stash@{0}
|
||||
```
|
||||
|
||||
These may contain work that was already incorporated into the branches, or may have unique changes. Review before dropping.
|
||||
|
||||
---
|
||||
|
||||
## The Original Plan (For Reference)
|
||||
|
||||
Your original plan from `branch_organization.md` was:
|
||||
|
||||
1. `feature/debugger-disassembler` - ✅ Already had commit
|
||||
2. `infra/ci-test-overhaul` - ✅ Now populated
|
||||
3. `test/e2e-dungeon-coverage` - ✅ Now populated
|
||||
4. `feature/agent-ui-improvements` - ✅ Now populated
|
||||
5. `fix/overworld-logic` - ✅ Now populated
|
||||
6. `chore/misc-cleanup` - ✅ Now populated
|
||||
|
||||
---
|
||||
|
||||
## UI Modernization Context
|
||||
|
||||
You also had `ui_modernization.md` which outlines the component-based architecture pattern. Key points:
|
||||
|
||||
- New editors should follow `DungeonEditorV2` pattern
|
||||
- Use `EditorDependencies` struct for dependency injection
|
||||
- Use `ImGuiWindowClass` for docking groups
|
||||
- Use `EditorCardRegistry` for tool windows
|
||||
- `UICoordinator` is the central hub for app-level UI
|
||||
|
||||
The agent UI improvements in `feature/agent-ui-improvements` should align with these patterns.
|
||||
|
||||
---
|
||||
|
||||
## Safety Net
|
||||
|
||||
If anything goes wrong, the backup branch has EVERYTHING:
|
||||
|
||||
```bash
|
||||
# Restore everything from backup
|
||||
git checkout backup/all-uncommitted-work-2024-11-22
|
||||
|
||||
# Or cherry-pick specific files
|
||||
git checkout backup/all-uncommitted-work-2024-11-22 -- path/to/file
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Questions for You
|
||||
|
||||
1. Should `third_party/bloaty` be a git submodule?
|
||||
2. Should `.tmp/` be added to `.gitignore`?
|
||||
3. Are the stashed changes still needed, or can they be dropped?
|
||||
4. Do you want PRs created for review, or direct merges?
|
||||
|
||||
---
|
||||
|
||||
## Contact
|
||||
|
||||
This document is in `docs/internal/plans/GEMINI3_HANDOFF.md` on the `chore/misc-cleanup` branch.
|
||||
|
||||
Good luck! 🚀
|
||||
585
docs/internal/plans/ai-assisted-development-plan.md
Normal file
585
docs/internal/plans/ai-assisted-development-plan.md
Normal file
@@ -0,0 +1,585 @@
|
||||
# AI-Assisted Development Workflow Plan
|
||||
|
||||
## Executive Summary
|
||||
|
||||
This document outlines a practical AI-assisted development workflow for the yaze project, enabling AI agents to help developers during both yaze development and ROM hack debugging. The system leverages existing infrastructure (gRPC services, tool dispatcher, emulator integration) to deliver immediate value with minimal new development.
|
||||
|
||||
## Architecture Overview
|
||||
|
||||
### Core Components
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────┐
|
||||
│ z3ed CLI │
|
||||
│ ┌──────────────────────────────────────────┐ │
|
||||
│ │ AI Service Factory │ │
|
||||
│ │ (Ollama/Gemini/Mock Providers) │ │
|
||||
│ └──────────────────────────────────────────┘ │
|
||||
│ │ │
|
||||
│ ┌──────────────────────────────────────────┐ │
|
||||
│ │ Agent Orchestrator │ │
|
||||
│ │ (Conversational + Tool Dispatcher) │ │
|
||||
│ └──────────────────────────────────────────┘ │
|
||||
│ │ │
|
||||
│ ┌────────────┴────────────┐ │
|
||||
│ ▼ ▼ │
|
||||
│ ┌──────────────┐ ┌──────────────┐ │
|
||||
│ │ Dev Mode │ │ Debug Mode │ │
|
||||
│ │ Agent │ │ Agent │ │
|
||||
│ └──────────────┘ └──────────────┘ │
|
||||
│ │ │ │
|
||||
│ ▼ ▼ │
|
||||
│ ┌──────────────────────────────────────────┐ │
|
||||
│ │ Tool Dispatcher │ │
|
||||
│ │ • FileSystemTool • EmulatorTool │ │
|
||||
│ │ • BuildTool • DisassemblyTool │ │
|
||||
│ │ • TestRunner • MemoryInspector │ │
|
||||
│ └──────────────────────────────────────────┘ │
|
||||
└─────────────────────────────────────────────────┘
|
||||
│
|
||||
┌────────────────┼────────────────┐
|
||||
▼ ▼ ▼
|
||||
┌──────────────┐ ┌──────────────┐ ┌──────────────┐
|
||||
│Build System │ │ Emulator │ │ ROM Editor │
|
||||
│(CMake/Ninja) │ │ (via gRPC) │ │ (via Tools) │
|
||||
└──────────────┘ └──────────────┘ └──────────────┘
|
||||
```
|
||||
|
||||
### Existing Infrastructure (Ready to Use)
|
||||
|
||||
1. **EmulatorServiceImpl** (`src/cli/service/agent/emulator_service_impl.cc`)
|
||||
- Full debugger control via gRPC
|
||||
- Breakpoints, watchpoints, memory inspection
|
||||
- Execution control (step, run, pause)
|
||||
- Disassembly and trace capabilities
|
||||
|
||||
2. **ToolDispatcher** (`src/cli/service/agent/tool_dispatcher.h`)
|
||||
- Extensible tool system
|
||||
- Already supports ROM operations, GUI automation
|
||||
- Easy to add new tools (FileSystem, Build, etc.)
|
||||
|
||||
3. **Disassembler65816** (`src/cli/service/agent/disassembler_65816.h`)
|
||||
- Full 65816 instruction decoding
|
||||
- Execution trace buffer
|
||||
- CPU state snapshots
|
||||
|
||||
4. **AI Service Integration**
|
||||
- Ollama and Gemini providers implemented
|
||||
- Conversational agent with tool calling
|
||||
- Prompt builder with context management
|
||||
|
||||
5. **FileSystemTool** (Just implemented by CLAUDE_AIINF)
|
||||
- Safe read-only filesystem exploration
|
||||
- Project directory restriction
|
||||
- Binary file detection
|
||||
|
||||
## Mode 1: App Development Agent
|
||||
|
||||
### Purpose
|
||||
Help developers while coding yaze itself - catch errors, run tests, analyze crashes, suggest improvements.
|
||||
|
||||
### Key Features
|
||||
|
||||
#### 1.1 Build Monitoring & Error Resolution
|
||||
```yaml
|
||||
Triggers:
|
||||
- Compilation error detected
|
||||
- Link failure
|
||||
- CMake configuration issue
|
||||
|
||||
Agent Actions:
|
||||
- Parse error messages
|
||||
- Analyze include paths and dependencies
|
||||
- Suggest fixes with code snippets
|
||||
- Check for common pitfalls (circular deps, missing headers)
|
||||
|
||||
Tools Used:
|
||||
- BuildTool (configure, compile, status)
|
||||
- FileSystemTool (read source files)
|
||||
- TestRunner (verify fixes)
|
||||
```
|
||||
|
||||
#### 1.2 Crash Analysis
|
||||
```yaml
|
||||
Triggers:
|
||||
- Segmentation fault
|
||||
- Assertion failure
|
||||
- Stack overflow
|
||||
|
||||
Agent Actions:
|
||||
- Parse stack trace
|
||||
- Read relevant source files
|
||||
- Analyze call chain
|
||||
- Suggest root cause and fix
|
||||
- Check for similar patterns in codebase
|
||||
|
||||
Tools Used:
|
||||
- FileSystemTool (read crash context)
|
||||
- BuildTool (recompile with debug symbols)
|
||||
- TestRunner (reproduce crash)
|
||||
```
|
||||
|
||||
#### 1.3 Test Automation
|
||||
```yaml
|
||||
Triggers:
|
||||
- Code changes detected
|
||||
- Manual test request
|
||||
- Pre-commit hook
|
||||
|
||||
Agent Actions:
|
||||
- Identify affected test suites
|
||||
- Run relevant tests
|
||||
- Parse test output
|
||||
- Suggest test additions for uncovered code
|
||||
- Generate test cases for new functions
|
||||
|
||||
Tools Used:
|
||||
- TestRunner (execute tests)
|
||||
- FileSystemTool (analyze coverage)
|
||||
- BuildTool (compile test targets)
|
||||
```
|
||||
|
||||
#### 1.4 Performance Analysis
|
||||
```yaml
|
||||
Triggers:
|
||||
- Performance regression detected
|
||||
- Manual profiling request
|
||||
- CI benchmark failure
|
||||
|
||||
Agent Actions:
|
||||
- Run performance benchmarks
|
||||
- Compare with baseline
|
||||
- Identify hot spots
|
||||
- Suggest optimization strategies
|
||||
- Check for common inefficiencies
|
||||
|
||||
Tools Used:
|
||||
- TestRunner (run benchmarks)
|
||||
- FileSystemTool (analyze code)
|
||||
- BuildTool (compile with profiling)
|
||||
```
|
||||
|
||||
### Example Workflow: Compilation Error
|
||||
|
||||
```bash
|
||||
# Developer encounters error
|
||||
$ cmake --build build_ai
|
||||
[ERROR] snes_color.cc:45: 'gfx::Arena' has not been declared
|
||||
|
||||
# Agent automatically kicks in
|
||||
$ z3ed agent dev-assist --monitor-build
|
||||
|
||||
AI: I detected a compilation error. Let me analyze...
|
||||
|
||||
[Reading src/app/gfx/snes_color.cc]
|
||||
[Checking include paths]
|
||||
[Searching for gfx::Arena definition]
|
||||
|
||||
Found the issue! The file is missing:
|
||||
#include "app/gfx/arena.h"
|
||||
|
||||
The Arena class is defined in app/gfx/arena.h but not included.
|
||||
Here's the fix:
|
||||
|
||||
--- a/src/app/gfx/snes_color.cc
|
||||
+++ b/src/app/gfx/snes_color.cc
|
||||
@@ -3,6 +3,7 @@
|
||||
#include "app/gfx/bitmap.h"
|
||||
+#include "app/gfx/arena.h"
|
||||
|
||||
Would you like me to:
|
||||
1. Apply this fix and rebuild?
|
||||
2. Check for similar missing includes?
|
||||
3. Run tests after fixing?
|
||||
```
|
||||
|
||||
## Mode 2: Zelda Hack Debugging Agent
|
||||
|
||||
### Purpose
|
||||
Help ROM hackers debug ASM patches, understand crashes, analyze game state during development.
|
||||
|
||||
### Key Features
|
||||
|
||||
#### 2.1 Breakpoint Analysis
|
||||
```yaml
|
||||
Triggers:
|
||||
- Breakpoint hit in emulator
|
||||
- Manual disassembly request
|
||||
- Crash during ROM execution
|
||||
|
||||
Agent Actions:
|
||||
- Disassemble current location
|
||||
- Explain instruction sequence
|
||||
- Show call stack
|
||||
- Analyze register values
|
||||
- Suggest what the code is doing
|
||||
|
||||
Tools Used:
|
||||
- EmulatorTool (control execution)
|
||||
- DisassemblyTool (decode instructions)
|
||||
- MemoryInspector (read RAM/ROM)
|
||||
```
|
||||
|
||||
#### 2.2 Memory State Analysis
|
||||
```yaml
|
||||
Triggers:
|
||||
- Watchpoint triggered
|
||||
- Manual memory inspection
|
||||
- Corruption detected
|
||||
|
||||
Agent Actions:
|
||||
- Read memory regions
|
||||
- Compare with known structures
|
||||
- Identify data types (sprites, tiles, etc.)
|
||||
- Track memory modifications
|
||||
- Suggest corruption sources
|
||||
|
||||
Tools Used:
|
||||
- MemoryInspector (read/monitor memory)
|
||||
- EmulatorTool (set watchpoints)
|
||||
- ResourceTool (correlate with ROM data)
|
||||
```
|
||||
|
||||
#### 2.3 ASM Patch Debugging
|
||||
```yaml
|
||||
Triggers:
|
||||
- Patch causes crash
|
||||
- Unexpected behavior after patch
|
||||
- Hook not executing
|
||||
|
||||
Agent Actions:
|
||||
- Compare patched vs original code
|
||||
- Trace execution flow
|
||||
- Verify jump targets
|
||||
- Check for stack imbalance
|
||||
- Validate addressing modes
|
||||
|
||||
Tools Used:
|
||||
- DisassemblyTool (analyze patches)
|
||||
- EmulatorTool (trace execution)
|
||||
- DiffTool (compare ROM regions)
|
||||
```
|
||||
|
||||
#### 2.4 Routine Tracing
|
||||
```yaml
|
||||
Triggers:
|
||||
- Need to understand game routine
|
||||
- Reverse engineering request
|
||||
- Finding hook points
|
||||
|
||||
Agent Actions:
|
||||
- Trace routine execution
|
||||
- Document register usage
|
||||
- Map memory accesses
|
||||
- Identify subroutine calls
|
||||
- Generate routine documentation
|
||||
|
||||
Tools Used:
|
||||
- EmulatorTool (step through code)
|
||||
- DisassemblyTool (decode instructions)
|
||||
- SymbolProvider (resolve addresses)
|
||||
```
|
||||
|
||||
### Example Workflow: Debugging ROM Crash
|
||||
|
||||
```bash
|
||||
# ROM hacker experiences crash
|
||||
$ z3ed agent debug-rom --rom=my_hack.sfc --emulator-port=50051
|
||||
|
||||
AI: Connected to emulator. Setting up debugging session...
|
||||
|
||||
[Emulator paused at crash point]
|
||||
Address: $0A:8234
|
||||
Instruction: STA $7E2000,X
|
||||
Registers: A=$FFFF X=$8000 Y=$0000
|
||||
|
||||
AI: I see the crash! You're writing to $7E:A000 (WRAM mirror + $8000).
|
||||
This is out of bounds for WRAM ($7E0000-$7FFFFF).
|
||||
|
||||
Let me trace back to see how X got this value...
|
||||
|
||||
[Analyzing execution trace]
|
||||
5 instructions ago at $0A:8220:
|
||||
LDX $1A ; Loaded X from $1A (value was $8000)
|
||||
|
||||
The issue is $1A contains $8000 when it should be < $2000.
|
||||
This variable appears to be an index into the sprite table.
|
||||
|
||||
Possible causes:
|
||||
1. Sprite index overflow (too many sprites)
|
||||
2. Uninitialized memory at $1A
|
||||
3. Calculation error in previous routine
|
||||
|
||||
Would you like me to:
|
||||
1. Set a watchpoint on $1A to find what's setting it?
|
||||
2. Analyze the routine that calculates sprite indices?
|
||||
3. Check for similar boundary issues in your patches?
|
||||
```
|
||||
|
||||
## Required New Components
|
||||
|
||||
### Phase 1: Core Tools (1-2 days)
|
||||
1. **BuildTool** - CMake/Ninja integration
|
||||
- Configure, compile, test commands
|
||||
- Parse build output for errors
|
||||
- Status monitoring
|
||||
|
||||
2. **TestRunner** - CTest integration
|
||||
- Run specific test suites
|
||||
- Parse test results
|
||||
- Coverage analysis
|
||||
|
||||
3. **MemoryInspector** - Enhanced memory tools
|
||||
- Structured memory reads
|
||||
- Pattern matching
|
||||
- Corruption detection
|
||||
|
||||
### Phase 2: Agent Modes (2-3 days)
|
||||
1. **DevAssistAgent** - Development helper
|
||||
- Build monitoring loop
|
||||
- Error pattern matching
|
||||
- Solution suggestion engine
|
||||
|
||||
2. **RomDebugAgent** - ROM hacking assistant
|
||||
- Emulator connection manager
|
||||
- Crash analysis engine
|
||||
- Patch verification system
|
||||
|
||||
### Phase 3: Enhanced Integration (3-5 days)
|
||||
1. **Continuous Monitoring**
|
||||
- File watcher for auto-rebuild
|
||||
- Test runner on file changes
|
||||
- Performance regression detection
|
||||
|
||||
2. **Context Management**
|
||||
- Project state tracking
|
||||
- History of issues and fixes
|
||||
- Learning from past solutions
|
||||
|
||||
## Implementation Phases
|
||||
|
||||
### Phase 1: Foundation (Week 1)
|
||||
**Goal**: Basic tool infrastructure
|
||||
**Deliverables**:
|
||||
- BuildTool implementation
|
||||
- TestRunner implementation
|
||||
- Basic DevAssistAgent with build monitoring
|
||||
- Command: `z3ed agent dev-assist --monitor`
|
||||
|
||||
### Phase 2: Debugging (Week 2)
|
||||
**Goal**: ROM debugging capabilities
|
||||
**Deliverables**:
|
||||
- MemoryInspector enhancements
|
||||
- RomDebugAgent implementation
|
||||
- Emulator integration improvements
|
||||
- Command: `z3ed agent debug-rom --rom=<file>`
|
||||
|
||||
### Phase 3: Intelligence (Week 3)
|
||||
**Goal**: Smart analysis and suggestions
|
||||
**Deliverables**:
|
||||
- Error pattern database
|
||||
- Solution suggestion engine
|
||||
- Context-aware responses
|
||||
- Test generation capabilities
|
||||
|
||||
### Phase 4: Polish (Week 4)
|
||||
**Goal**: Production readiness
|
||||
**Deliverables**:
|
||||
- Performance optimization
|
||||
- Documentation and tutorials
|
||||
- Example workflows
|
||||
- Integration tests
|
||||
|
||||
## Integration Points
|
||||
|
||||
### With Existing Code
|
||||
|
||||
1. **ToolDispatcher** (`tool_dispatcher.h`)
|
||||
```cpp
|
||||
// Add new tool types
|
||||
enum class ToolCallType {
|
||||
// ... existing ...
|
||||
kBuildConfigure,
|
||||
kBuildCompile,
|
||||
kBuildTest,
|
||||
kMemoryRead,
|
||||
kMemoryWatch,
|
||||
kTestRun,
|
||||
kTestCoverage,
|
||||
};
|
||||
```
|
||||
|
||||
2. **ConversationalAgentService**
|
||||
```cpp
|
||||
// Add agent modes
|
||||
class DevAssistAgent : public AgentMode {
|
||||
void MonitorBuild();
|
||||
void AnalyzeCrash(const StackTrace& trace);
|
||||
void SuggestFix(const CompileError& error);
|
||||
};
|
||||
```
|
||||
|
||||
3. **EmulatorService**
|
||||
```cpp
|
||||
// Enhance debugging APIs
|
||||
class DebugSession {
|
||||
void SetAutomaticAnalysis(bool enabled);
|
||||
void RegisterCrashHandler(CrashCallback cb);
|
||||
void EnableInstructionTrace(size_t buffer_size);
|
||||
};
|
||||
```
|
||||
|
||||
### With CI/CD Pipeline
|
||||
|
||||
1. **GitHub Actions Integration**
|
||||
```yaml
|
||||
- name: AI-Assisted Build Check
|
||||
run: |
|
||||
z3ed agent dev-assist --ci-mode \
|
||||
--analyze-errors \
|
||||
--suggest-fixes \
|
||||
--output=ai-analysis.md
|
||||
```
|
||||
|
||||
2. **Pre-commit Hooks**
|
||||
```bash
|
||||
#!/bin/bash
|
||||
# .git/hooks/pre-commit
|
||||
z3ed agent dev-assist --check-changes \
|
||||
--run-affected-tests \
|
||||
--verify-no-regressions
|
||||
```
|
||||
|
||||
## Example Workflows
|
||||
|
||||
### Workflow 1: AI-Assisted TDD
|
||||
```bash
|
||||
# Developer writes test first
|
||||
$ cat > test/unit/my_feature_test.cc << EOF
|
||||
TEST(MyFeature, ShouldDoSomething) {
|
||||
MyClass obj;
|
||||
EXPECT_EQ(obj.Process(5), 10);
|
||||
}
|
||||
EOF
|
||||
|
||||
# AI generates implementation
|
||||
$ z3ed agent generate --from-test=test/unit/my_feature_test.cc
|
||||
|
||||
AI: Based on your test, here's a suggested implementation:
|
||||
|
||||
class MyClass {
|
||||
public:
|
||||
int Process(int input) {
|
||||
return input * 2; // Doubles the input based on test expectation
|
||||
}
|
||||
};
|
||||
|
||||
Shall I create src/app/my_class.h with this implementation?
|
||||
```
|
||||
|
||||
### Workflow 2: Crash During ROM Testing
|
||||
```bash
|
||||
# Developer testing ROM modifications
|
||||
$ z3ed agent debug-rom --rom=hack.sfc --auto-debug
|
||||
|
||||
AI: Monitoring emulator for issues...
|
||||
|
||||
[CRASH DETECTED at $15:A0F2]
|
||||
Illegal instruction: $42 (WDM - disabled on SNES)
|
||||
|
||||
This appears to be data executed as code. Analyzing...
|
||||
|
||||
The jump at $15:A0E0 uses indirect addressing: JMP ($0234)
|
||||
The value at $0234 is $A0F2, which points to sprite data, not code.
|
||||
|
||||
Likely cause: Corrupted pointer table at $0234.
|
||||
|
||||
Suggested fix:
|
||||
1. Check your modifications to pointer tables
|
||||
2. The original value at $0234 should be $8CF2
|
||||
3. Look for code that writes to $0234-$0235
|
||||
|
||||
Would you like me to trace what modified this address?
|
||||
```
|
||||
|
||||
### Workflow 3: Performance Regression
|
||||
```bash
|
||||
# CI detects performance issue
|
||||
$ z3ed agent analyze-perf --baseline=main --current=HEAD
|
||||
|
||||
AI: Performance regression detected in gfx::Arena::LoadTile16
|
||||
|
||||
Baseline: 1.2ms average
|
||||
Current: 4.5ms average (275% slower)
|
||||
|
||||
Analyzing changes... Found the issue:
|
||||
|
||||
commit abc123: "Add texture validation"
|
||||
+ for (auto& pixel : tile.data()) {
|
||||
+ ValidatePixel(pixel); // This is called 256 times per tile
|
||||
+ }
|
||||
|
||||
The validation is happening in the hot path. Suggestions:
|
||||
1. Move validation to debug builds only
|
||||
2. Batch validation instead of per-pixel
|
||||
3. Use SIMD for validation if keeping it
|
||||
|
||||
Here's an optimized version:
|
||||
#ifdef DEBUG
|
||||
ValidateTileData(tile.data()); // Batch validation
|
||||
#endif
|
||||
```
|
||||
|
||||
## Success Metrics
|
||||
|
||||
### Immediate (Week 1)
|
||||
- Build error resolution time < 30 seconds
|
||||
- Basic test automation working
|
||||
- 5+ common error patterns recognized
|
||||
|
||||
### Short-term (Month 1)
|
||||
- 50% reduction in debugging time
|
||||
- 80% of build errors auto-resolved
|
||||
- 10+ developers using the tool
|
||||
|
||||
### Long-term (Quarter 1)
|
||||
- Comprehensive error pattern database
|
||||
- Integration with all major workflows
|
||||
- Measurable improvement in development velocity
|
||||
- Community contributions to agent capabilities
|
||||
|
||||
## Risk Mitigation
|
||||
|
||||
### Technical Risks
|
||||
1. **AI Model Limitations**
|
||||
- Mitigation: Fallback to pattern matching when AI unavailable
|
||||
- Use local models (Ollama) for offline capability
|
||||
|
||||
2. **Performance Impact**
|
||||
- Mitigation: Async processing, optional features
|
||||
- Configurable resource limits
|
||||
|
||||
3. **False Positives**
|
||||
- Mitigation: Confidence scoring, user confirmation
|
||||
- Learning from corrections
|
||||
|
||||
### Adoption Risks
|
||||
1. **Learning Curve**
|
||||
- Mitigation: Progressive disclosure, good defaults
|
||||
- Comprehensive examples and documentation
|
||||
|
||||
2. **Trust Issues**
|
||||
- Mitigation: Explainable suggestions, show reasoning
|
||||
- Allow manual override always
|
||||
|
||||
## Conclusion
|
||||
|
||||
This AI-assisted development workflow leverages yaze's existing infrastructure to provide immediate value with minimal new development. The phased approach ensures quick wins while building toward comprehensive AI assistance for both yaze development and ROM hacking workflows.
|
||||
|
||||
The system is designed to be:
|
||||
- **Practical**: Uses existing components, minimal new code
|
||||
- **Incremental**: Each phase delivers working features
|
||||
- **Extensible**: Easy to add new capabilities
|
||||
- **Reliable**: Fallbacks for when AI is unavailable
|
||||
|
||||
With just 1-2 weeks of development, we can have a working system that significantly improves developer productivity and ROM hacking debugging capabilities.
|
||||
230
docs/internal/plans/ai-infra-improvements.md
Normal file
230
docs/internal/plans/ai-infra-improvements.md
Normal file
@@ -0,0 +1,230 @@
|
||||
# AI Infrastructure Improvements Plan
|
||||
|
||||
**Branch:** `feature/ai-infra-improvements`
|
||||
**Created:** 2025-11-21
|
||||
**Status:** Planning
|
||||
|
||||
## Overview
|
||||
|
||||
This document outlines the gaps in yaze's AI infrastructure (gRPC services, MCP integration) and the planned improvements to make yaze-mcp fully functional for AI-assisted SNES ROM hacking.
|
||||
|
||||
## Current State Analysis
|
||||
|
||||
### yaze-mcp Tools (28 Emulator + 10 ROM = 38 total)
|
||||
|
||||
| Category | Tools | Status |
|
||||
|----------|-------|--------|
|
||||
| Emulator Lifecycle | pause, resume, reset | Working |
|
||||
| Execution Control | step_instruction, run_to_breakpoint | Working |
|
||||
| Execution Control | step_over, step_out | Partial (step_over falls back to single-step) |
|
||||
| Memory | read_memory, write_memory, get_game_state | Working |
|
||||
| Breakpoints | add/remove/list/toggle | Working (execute only during emulation) |
|
||||
| Watchpoints | add/remove/list/history | NOT WIRED (only called from RPC handlers) |
|
||||
| Disassembly | get_disassembly | Partial (returns OPCODE_XX placeholders) |
|
||||
| Tracing | get_execution_trace | BROKEN (returns FAILED_PRECONDITION) |
|
||||
| Symbols | load/resolve/get_symbol_at | DISABLED (ASAR integration disabled) |
|
||||
| ROM Basic | get_rom_info, read_rom_bytes | Working |
|
||||
| ROM Advanced | overworld/dungeon/sprite reads | NOT IMPLEMENTED (stubs return errors) |
|
||||
| ROM Versioning | create/list snapshots | Working |
|
||||
| Input | press_buttons | Working |
|
||||
|
||||
### Critical Gaps
|
||||
|
||||
1. **gRPC Server Not Started** - `AgentControlServer` exists but is never instantiated
|
||||
2. **Watchpoints Bypass Emulation** - Only triggered by RPC read/write, not CPU bus activity
|
||||
3. **Disassembly Uses Placeholders** - No proper 65816 disassembler integration
|
||||
4. **Execution Trace Not Buffered** - No ring buffer for instruction history
|
||||
5. **Symbols Disabled** - ASAR integration commented out
|
||||
6. **ROM Domain RPCs Stubbed** - Overworld/dungeon/sprite return "not yet implemented"
|
||||
|
||||
## Implementation Plan
|
||||
|
||||
### Phase 1: gRPC Server Hosting (Priority: Critical)
|
||||
|
||||
**Goal:** Stand up a unified gRPC server that registers EmulatorService + RomService
|
||||
|
||||
**Files to Modify:**
|
||||
- `src/app/editor/editor_manager.cc` - Start AgentControlServer when YAZE_ENABLE_REMOTE_AUTOMATION
|
||||
- `src/cli/service/agent/agent_control_server.cc` - Register both EmulatorService and RomService
|
||||
- `src/app/service/unified_grpc_server.cc` - Consider merging with AgentControlServer
|
||||
|
||||
**Tasks:**
|
||||
- [ ] Add `StartAgentServer()` method to EditorManager
|
||||
- [ ] Wire startup to `YAZE_ENABLE_REMOTE_AUTOMATION` flag or `--enable-grpc` CLI flag
|
||||
- [ ] Register EmulatorService and RomService on same server
|
||||
- [ ] Add configurable port (default 50051)
|
||||
- [ ] Test with yaze-mcp `check_status`
|
||||
|
||||
### Phase 2: Emulator Debug RPCs (Priority: High)
|
||||
|
||||
**Goal:** Flesh out disassembly, execution trace, and stepping
|
||||
|
||||
**2a. Proper Disassembly**
|
||||
- Use DisassemblyViewer's existing instruction recording
|
||||
- Or integrate a standalone 65816 disassembler (bsnes style)
|
||||
- File: `src/cli/service/agent/emulator_service_impl.cc` lines 661-705
|
||||
|
||||
**2b. Execution Trace Buffer**
|
||||
- Add ring buffer (1000-10000 entries) to DisassemblyViewer
|
||||
- Record: address, opcode, operands, cycle count, register snapshot
|
||||
- File: `src/app/emu/debug/disassembly_viewer.h`
|
||||
|
||||
**2c. StepOver Implementation**
|
||||
- Detect JSR (0x20) and JSL (0x22) opcodes
|
||||
- Set temporary breakpoint at return address (PC + instruction length)
|
||||
- Run until breakpoint hit, then remove temporary BP
|
||||
- File: `src/cli/service/agent/emulator_service_impl.cc` lines 598-607
|
||||
|
||||
**Tasks:**
|
||||
- [ ] Integrate real 65816 disassembly into GetDisassembly RPC
|
||||
- [ ] Add ExecutionTraceBuffer class with ring buffer
|
||||
- [ ] Implement GetExecutionTrace from buffer
|
||||
- [ ] Implement proper StepOver with JSR/JSL detection
|
||||
|
||||
### Phase 3: Breakpoint/Watchpoint Memory Integration (Priority: High)
|
||||
|
||||
**Goal:** Wire memory breakpoints and watchpoints into emulator memory bus
|
||||
|
||||
**Current State:**
|
||||
- `BreakpointManager::ShouldBreakOnExecute()` IS called via CPU callback
|
||||
- `BreakpointManager::ShouldBreakOnMemoryAccess()` IS NOT called during emulation
|
||||
- `WatchpointManager::OnMemoryAccess()` IS NOT called during emulation
|
||||
|
||||
**Files to Modify:**
|
||||
- `src/app/emu/snes.h` - Add read/write callbacks
|
||||
- `src/app/emu/snes.cc` - Invoke breakpoint/watchpoint managers in CpuRead/CpuWrite
|
||||
- `src/app/emu/emulator.cc` - Wire managers to callbacks
|
||||
|
||||
**Implementation:**
|
||||
```cpp
|
||||
// In Snes::CpuRead() or via callback:
|
||||
if (debugging_enabled_) {
|
||||
if (breakpoint_manager_.ShouldBreakOnMemoryAccess(addr, BreakpointManager::AccessType::READ)) {
|
||||
running_ = false;
|
||||
}
|
||||
watchpoint_manager_.OnMemoryAccess(addr, /*is_write=*/false, value);
|
||||
}
|
||||
|
||||
// In Snes::CpuWrite() or via callback:
|
||||
if (debugging_enabled_) {
|
||||
if (breakpoint_manager_.ShouldBreakOnMemoryAccess(addr, BreakpointManager::AccessType::WRITE)) {
|
||||
running_ = false;
|
||||
}
|
||||
watchpoint_manager_.OnMemoryAccess(addr, /*is_write=*/true, value);
|
||||
}
|
||||
```
|
||||
|
||||
**Tasks:**
|
||||
- [ ] Add `on_memory_read_` and `on_memory_write_` callbacks to CPU
|
||||
- [ ] Invoke BreakpointManager from callbacks
|
||||
- [ ] Invoke WatchpointManager from callbacks
|
||||
- [ ] Add MCP tools for watchpoints: `add_watchpoint`, `list_watchpoints`, `get_watchpoint_history`
|
||||
- [ ] Test memory breakpoints and watchpoints with yaze-mcp
|
||||
|
||||
### Phase 4: Symbol Loading & Resolution (Priority: Medium)
|
||||
|
||||
**Goal:** Load ASAR/WLA-DX/CA65 symbol files and enable label resolution
|
||||
|
||||
**Current State:**
|
||||
- EmulatorServiceImpl has stubbed symbol methods returning "not available"
|
||||
- ASAR wrapper exists in `src/core/asar_wrapper.h`
|
||||
|
||||
**Implementation Approach:**
|
||||
1. Create `SymbolTable` class to store symbols (name -> address map)
|
||||
2. Implement parsers for each format:
|
||||
- ASAR: `.sym` files with `label = $XXXXXX` format
|
||||
- WLA-DX: `.sym` files with different format
|
||||
- CA65: `.dbg` or `.map` files
|
||||
- Mesen: `.mlb` label files
|
||||
3. Wire LoadSymbols RPC to parse and populate SymbolTable
|
||||
4. Wire ResolveSymbol/GetSymbolAt to query SymbolTable
|
||||
|
||||
**Files to Create:**
|
||||
- `src/app/emu/debug/symbol_table.h`
|
||||
- `src/app/emu/debug/symbol_table.cc`
|
||||
- `src/app/emu/debug/symbol_parser.h` - Format parsers
|
||||
|
||||
**Tasks:**
|
||||
- [ ] Design SymbolTable class (bidirectional lookup)
|
||||
- [ ] Implement ASAR .sym parser
|
||||
- [ ] Implement WLA-DX parser
|
||||
- [ ] Wire to EmulatorServiceImpl
|
||||
- [ ] Test with Oracle of Secrets symbols
|
||||
|
||||
### Phase 5: ROM Domain RPCs (Priority: Medium)
|
||||
|
||||
**Goal:** Implement overworld/dungeon/sprite read/write RPCs
|
||||
|
||||
**Current State:**
|
||||
- All domain RPCs return "not yet implemented"
|
||||
- ROM class has raw access, but not structured zelda3 data
|
||||
|
||||
**Implementation:**
|
||||
- Leverage `zelda3::Overworld`, `zelda3::Dungeon`, `zelda3::Sprite` classes
|
||||
- Need to instantiate these in RomServiceImpl or get from shared state
|
||||
|
||||
**Files to Modify:**
|
||||
- `src/app/net/rom_service_impl.cc` - Implement ReadOverworldMap, ReadDungeonRoom, ReadSprite
|
||||
- Proto messages already defined in `rom_service.proto`
|
||||
|
||||
**Tasks:**
|
||||
- [ ] Add zelda3::Overworld access to RomServiceImpl
|
||||
- [ ] Implement ReadOverworldMap (tile16 data for 160 maps)
|
||||
- [ ] Implement WriteOverworldTile
|
||||
- [ ] Add zelda3::Dungeon access
|
||||
- [ ] Implement ReadDungeonRoom (tile16 data for 296 rooms)
|
||||
- [ ] Implement WriteDungeonTile
|
||||
- [ ] Implement ReadSprite
|
||||
|
||||
### Phase 6: yaze-mcp Enhancements (Priority: Low)
|
||||
|
||||
**Goal:** Improve MCP error handling and add missing tools
|
||||
|
||||
**Tasks:**
|
||||
- [ ] Add timeout/retry logic based on gRPC status codes
|
||||
- [ ] Add clearer error messages for unimplemented RPCs
|
||||
- [ ] Add watchpoint tools to server.py
|
||||
- [ ] Document required build preset and port
|
||||
- [ ] Add connection health monitoring
|
||||
|
||||
## File Reference
|
||||
|
||||
### Emulator Service
|
||||
- **Header:** `src/cli/service/agent/emulator_service_impl.h`
|
||||
- **Implementation:** `src/cli/service/agent/emulator_service_impl.cc` (822 lines)
|
||||
- **Server:** `src/cli/service/agent/agent_control_server.cc`
|
||||
|
||||
### ROM Service
|
||||
- **Header:** `src/app/net/rom_service_impl.h`
|
||||
- **Implementation:** `src/app/net/rom_service_impl.cc`
|
||||
- **Version Manager:** `src/app/net/rom_version_manager.h`
|
||||
|
||||
### Debug Managers
|
||||
- **Breakpoints:** `src/app/emu/debug/breakpoint_manager.h|cc`
|
||||
- **Watchpoints:** `src/app/emu/debug/watchpoint_manager.h|cc`
|
||||
- **Disassembly:** `src/app/emu/debug/disassembly_viewer.h`
|
||||
|
||||
### Emulator Core
|
||||
- **Emulator:** `src/app/emu/emulator.h|cc`
|
||||
- **SNES:** `src/app/emu/snes.h|cc`
|
||||
- **CPU:** `src/app/emu/cpu/cpu.h`
|
||||
|
||||
### MCP Server
|
||||
- **Location:** `/Users/scawful/Code/yaze-mcp/server.py`
|
||||
- **Proto Stubs:** `/Users/scawful/Code/yaze-mcp/protos/`
|
||||
|
||||
## Success Criteria
|
||||
|
||||
1. **yaze-mcp `check_status`** connects and returns full emulator state
|
||||
2. **Memory breakpoints** pause emulation on WRAM/SRAM access
|
||||
3. **Watchpoints** track and log all memory accesses in specified ranges
|
||||
4. **`get_disassembly`** returns proper 65816 mnemonics
|
||||
5. **`get_execution_trace`** returns last N instructions executed
|
||||
6. **Symbol loading** works with ASAR output from Oracle of Secrets
|
||||
7. **ROM domain RPCs** return structured overworld/dungeon/sprite data
|
||||
|
||||
## Notes
|
||||
|
||||
- Consider performance impact of memory access callbacks (may need optimization)
|
||||
- May want debug mode toggle to enable/disable expensive instrumentation
|
||||
- Future: Canvas automation service for GUI automation via MCP
|
||||
818
docs/internal/plans/app-dev-agent-tools.md
Normal file
818
docs/internal/plans/app-dev-agent-tools.md
Normal file
@@ -0,0 +1,818 @@
|
||||
# App Development Agent Tools Specification
|
||||
|
||||
**Document Version**: 1.0
|
||||
**Date**: 2025-11-22
|
||||
**Author**: CLAUDE_AIINF
|
||||
**Purpose**: Define tools that enable AI agents to assist with yaze C++ development
|
||||
|
||||
## Executive Summary
|
||||
|
||||
This document specifies new tools for the yaze AI agent system that enable agents to assist with C++ application development. These tools complement existing ROM manipulation and editor tools by providing build system interaction, code analysis, debugging assistance, and editor integration capabilities.
|
||||
|
||||
## Tool Architecture Overview
|
||||
|
||||
### Integration Points
|
||||
- **ToolDispatcher**: Central routing via `src/cli/service/agent/tool_dispatcher.cc`
|
||||
- **CommandHandler Pattern**: All tools inherit from `resources::CommandHandler`
|
||||
- **Output Formatting**: JSON and text formats via `resources::OutputFormatter`
|
||||
- **Security Model**: Sandboxed execution, project-restricted access
|
||||
- **Async Support**: Long-running operations use background execution
|
||||
|
||||
## Tool Specifications
|
||||
|
||||
### 1. Build System Tools
|
||||
|
||||
#### 1.1 build_configure
|
||||
**Purpose**: Configure CMake build with appropriate presets and options
|
||||
**Priority**: P0 (Critical for MVP)
|
||||
|
||||
**Parameters**:
|
||||
```cpp
|
||||
struct BuildConfigureParams {
|
||||
std::string preset; // e.g., "mac-dbg", "lin-ai", "win-rel"
|
||||
std::string build_dir; // e.g., "build_ai" (default: "build")
|
||||
bool clean_build; // Remove existing build directory first
|
||||
std::vector<std::string> options; // Additional CMake options
|
||||
};
|
||||
```
|
||||
|
||||
**Returns**:
|
||||
```json
|
||||
{
|
||||
"status": "success",
|
||||
"preset": "mac-dbg",
|
||||
"build_directory": "/Users/scawful/Code/yaze/build_ai",
|
||||
"cmake_version": "3.28.0",
|
||||
"compiler": "AppleClang 15.0.0.15000100",
|
||||
"options_applied": ["YAZE_ENABLE_AI=ON", "YAZE_ENABLE_GRPC=ON"]
|
||||
}
|
||||
```
|
||||
|
||||
**Implementation Approach**:
|
||||
- Execute `cmake --preset <preset>` via subprocess
|
||||
- Parse CMakeCache.txt for configuration details
|
||||
- Validate preset exists in CMakePresets.json
|
||||
- Support parallel build directories for agent isolation
|
||||
|
||||
---
|
||||
|
||||
#### 1.2 build_compile
|
||||
**Purpose**: Trigger compilation of specific targets or entire project
|
||||
**Priority**: P0 (Critical for MVP)
|
||||
|
||||
**Parameters**:
|
||||
```cpp
|
||||
struct BuildCompileParams {
|
||||
std::string build_dir; // Build directory (default: "build")
|
||||
std::string target; // Specific target or "all"
|
||||
int jobs; // Parallel jobs (default: CPU count)
|
||||
bool verbose; // Show detailed compiler output
|
||||
bool continue_on_error; // Continue building after errors
|
||||
};
|
||||
```
|
||||
|
||||
**Returns**:
|
||||
```json
|
||||
{
|
||||
"status": "failed",
|
||||
"target": "yaze",
|
||||
"errors": [
|
||||
{
|
||||
"file": "src/app/editor/overworld_editor.cc",
|
||||
"line": 234,
|
||||
"column": 15,
|
||||
"severity": "error",
|
||||
"message": "use of undeclared identifier 'LoadGraphics'",
|
||||
"context": " LoadGraphics();"
|
||||
}
|
||||
],
|
||||
"warnings_count": 12,
|
||||
"build_time_seconds": 45.3,
|
||||
"artifacts": ["bin/yaze", "bin/z3ed"]
|
||||
}
|
||||
```
|
||||
|
||||
**Implementation Approach**:
|
||||
- Execute `cmake --build <dir> --target <target> -j<jobs>`
|
||||
- Parse compiler output with regex patterns for errors/warnings
|
||||
- Track build timing and resource usage
|
||||
- Support incremental builds and error recovery
|
||||
|
||||
---
|
||||
|
||||
#### 1.3 build_test
|
||||
**Purpose**: Execute test suites with filtering and result parsing
|
||||
**Priority**: P0 (Critical for MVP)
|
||||
|
||||
**Parameters**:
|
||||
```cpp
|
||||
struct BuildTestParams {
|
||||
std::string build_dir; // Build directory
|
||||
std::string suite; // Test suite: "unit", "integration", "e2e", "all"
|
||||
std::string filter; // Test name filter (gtest pattern)
|
||||
bool rom_dependent; // Include ROM-dependent tests
|
||||
std::string rom_path; // Path to ROM file (if rom_dependent)
|
||||
bool show_output; // Display test output
|
||||
};
|
||||
```
|
||||
|
||||
**Returns**:
|
||||
```json
|
||||
{
|
||||
"status": "failed",
|
||||
"suite": "unit",
|
||||
"tests_run": 156,
|
||||
"tests_passed": 154,
|
||||
"tests_failed": 2,
|
||||
"failures": [
|
||||
{
|
||||
"test_name": "SnesColorTest.ConvertRgbToSnes",
|
||||
"file": "test/unit/gfx/snes_color_test.cc",
|
||||
"line": 45,
|
||||
"failure_message": "Expected: 0x7FFF\n Actual: 0x7FFE"
|
||||
}
|
||||
],
|
||||
"execution_time_seconds": 12.4,
|
||||
"coverage_percent": 78.3
|
||||
}
|
||||
```
|
||||
|
||||
**Implementation Approach**:
|
||||
- Execute ctest with appropriate labels and filters
|
||||
- Parse test output XML (if available) or stdout
|
||||
- Support test discovery and listing
|
||||
- Handle timeouts and crashes gracefully
|
||||
|
||||
---
|
||||
|
||||
#### 1.4 build_status
|
||||
**Purpose**: Query current build system state and configuration
|
||||
**Priority**: P1 (Important for debugging)
|
||||
|
||||
**Parameters**:
|
||||
```cpp
|
||||
struct BuildStatusParams {
|
||||
std::string build_dir; // Build directory to inspect
|
||||
bool show_cache; // Include CMakeCache variables
|
||||
bool show_targets; // List available build targets
|
||||
};
|
||||
```
|
||||
|
||||
**Returns**:
|
||||
```json
|
||||
{
|
||||
"configured": true,
|
||||
"preset": "mac-dbg",
|
||||
"last_build": "2025-11-22T10:30:00Z",
|
||||
"targets_available": ["yaze", "z3ed", "yaze_test", "format"],
|
||||
"configuration": {
|
||||
"CMAKE_BUILD_TYPE": "Debug",
|
||||
"YAZE_ENABLE_AI": "ON",
|
||||
"YAZE_ENABLE_GRPC": "ON"
|
||||
},
|
||||
"dirty_files": ["src/app/editor/overworld_editor.cc"],
|
||||
"build_dependencies_outdated": false
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 2. Code Analysis Tools
|
||||
|
||||
#### 2.1 find_symbol
|
||||
**Purpose**: Locate class, function, or variable definitions in codebase
|
||||
**Priority**: P0 (Critical for navigation)
|
||||
|
||||
**Parameters**:
|
||||
```cpp
|
||||
struct FindSymbolParams {
|
||||
std::string symbol_name; // Name to search for
|
||||
std::string symbol_type; // "class", "function", "variable", "any"
|
||||
std::string scope; // Directory scope (default: "src/")
|
||||
bool include_declarations; // Include forward declarations
|
||||
};
|
||||
```
|
||||
|
||||
**Returns**:
|
||||
```json
|
||||
{
|
||||
"symbol": "OverworldEditor",
|
||||
"type": "class",
|
||||
"locations": [
|
||||
{
|
||||
"file": "src/app/editor/overworld/overworld_editor.h",
|
||||
"line": 45,
|
||||
"kind": "definition",
|
||||
"context": "class OverworldEditor : public Editor {"
|
||||
},
|
||||
{
|
||||
"file": "src/app/editor/overworld/overworld_editor.cc",
|
||||
"line": 23,
|
||||
"kind": "implementation",
|
||||
"context": "OverworldEditor::OverworldEditor() {"
|
||||
}
|
||||
],
|
||||
"base_classes": ["Editor"],
|
||||
"derived_classes": [],
|
||||
"namespace": "yaze::app::editor"
|
||||
}
|
||||
```
|
||||
|
||||
**Implementation Approach**:
|
||||
- Use ctags/cscope database if available
|
||||
- Fall back to intelligent grep patterns
|
||||
- Parse include guards and namespace blocks
|
||||
- Cache symbol database for performance
|
||||
|
||||
---
|
||||
|
||||
#### 2.2 get_call_hierarchy
|
||||
**Purpose**: Analyze function call relationships
|
||||
**Priority**: P1 (Important for refactoring)
|
||||
|
||||
**Parameters**:
|
||||
```cpp
|
||||
struct CallHierarchyParams {
|
||||
std::string function_name; // Function to analyze
|
||||
std::string direction; // "callers", "callees", "both"
|
||||
int max_depth; // Recursion depth (default: 3)
|
||||
bool include_virtual; // Track virtual function calls
|
||||
};
|
||||
```
|
||||
|
||||
**Returns**:
|
||||
```json
|
||||
{
|
||||
"function": "Rom::LoadFromFile",
|
||||
"callers": [
|
||||
{
|
||||
"function": "EditorManager::OpenRom",
|
||||
"file": "src/app/editor/editor_manager.cc",
|
||||
"line": 156,
|
||||
"call_sites": [{"line": 162, "context": "rom_->LoadFromFile(path)"}]
|
||||
}
|
||||
],
|
||||
"callees": [
|
||||
{
|
||||
"function": "Rom::ReadAllGraphicsData",
|
||||
"file": "src/app/rom.cc",
|
||||
"line": 234,
|
||||
"is_virtual": false
|
||||
}
|
||||
],
|
||||
"complexity_score": 12
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
#### 2.3 get_class_members
|
||||
**Purpose**: List all methods and fields of a class
|
||||
**Priority**: P1 (Important for understanding)
|
||||
|
||||
**Parameters**:
|
||||
```cpp
|
||||
struct ClassMembersParams {
|
||||
std::string class_name; // Class to analyze
|
||||
bool include_inherited; // Include base class members
|
||||
bool include_private; // Include private members
|
||||
std::string filter; // Filter by member name pattern
|
||||
};
|
||||
```
|
||||
|
||||
**Returns**:
|
||||
```json
|
||||
{
|
||||
"class": "OverworldEditor",
|
||||
"namespace": "yaze::app::editor",
|
||||
"members": {
|
||||
"methods": [
|
||||
{
|
||||
"name": "Update",
|
||||
"signature": "absl::Status Update() override",
|
||||
"visibility": "public",
|
||||
"is_virtual": true,
|
||||
"line": 67
|
||||
}
|
||||
],
|
||||
"fields": [
|
||||
{
|
||||
"name": "current_map_",
|
||||
"type": "int",
|
||||
"visibility": "private",
|
||||
"line": 234,
|
||||
"has_getter": true,
|
||||
"has_setter": false
|
||||
}
|
||||
]
|
||||
},
|
||||
"base_classes": ["Editor"],
|
||||
"total_methods": 42,
|
||||
"total_fields": 18
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
#### 2.4 analyze_includes
|
||||
**Purpose**: Show include dependency graph
|
||||
**Priority**: P2 (Useful for optimization)
|
||||
|
||||
**Parameters**:
|
||||
```cpp
|
||||
struct AnalyzeIncludesParams {
|
||||
std::string file_path; // File to analyze
|
||||
std::string direction; // "includes", "included_by", "both"
|
||||
bool show_system; // Include system headers
|
||||
int max_depth; // Recursion depth
|
||||
};
|
||||
```
|
||||
|
||||
**Returns**:
|
||||
```json
|
||||
{
|
||||
"file": "src/app/editor/overworld_editor.cc",
|
||||
"direct_includes": [
|
||||
{"file": "overworld_editor.h", "is_system": false},
|
||||
{"file": "app/rom.h", "is_system": false},
|
||||
{"file": <vector>", "is_system": true}
|
||||
],
|
||||
"included_by": [
|
||||
"src/app/editor/editor_manager.cc"
|
||||
],
|
||||
"include_depth": 3,
|
||||
"circular_dependencies": [],
|
||||
"suggestions": ["Consider forward declaration for 'Rom' class"]
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 3. Debug Tools
|
||||
|
||||
#### 3.1 parse_crash_log
|
||||
**Purpose**: Extract actionable information from crash dumps
|
||||
**Priority**: P0 (Critical for debugging)
|
||||
|
||||
**Parameters**:
|
||||
```cpp
|
||||
struct ParseCrashLogParams {
|
||||
std::string log_path; // Path to crash log or stdin
|
||||
std::string platform; // "macos", "linux", "windows", "auto"
|
||||
bool symbolicate; // Attempt to resolve symbols
|
||||
};
|
||||
```
|
||||
|
||||
**Returns**:
|
||||
```json
|
||||
{
|
||||
"crash_type": "SIGSEGV",
|
||||
"crash_address": "0x00000000",
|
||||
"crashed_thread": 0,
|
||||
"stack_trace": [
|
||||
{
|
||||
"frame": 0,
|
||||
"address": "0x10234abcd",
|
||||
"symbol": "yaze::app::editor::OverworldEditor::RenderMap",
|
||||
"file": "src/app/editor/overworld_editor.cc",
|
||||
"line": 456,
|
||||
"is_user_code": true
|
||||
}
|
||||
],
|
||||
"likely_cause": "Null pointer dereference in RenderMap",
|
||||
"suggested_fixes": [
|
||||
"Check if 'current_map_data_' is initialized before use",
|
||||
"Add null check at line 456"
|
||||
],
|
||||
"similar_crashes": ["#1234 - Fixed in commit abc123"]
|
||||
}
|
||||
```
|
||||
|
||||
**Implementation Approach**:
|
||||
- Parse platform-specific crash formats (lldb, gdb, Windows dumps)
|
||||
- Symbolicate addresses using debug symbols
|
||||
- Identify patterns (null deref, stack overflow, etc.)
|
||||
- Search issue tracker for similar crashes
|
||||
|
||||
---
|
||||
|
||||
#### 3.2 get_memory_profile
|
||||
**Purpose**: Analyze memory usage and detect leaks
|
||||
**Priority**: P2 (Useful for optimization)
|
||||
|
||||
**Parameters**:
|
||||
```cpp
|
||||
struct MemoryProfileParams {
|
||||
std::string process_name; // Process to analyze or PID
|
||||
std::string profile_type; // "snapshot", "leaks", "allocations"
|
||||
int duration_seconds; // For allocation profiling
|
||||
};
|
||||
```
|
||||
|
||||
**Returns**:
|
||||
```json
|
||||
{
|
||||
"total_memory_mb": 234.5,
|
||||
"heap_size_mb": 180.2,
|
||||
"largest_allocations": [
|
||||
{
|
||||
"size_mb": 45.6,
|
||||
"location": "gfx::Arena::LoadAllGraphics",
|
||||
"count": 223,
|
||||
"type": "gfx::Bitmap"
|
||||
}
|
||||
],
|
||||
"potential_leaks": [
|
||||
{
|
||||
"size_bytes": 1024,
|
||||
"allocation_site": "CreateTempBuffer at editor.cc:123",
|
||||
"leak_confidence": 0.85
|
||||
}
|
||||
],
|
||||
"memory_growth_rate_mb_per_min": 2.3
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
#### 3.3 analyze_performance
|
||||
**Purpose**: Profile performance hotspots
|
||||
**Priority**: P2 (Useful for optimization)
|
||||
|
||||
**Parameters**:
|
||||
```cpp
|
||||
struct PerformanceAnalysisParams {
|
||||
std::string target; // Binary or test to profile
|
||||
std::string scenario; // Specific scenario to profile
|
||||
int duration_seconds; // Profiling duration
|
||||
std::string metric; // "cpu", "memory", "io", "all"
|
||||
};
|
||||
```
|
||||
|
||||
**Returns**:
|
||||
```json
|
||||
{
|
||||
"hotspots": [
|
||||
{
|
||||
"function": "gfx::Bitmap::ApplyPalette",
|
||||
"cpu_percent": 23.4,
|
||||
"call_count": 1000000,
|
||||
"avg_duration_us": 12.3,
|
||||
"file": "src/app/gfx/bitmap.cc",
|
||||
"line": 234
|
||||
}
|
||||
],
|
||||
"bottlenecks": [
|
||||
"Graphics rendering taking 65% of frame time",
|
||||
"Excessive allocations in tile loading"
|
||||
],
|
||||
"optimization_suggestions": [
|
||||
"Cache palette conversions",
|
||||
"Use SIMD for pixel operations"
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 4. Editor Integration Tools
|
||||
|
||||
#### 4.1 get_canvas_state
|
||||
**Purpose**: Query current canvas/editor state for context
|
||||
**Priority**: P1 (Important for automation)
|
||||
|
||||
**Parameters**:
|
||||
```cpp
|
||||
struct CanvasStateParams {
|
||||
std::string editor_type; // "overworld", "dungeon", "graphics"
|
||||
bool include_selection; // Include selected entities
|
||||
bool include_viewport; // Include camera/zoom info
|
||||
};
|
||||
```
|
||||
|
||||
**Returns**:
|
||||
```json
|
||||
{
|
||||
"editor": "overworld",
|
||||
"current_map": 0x00,
|
||||
"map_name": "Hyrule Field",
|
||||
"viewport": {
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"width": 512,
|
||||
"height": 512,
|
||||
"zoom": 2.0
|
||||
},
|
||||
"selection": {
|
||||
"type": "entrance",
|
||||
"id": 0x03,
|
||||
"position": {"x": 256, "y": 128}
|
||||
},
|
||||
"tool": "select",
|
||||
"modified": true,
|
||||
"undo_stack_size": 15
|
||||
}
|
||||
```
|
||||
|
||||
**Implementation Approach**:
|
||||
- Query EditorManager for active editor
|
||||
- Use Canvas automation API for state extraction
|
||||
- Serialize entity selections and properties
|
||||
- Include modification tracking
|
||||
|
||||
---
|
||||
|
||||
#### 4.2 simulate_user_action
|
||||
**Purpose**: Trigger UI actions programmatically
|
||||
**Priority**: P1 (Important for automation)
|
||||
|
||||
**Parameters**:
|
||||
```cpp
|
||||
struct SimulateActionParams {
|
||||
std::string action_type; // "click", "drag", "key", "menu"
|
||||
nlohmann::json parameters; // Action-specific parameters
|
||||
std::string editor_context; // Which editor to target
|
||||
};
|
||||
```
|
||||
|
||||
**Returns**:
|
||||
```json
|
||||
{
|
||||
"action": "click",
|
||||
"target": "tile_palette",
|
||||
"position": {"x": 100, "y": 50},
|
||||
"result": "success",
|
||||
"new_selection": {
|
||||
"tile_id": 0x42,
|
||||
"tile_type": "grass"
|
||||
},
|
||||
"side_effects": ["Tool changed to 'paint'"]
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
#### 4.3 capture_screenshot
|
||||
**Purpose**: Capture editor visuals for verification or documentation
|
||||
**Priority**: P2 (Useful for testing)
|
||||
|
||||
**Parameters**:
|
||||
```cpp
|
||||
struct ScreenshotParams {
|
||||
std::string output_path; // Where to save screenshot
|
||||
std::string target; // "full", "canvas", "window"
|
||||
std::string format; // "png", "jpg", "bmp"
|
||||
bool include_ui; // Include UI overlays
|
||||
};
|
||||
```
|
||||
|
||||
**Returns**:
|
||||
```json
|
||||
{
|
||||
"status": "success",
|
||||
"file_path": "/tmp/screenshot_2025_11_22_103045.png",
|
||||
"dimensions": {"width": 1920, "height": 1080},
|
||||
"file_size_kb": 234,
|
||||
"metadata": {
|
||||
"editor": "overworld",
|
||||
"map_id": "0x00",
|
||||
"timestamp": "2025-11-22T10:30:45Z"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Implementation Roadmap
|
||||
|
||||
### Phase 1: MVP (Week 1)
|
||||
**Priority P0 tools only**
|
||||
1. `build_compile` - Essential for development iteration
|
||||
2. `build_test` - Required for validation
|
||||
3. `find_symbol` - Core navigation capability
|
||||
4. `parse_crash_log` - Critical debugging tool
|
||||
|
||||
### Phase 2: Enhanced (Week 2)
|
||||
**Priority P1 tools**
|
||||
1. `build_configure` - Build system management
|
||||
2. `build_status` - State inspection
|
||||
3. `get_call_hierarchy` - Code understanding
|
||||
4. `get_class_members` - API exploration
|
||||
5. `get_canvas_state` - Editor integration
|
||||
6. `simulate_user_action` - Automation capability
|
||||
|
||||
### Phase 3: Complete (Week 3)
|
||||
**Priority P2 tools**
|
||||
1. `analyze_includes` - Optimization support
|
||||
2. `get_memory_profile` - Memory debugging
|
||||
3. `analyze_performance` - Performance tuning
|
||||
4. `capture_screenshot` - Visual verification
|
||||
|
||||
## Integration with Existing Infrastructure
|
||||
|
||||
### ToolDispatcher Integration
|
||||
|
||||
Add to `tool_dispatcher.h`:
|
||||
```cpp
|
||||
enum class ToolCallType {
|
||||
// ... existing types ...
|
||||
|
||||
// Build Tools
|
||||
kBuildConfigure,
|
||||
kBuildCompile,
|
||||
kBuildTest,
|
||||
kBuildStatus,
|
||||
|
||||
// Code Analysis
|
||||
kCodeFindSymbol,
|
||||
kCodeGetCallHierarchy,
|
||||
kCodeGetClassMembers,
|
||||
kCodeAnalyzeIncludes,
|
||||
|
||||
// Debug Tools
|
||||
kDebugParseCrashLog,
|
||||
kDebugGetMemoryProfile,
|
||||
kDebugAnalyzePerformance,
|
||||
|
||||
// Editor Integration
|
||||
kEditorGetCanvasState,
|
||||
kEditorSimulateAction,
|
||||
kEditorCaptureScreenshot,
|
||||
};
|
||||
```
|
||||
|
||||
### Handler Implementation Pattern
|
||||
|
||||
Each tool follows the CommandHandler pattern:
|
||||
|
||||
```cpp
|
||||
class BuildCompileCommandHandler : public resources::CommandHandler {
|
||||
public:
|
||||
std::string GetName() const override { return "build-compile"; }
|
||||
|
||||
std::string GetUsage() const override {
|
||||
return "build-compile --build-dir <dir> [--target <name>] "
|
||||
"[--jobs <n>] [--verbose] [--format <json|text>]";
|
||||
}
|
||||
|
||||
protected:
|
||||
absl::Status ValidateArgs(const resources::ArgumentParser& parser) override {
|
||||
// Validate required arguments
|
||||
return absl::OkStatus();
|
||||
}
|
||||
|
||||
absl::Status Execute(Rom* rom, const resources::ArgumentParser& parser,
|
||||
resources::OutputFormatter& formatter) override {
|
||||
// Implementation
|
||||
return absl::OkStatus();
|
||||
}
|
||||
|
||||
bool RequiresLabels() const override { return false; }
|
||||
};
|
||||
```
|
||||
|
||||
### Security Considerations
|
||||
|
||||
1. **Build System Tools**:
|
||||
- Restrict to project directory
|
||||
- Validate presets against CMakePresets.json
|
||||
- Sanitize compiler flags
|
||||
- Limit parallel jobs to prevent DoS
|
||||
|
||||
2. **Code Analysis Tools**:
|
||||
- Read-only operations only
|
||||
- Cache results to prevent excessive parsing
|
||||
- Timeout long-running analyses
|
||||
|
||||
3. **Debug Tools**:
|
||||
- Sanitize crash log paths
|
||||
- Limit profiling duration
|
||||
- Prevent access to system processes
|
||||
|
||||
4. **Editor Integration**:
|
||||
- Rate limit UI actions
|
||||
- Validate action parameters
|
||||
- Prevent infinite loops in automation
|
||||
|
||||
## Testing Strategy
|
||||
|
||||
### Unit Tests
|
||||
- Mock subprocess execution for build tools
|
||||
- Test error parsing with known compiler outputs
|
||||
- Verify security restrictions (path traversal, etc.)
|
||||
|
||||
### Integration Tests
|
||||
- Test with real CMake builds (small test projects)
|
||||
- Verify symbol finding with known codebase structure
|
||||
- Test crash parsing with sample logs
|
||||
|
||||
### End-to-End Tests
|
||||
- Full development workflow automation
|
||||
- Build → Test → Debug cycle
|
||||
- Editor automation scenarios
|
||||
|
||||
## Performance Considerations
|
||||
|
||||
1. **Caching**:
|
||||
- Symbol database caching (5-minute TTL)
|
||||
- Build status caching (invalidate on file changes)
|
||||
- Compiler error pattern cache
|
||||
|
||||
2. **Async Operations**:
|
||||
- Long builds run in background
|
||||
- Profiling operations are async
|
||||
- Support streaming output for progress
|
||||
|
||||
3. **Resource Limits**:
|
||||
- Max parallel build jobs = CPU count
|
||||
- Profiling duration cap = 5 minutes
|
||||
- Screenshot size limit = 10MB
|
||||
|
||||
## Success Metrics
|
||||
|
||||
1. **Developer Productivity**:
|
||||
- Reduce build debugging time by 50%
|
||||
- Enable AI agents to fix 80% of simple compilation errors
|
||||
- Automate 60% of test failure investigations
|
||||
|
||||
2. **Code Quality**:
|
||||
- Increase test coverage by 20% through AI-generated tests
|
||||
- Identify 90% of memory leaks before release
|
||||
- Reduce performance regressions by 40%
|
||||
|
||||
3. **Agent Capabilities**:
|
||||
- Agents can complete full edit-compile-test cycles
|
||||
- Agents can diagnose and suggest fixes for crashes
|
||||
- Agents can navigate and understand codebase structure
|
||||
|
||||
## Appendix A: Error Pattern Database
|
||||
|
||||
Common compilation error patterns for parsing:
|
||||
|
||||
```regex
|
||||
# GCC/Clang error
|
||||
^([^:]+):(\d+):(\d+):\s+(error|warning):\s+(.+)$
|
||||
|
||||
# MSVC error
|
||||
^([^(]+)\((\d+)\):\s+(error|warning)\s+(\w+):\s+(.+)$
|
||||
|
||||
# Linker error
|
||||
^(ld|link):\s+(error|warning):\s+(.+)$
|
||||
```
|
||||
|
||||
## Appendix B: Platform-Specific Considerations
|
||||
|
||||
### macOS
|
||||
- Use `xcrun` for toolchain discovery
|
||||
- Parse `.crash` files from `~/Library/Logs/DiagnosticReports/`
|
||||
- Support both x86_64 and arm64 architectures
|
||||
|
||||
### Linux
|
||||
- Check for gcc/g++ and clang/clang++
|
||||
- Parse core dumps with gdb
|
||||
- Use `perf` for profiling when available
|
||||
|
||||
### Windows
|
||||
- Handle both MSVC and MinGW toolchains
|
||||
- Parse `.dmp` files for crash analysis
|
||||
- Use Windows Performance Toolkit for profiling
|
||||
|
||||
## Appendix C: AI Agent Use Cases
|
||||
|
||||
### Use Case 1: Compilation Error Resolution
|
||||
```
|
||||
Agent: I see you have a compilation error in overworld_editor.cc
|
||||
Agent: Let me analyze the error...
|
||||
[Executes: build_compile --verbose]
|
||||
[Executes: find_symbol --symbol LoadGraphics]
|
||||
Agent: The function LoadGraphics was renamed to LoadAreaGraphics in commit abc123
|
||||
Agent: I'll update the call site...
|
||||
[Modifies file]
|
||||
[Executes: build_compile --target yaze]
|
||||
Agent: Build successful! The error is resolved.
|
||||
```
|
||||
|
||||
### Use Case 2: Test Failure Investigation
|
||||
```
|
||||
Agent: The SnesColorTest is failing. Let me investigate...
|
||||
[Executes: build_test --filter "*SnesColor*" --show-output]
|
||||
[Executes: get_class_members --class SnesColor]
|
||||
Agent: The test expects 0x7FFF but gets 0x7FFE
|
||||
Agent: This is a rounding error in the conversion function
|
||||
[Analyzes implementation]
|
||||
Agent: The issue is at line 45 - we need to round instead of truncate
|
||||
```
|
||||
|
||||
### Use Case 3: Performance Optimization
|
||||
```
|
||||
Agent: Let me profile the slow rendering...
|
||||
[Executes: analyze_performance --scenario "load_overworld"]
|
||||
Agent: I found that ApplyPalette takes 23% of CPU time
|
||||
[Executes: get_call_hierarchy --function ApplyPalette]
|
||||
Agent: It's called 1M times per frame - that's excessive
|
||||
Agent: I suggest caching the palette conversions...
|
||||
```
|
||||
|
||||
## Document History
|
||||
|
||||
- 2025-11-22: Initial specification (v1.0) - CLAUDE_AIINF
|
||||
1334
docs/internal/plans/asm-debug-prompt-engineering.md
Normal file
1334
docs/internal/plans/asm-debug-prompt-engineering.md
Normal file
File diff suppressed because it is too large
Load Diff
70
docs/internal/plans/branch_organization.md
Normal file
70
docs/internal/plans/branch_organization.md
Normal file
@@ -0,0 +1,70 @@
|
||||
# Branch Organization Plan
|
||||
|
||||
The current workspace has a significant number of unstaged changes covering multiple distinct areas of work. To maintain a clean history and facilitate parallel development, these should be split into the following branches:
|
||||
|
||||
## 1. `feature/debugger-disassembler`
|
||||
**Purpose**: Implementation of the new debugging and disassembly tools.
|
||||
**Files**:
|
||||
- `src/app/emu/debug/disassembler.cc` / `.h`
|
||||
- `src/app/emu/debug/step_controller.cc` / `.h`
|
||||
- `src/app/emu/debug/symbol_provider.cc` / `.h`
|
||||
- `src/cli/service/agent/disassembler_65816.cc` / `.h`
|
||||
- `src/cli/service/agent/rom_debug_agent.cc` / `.h`
|
||||
- `src/cli/service/agent/memory_debugging_example.cc`
|
||||
- `test/unit/emu/disassembler_test.cc`
|
||||
- `test/unit/emu/step_controller_test.cc`
|
||||
- `test/unit/cli/rom_debug_agent_test.cc`
|
||||
- `test/integration/memory_debugging_test.cc`
|
||||
|
||||
## 2. `infra/ci-test-overhaul`
|
||||
**Purpose**: Updates to CI workflows, test configuration, and agent documentation.
|
||||
**Files**:
|
||||
- `.github/actions/run-tests/action.yml`
|
||||
- `.github/workflows/ci.yml`
|
||||
- `.github/workflows/release.yml`
|
||||
- `.github/workflows/nightly.yml`
|
||||
- `AGENTS.md`
|
||||
- `CLAUDE.md`
|
||||
- `docs/internal/agents/*`
|
||||
- `cmake/options.cmake`
|
||||
- `cmake/packaging/cpack.cmake`
|
||||
- `src/app/test/test.cmake`
|
||||
- `test/test.cmake`
|
||||
- `test/README.md`
|
||||
|
||||
## 3. `test/e2e-dungeon-coverage`
|
||||
**Purpose**: Extensive additions to E2E and integration tests for the Dungeon Editor.
|
||||
**Files**:
|
||||
- `test/e2e/dungeon_*`
|
||||
- `test/integration/zelda3/dungeon_*`
|
||||
- `test/unit/zelda3/dungeon/object_rendering_test.cc`
|
||||
|
||||
## 4. `feature/agent-ui-improvements`
|
||||
**Purpose**: Enhancements to the Agent Chat Widget and Proposal Drawer.
|
||||
**Files**:
|
||||
- `src/app/editor/agent/agent_chat_widget.cc`
|
||||
- `src/app/editor/system/proposal_drawer.cc`
|
||||
- `src/cli/service/agent/tool_dispatcher.cc` / `.h`
|
||||
- `src/cli/service/ai/prompt_builder.cc`
|
||||
|
||||
## 5. `fix/overworld-logic`
|
||||
**Purpose**: Fixes or modifications to Overworld logic (possibly related to the other agent's work).
|
||||
**Files**:
|
||||
- `src/zelda3/overworld/overworld.cc`
|
||||
- `src/zelda3/overworld/overworld.h`
|
||||
- `test/e2e/overworld/overworld_e2e_test.cc`
|
||||
- `test/integration/zelda3/overworld_integration_test.cc`
|
||||
|
||||
## 6. `chore/misc-cleanup`
|
||||
**Purpose**: Miscellaneous cleanups and minor fixes.
|
||||
**Files**:
|
||||
- `src/CMakeLists.txt`
|
||||
- `src/app/editor/editor_library.cmake`
|
||||
- `test/yaze_test.cc`
|
||||
- `test/test_utils.cc`
|
||||
- `test/test_editor.cc`
|
||||
|
||||
## Action Items
|
||||
1. Review this list with the user (if they were here, but I will assume this is the plan).
|
||||
2. For the current task (UI/UX), I should likely branch off `master` (or the current state if dependencies exist) but be careful not to include unrelated changes in my commits if I were to commit.
|
||||
3. Since I am in an agentic mode, I will proceed by assuming these changes are "work in progress" and I should try to touch only what is necessary for UI/UX, or if I need to clean up, I should be aware of these boundaries.
|
||||
112
docs/internal/plans/branch_recovery_plan.md
Normal file
112
docs/internal/plans/branch_recovery_plan.md
Normal file
@@ -0,0 +1,112 @@
|
||||
# Branch Recovery Plan
|
||||
|
||||
**Date**: 2024-11-22
|
||||
**Status**: COMPLETED - All changes organized
|
||||
**Context**: Gemini 3 was interrupted, Claude 4.5 and GPT-OSS 120 attempted to help. Claude (Sonnet 4.5) completed reorganization.
|
||||
|
||||
## Final State Summary
|
||||
|
||||
All ~112 files have been organized into logical branches. Each branch has a clean, focused commit.
|
||||
|
||||
### Branch Status
|
||||
|
||||
| Branch | Commit | Files | Description |
|
||||
|--------|--------|-------|-------------|
|
||||
| `feature/agent-ui-improvements` | `29931139f5` | 19 files | Agent UI, tool dispatcher, dev assist tools |
|
||||
| `infra/ci-test-overhaul` | `aa411a5d1b` | 23 files | CI/CD workflows, test infrastructure, docs |
|
||||
| `test/e2e-dungeon-coverage` | `28147624a3` | 18 files | Dungeon E2E and integration tests |
|
||||
| `chore/misc-cleanup` | `a01a630c7f` | 39 files | Misc cleanup, docs, unit tests, style |
|
||||
| `fix/overworld-logic` | `00fef1169d` | 2 files | Overworld test fixes |
|
||||
| `backup/all-uncommitted-work-2024-11-22` | `5e32a8983f` | 112 files | Full backup (safety net) |
|
||||
|
||||
### What's in Each Branch
|
||||
|
||||
**`feature/agent-ui-improvements`** (Ready for review)
|
||||
- `src/app/editor/agent/agent_chat_widget.cc`
|
||||
- `src/app/editor/agent/agent_editor.cc`
|
||||
- `src/app/editor/system/proposal_drawer.cc`
|
||||
- `src/cli/service/agent/tool_dispatcher.cc/.h`
|
||||
- `src/cli/service/agent/dev_assist_agent.cc/.h`
|
||||
- `src/cli/service/agent/tools/*` (new tool modules)
|
||||
- `src/cli/service/agent/emulator_service_impl.cc/.h`
|
||||
- `src/cli/service/ai/prompt_builder.cc`
|
||||
- `src/cli/tui/command_palette.cc`
|
||||
- `test/integration/agent/tool_dispatcher_test.cc`
|
||||
|
||||
**`infra/ci-test-overhaul`** (Ready for review)
|
||||
- `.github/workflows/ci.yml`, `release.yml`, `nightly.yml`
|
||||
- `.github/actions/run-tests/action.yml`
|
||||
- `cmake/options.cmake`, `cmake/packaging/cpack.cmake`
|
||||
- `AGENTS.md`, `CLAUDE.md`
|
||||
- `docs/internal/agents/*` (coordination docs)
|
||||
- `docs/internal/ci-and-testing.md`
|
||||
- `docs/internal/CI-TEST-STRATEGY.md`
|
||||
- `test/test.cmake`, `test/README.md`
|
||||
|
||||
**`test/e2e-dungeon-coverage`** (Ready for review)
|
||||
- `test/e2e/dungeon_canvas_interaction_test.cc/.h`
|
||||
- `test/e2e/dungeon_e2e_tests.cc/.h`
|
||||
- `test/e2e/dungeon_layer_rendering_test.cc/.h`
|
||||
- `test/e2e/dungeon_object_drawing_test.cc/.h`
|
||||
- `test/e2e/dungeon_visual_verification_test.cc/.h`
|
||||
- `test/integration/zelda3/dungeon_*`
|
||||
- `test/unit/zelda3/dungeon/object_rendering_test.cc`
|
||||
- `docs/internal/testing/dungeon-gui-test-design.md`
|
||||
|
||||
**`chore/misc-cleanup`** (Ready for review)
|
||||
- `src/CMakeLists.txt`, `src/app/editor/editor_library.cmake`
|
||||
- `src/app/controller.cc`, `src/app/main.cc`
|
||||
- `src/app/service/canvas_automation_service.cc`
|
||||
- `src/app/gui/style/theme.h`
|
||||
- `docs/internal/architecture/*`
|
||||
- `docs/internal/plans/*` (including this file)
|
||||
- `test/yaze_test.cc`, `test/test_utils.cc`, `test/test_editor.cc`
|
||||
- Various unit tests updates
|
||||
|
||||
**`fix/overworld-logic`** (Ready for review)
|
||||
- `test/integration/zelda3/overworld_integration_test.cc`
|
||||
- `test/unit/zelda3/overworld_test.cc`
|
||||
|
||||
## Items NOT Committed (Still Untracked)
|
||||
|
||||
These items remain untracked and need manual attention:
|
||||
- `.tmp/` - Contains ZScreamDungeon submodule (should be in .gitignore?)
|
||||
- `third_party/bloaty` - Another git repo (should be submodule?)
|
||||
- `CIRCULAR_DEPENDENCY_*.md` - Temporary analysis artifacts (delete?)
|
||||
- `FIX_CIRCULAR_DEPS.patch` - Temporary patch (delete?)
|
||||
- `debug_crash.lldb` - Debug file (delete)
|
||||
- `fix_dungeon_colors.py` - One-off script (delete?)
|
||||
- `test_grpc_server.sh` - Test script (keep or delete?)
|
||||
|
||||
## Recommended Merge Order
|
||||
|
||||
1. **First**: `infra/ci-test-overhaul` - Updates CI and test infrastructure
|
||||
2. **Second**: `test/e2e-dungeon-coverage` - Adds new tests
|
||||
3. **Third**: `feature/agent-ui-improvements` - Agent improvements
|
||||
4. **Fourth**: `fix/overworld-logic` - Small test fix
|
||||
5. **Last**: `chore/misc-cleanup` - Docs and cleanup (may need rebasing)
|
||||
|
||||
## Notes for Gemini 3
|
||||
|
||||
- All branches are based on `master` at commit `0d18c521a1`
|
||||
- The `feature/debugger-disassembler` branch still has its original commit - preserved
|
||||
- Stashes are still available if needed (`git stash list`)
|
||||
- The `backup/all-uncommitted-work-2024-11-22` branch has EVERYTHING as a safety net
|
||||
- Consider creating PRs for review before merging
|
||||
|
||||
## Quick Commands
|
||||
|
||||
```bash
|
||||
# See all organized branches
|
||||
git branch -a | grep -E '(feature|infra|test|chore|fix|backup)/'
|
||||
|
||||
# View commits on a branch
|
||||
git log --oneline master..branch-name
|
||||
|
||||
# Merge a branch (after review)
|
||||
git checkout master
|
||||
git merge --no-ff branch-name
|
||||
|
||||
# Delete backup after all merges confirmed
|
||||
git branch -D backup/all-uncommitted-work-2024-11-22
|
||||
```
|
||||
510
docs/internal/plans/emulator-debug-api-design.md
Normal file
510
docs/internal/plans/emulator-debug-api-design.md
Normal file
@@ -0,0 +1,510 @@
|
||||
# Emulator Debug API Design for AI Agent Integration
|
||||
|
||||
## Executive Summary
|
||||
|
||||
This document outlines the design for a comprehensive debugging API that enables AI agents to debug Zelda ROM hacks through the yaze emulator. The API provides execution control, memory inspection, disassembly, and analysis capabilities specifically tailored for 65816 and SPC700 debugging.
|
||||
|
||||
## Architecture Overview
|
||||
|
||||
```
|
||||
┌──────────────────┐ ┌─────────────────┐ ┌──────────────────┐
|
||||
│ AI Agent │◄────►│ Tool Dispatcher │◄────►│ gRPC Service │
|
||||
│ (Claude/GPT) │ │ │ │ │
|
||||
└──────────────────┘ └─────────────────┘ └──────────────────┘
|
||||
│ │
|
||||
▼ ▼
|
||||
┌─────────────────┐ ┌──────────────────┐
|
||||
│ Tool Handlers │ │ Emulator Service │
|
||||
│ │ │ Implementation │
|
||||
└─────────────────┘ └──────────────────┘
|
||||
│ │
|
||||
▼ ▼
|
||||
┌─────────────────────────────────────────┐
|
||||
│ Debug Infrastructure │
|
||||
├─────────────────┬───────────────────────┤
|
||||
│ Disassembler │ Step Controller │
|
||||
│ Symbol Provider │ Breakpoint Manager │
|
||||
│ Memory Tracker │ State Snapshots │
|
||||
└─────────────────┴───────────────────────┘
|
||||
```
|
||||
|
||||
## Phase 1 (MVP) Features
|
||||
|
||||
### 1. Execution Control API
|
||||
|
||||
```cpp
|
||||
// Tool Dispatcher Commands
|
||||
enum class EmulatorDebugTool {
|
||||
// Basic execution
|
||||
kDebugRun, // Run until breakpoint or pause
|
||||
kDebugStep, // Single instruction step
|
||||
kDebugStepOver, // Step over JSR/JSL calls
|
||||
kDebugStepOut, // Step out of current subroutine
|
||||
kDebugPause, // Pause execution
|
||||
kDebugReset, // Reset to power-on state
|
||||
|
||||
// Breakpoint management
|
||||
kDebugSetBreak, // Set execution breakpoint
|
||||
kDebugClearBreak, // Clear breakpoint by ID
|
||||
kDebugListBreaks, // List all breakpoints
|
||||
kDebugToggleBreak, // Enable/disable breakpoint
|
||||
};
|
||||
```
|
||||
|
||||
#### Example Tool Call Structure:
|
||||
```cpp
|
||||
struct DebugStepRequest {
|
||||
enum StepType {
|
||||
SINGLE, // One instruction
|
||||
OVER, // Step over calls
|
||||
OUT, // Step out of routine
|
||||
TO_ADDRESS // Run to specific address
|
||||
};
|
||||
|
||||
StepType type;
|
||||
uint32_t target_address; // For TO_ADDRESS
|
||||
uint32_t max_steps; // Timeout protection
|
||||
};
|
||||
|
||||
struct DebugStepResponse {
|
||||
bool success;
|
||||
uint32_t pc; // New program counter
|
||||
uint32_t instruction_count;
|
||||
DisassembledInstruction current_instruction;
|
||||
std::vector<std::string> call_stack;
|
||||
std::string message;
|
||||
};
|
||||
```
|
||||
|
||||
### 2. Memory Inspection API
|
||||
|
||||
```cpp
|
||||
enum class MemoryDebugTool {
|
||||
kMemoryRead, // Read memory region
|
||||
kMemoryWrite, // Write memory (for patching)
|
||||
kMemoryWatch, // Set memory watchpoint
|
||||
kMemoryCompare, // Compare two memory regions
|
||||
kMemorySearch, // Search for byte pattern
|
||||
kMemorySnapshot, // Save memory state
|
||||
kMemoryDiff, // Diff against snapshot
|
||||
};
|
||||
```
|
||||
|
||||
#### Memory Region Types:
|
||||
```cpp
|
||||
enum class MemoryRegion {
|
||||
WRAM, // Work RAM ($7E0000-$7FFFFF)
|
||||
SRAM, // Save RAM ($700000-$77FFFF)
|
||||
ROM, // ROM banks ($008000-$FFFFFF)
|
||||
VRAM, // Video RAM (PPU)
|
||||
OAM, // Sprite data
|
||||
CGRAM, // Palette data
|
||||
APU_RAM, // Audio RAM ($0000-$FFFF in SPC700 space)
|
||||
};
|
||||
|
||||
struct MemoryReadRequest {
|
||||
MemoryRegion region;
|
||||
uint32_t address; // 24-bit SNES address
|
||||
uint32_t size; // Bytes to read
|
||||
bool as_hex; // Format as hex dump
|
||||
bool with_symbols; // Include symbol annotations
|
||||
};
|
||||
|
||||
struct MemoryReadResponse {
|
||||
std::vector<uint8_t> data;
|
||||
std::string hex_dump;
|
||||
std::map<uint32_t, std::string> symbols; // Address -> symbol name
|
||||
std::string interpretation; // AI-friendly interpretation
|
||||
};
|
||||
```
|
||||
|
||||
### 3. Disassembly API
|
||||
|
||||
```cpp
|
||||
enum class DisassemblyTool {
|
||||
kDisassemble, // Disassemble at address
|
||||
kDisassembleRange, // Disassemble N instructions
|
||||
kDisassembleContext, // Show surrounding code
|
||||
kFindInstruction, // Search for instruction pattern
|
||||
kGetCallStack, // Get current call stack
|
||||
kTraceExecution, // Get execution history
|
||||
};
|
||||
```
|
||||
|
||||
#### Disassembly Request/Response:
|
||||
```cpp
|
||||
struct DisassemblyRequest {
|
||||
uint32_t address;
|
||||
uint32_t instruction_count;
|
||||
uint32_t context_before; // Instructions before target
|
||||
uint32_t context_after; // Instructions after target
|
||||
bool include_symbols;
|
||||
bool include_execution_counts;
|
||||
bool track_branches; // Show branch targets
|
||||
};
|
||||
|
||||
struct DisassemblyResponse {
|
||||
struct Line {
|
||||
uint32_t address;
|
||||
std::string hex_bytes; // "20 34 80"
|
||||
std::string mnemonic; // "JSR"
|
||||
std::string operands; // "$8034"
|
||||
std::string symbol; // "MainGameLoop"
|
||||
std::string comment; // "; Initialize game state"
|
||||
bool is_breakpoint;
|
||||
bool is_current_pc;
|
||||
uint32_t execution_count;
|
||||
uint32_t branch_target; // For jumps/branches
|
||||
};
|
||||
|
||||
std::vector<Line> lines;
|
||||
std::string formatted_text; // Human-readable disassembly
|
||||
std::vector<std::string> referenced_symbols;
|
||||
};
|
||||
```
|
||||
|
||||
### 4. Analysis API
|
||||
|
||||
```cpp
|
||||
enum class AnalysisTool {
|
||||
kAnalyzeRoutine, // Analyze subroutine behavior
|
||||
kFindReferences, // Find references to address
|
||||
kDetectPattern, // Detect common bug patterns
|
||||
kCompareRom, // Compare with original ROM
|
||||
kProfileExecution, // Performance profiling
|
||||
kTrackDataFlow, // Track value propagation
|
||||
};
|
||||
```
|
||||
|
||||
## Tool Dispatcher Integration
|
||||
|
||||
### New Tool Definitions
|
||||
|
||||
```cpp
|
||||
// In tool_dispatcher.h
|
||||
enum class ToolCallType {
|
||||
// ... existing tools ...
|
||||
|
||||
// Debugger - Execution Control
|
||||
kDebugRun,
|
||||
kDebugStep,
|
||||
kDebugStepOver,
|
||||
kDebugStepOut,
|
||||
kDebugRunToAddress,
|
||||
|
||||
// Debugger - Breakpoints
|
||||
kDebugSetBreakpoint,
|
||||
kDebugSetWatchpoint,
|
||||
kDebugClearBreakpoint,
|
||||
kDebugListBreakpoints,
|
||||
kDebugEnableBreakpoint,
|
||||
|
||||
// Debugger - Memory
|
||||
kDebugReadMemory,
|
||||
kDebugWriteMemory,
|
||||
kDebugSearchMemory,
|
||||
kDebugCompareMemory,
|
||||
kDebugSnapshotMemory,
|
||||
|
||||
// Debugger - Disassembly
|
||||
kDebugDisassemble,
|
||||
kDebugGetCallStack,
|
||||
kDebugGetExecutionTrace,
|
||||
kDebugFindInstruction,
|
||||
|
||||
// Debugger - Analysis
|
||||
kDebugAnalyzeRoutine,
|
||||
kDebugFindReferences,
|
||||
kDebugDetectBugs,
|
||||
kDebugProfileCode,
|
||||
};
|
||||
```
|
||||
|
||||
### Tool Handler Implementation
|
||||
|
||||
```cpp
|
||||
class DebuggerToolHandler {
|
||||
public:
|
||||
explicit DebuggerToolHandler(EmulatorServiceImpl* service);
|
||||
|
||||
absl::StatusOr<ToolResponse> HandleDebugStep(const nlohmann::json& params);
|
||||
absl::StatusOr<ToolResponse> HandleDebugSetBreakpoint(const nlohmann::json& params);
|
||||
absl::StatusOr<ToolResponse> HandleDebugDisassemble(const nlohmann::json& params);
|
||||
absl::StatusOr<ToolResponse> HandleDebugReadMemory(const nlohmann::json& params);
|
||||
absl::StatusOr<ToolResponse> HandleDebugAnalyze(const nlohmann::json& params);
|
||||
|
||||
private:
|
||||
EmulatorServiceImpl* emulator_service_;
|
||||
Disassembler65816 disassembler_;
|
||||
SymbolProvider symbol_provider_;
|
||||
MemoryAnalyzer analyzer_;
|
||||
};
|
||||
```
|
||||
|
||||
## Example AI Agent Interactions
|
||||
|
||||
### Example 1: Debugging a Crash
|
||||
|
||||
**Agent Query:**
|
||||
```json
|
||||
{
|
||||
"tool": "debug_analyze",
|
||||
"params": {
|
||||
"problem": "Game crashes when entering dungeon room 15",
|
||||
"context": {
|
||||
"room_id": 15,
|
||||
"entrance_id": 3
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**System Response:**
|
||||
```json
|
||||
{
|
||||
"analysis": {
|
||||
"crash_location": {
|
||||
"address": "0x008A45",
|
||||
"instruction": "LDA [$00],Y",
|
||||
"symbol": "LoadRoomHeader+0x15"
|
||||
},
|
||||
"cause": "Null pointer dereference",
|
||||
"explanation": "Direct page location $00 contains $0000, causing invalid long pointer access",
|
||||
"registers_at_crash": {
|
||||
"Y": "0x0010",
|
||||
"DP": "0x1E00",
|
||||
"$1E00": "0x0000"
|
||||
},
|
||||
"suggested_fix": "Check room header pointer before dereferencing",
|
||||
"call_stack": [
|
||||
"Module_Dungeon",
|
||||
"Dungeon_LoadRoom",
|
||||
"LoadRoomHeader"
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Example 2: Step-by-Step Debugging
|
||||
|
||||
**Agent Query:**
|
||||
```json
|
||||
{
|
||||
"tool": "debug_step",
|
||||
"params": {
|
||||
"type": "over",
|
||||
"with_context": true,
|
||||
"show_memory": ["$7E0010", "$7E0012"]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Response:**
|
||||
```json
|
||||
{
|
||||
"pc_before": "0x008034",
|
||||
"pc_after": "0x008037",
|
||||
"instruction_executed": {
|
||||
"address": "0x008034",
|
||||
"mnemonic": "JSR",
|
||||
"operand": "$8520",
|
||||
"symbol": "UpdateSprites",
|
||||
"cycles": 6
|
||||
},
|
||||
"context": {
|
||||
"before": [
|
||||
{"address": "0x008031", "instruction": "LDA $10", "value": "0x07"}
|
||||
],
|
||||
"after": [
|
||||
{"address": "0x008037", "instruction": "BEQ $8045"}
|
||||
]
|
||||
},
|
||||
"memory_values": {
|
||||
"$7E0010": "0x07",
|
||||
"$7E0012": "0x00"
|
||||
},
|
||||
"call_depth": 2
|
||||
}
|
||||
```
|
||||
|
||||
### Example 3: Finding Bug Patterns
|
||||
|
||||
**Agent Query:**
|
||||
```json
|
||||
{
|
||||
"tool": "debug_detect_bugs",
|
||||
"params": {
|
||||
"patterns": ["stack_overflow", "invalid_bank", "dma_collision"],
|
||||
"range": {
|
||||
"start": "0x008000",
|
||||
"end": "0x00FFFF"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Response:**
|
||||
```json
|
||||
{
|
||||
"bugs_found": [
|
||||
{
|
||||
"type": "potential_stack_overflow",
|
||||
"location": "0x009A23",
|
||||
"description": "Recursive JSR without stack check",
|
||||
"severity": "high",
|
||||
"suggestion": "Add stack pointer validation before recursive call"
|
||||
},
|
||||
{
|
||||
"type": "invalid_bank_switch",
|
||||
"location": "0x00B456",
|
||||
"description": "PHB without corresponding PLB",
|
||||
"severity": "medium",
|
||||
"suggestion": "Ensure data bank is restored after operation"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### Example 4: Memory Watchpoint
|
||||
|
||||
**Agent Query:**
|
||||
```json
|
||||
{
|
||||
"tool": "debug_set_watchpoint",
|
||||
"params": {
|
||||
"address": "0x7E0020",
|
||||
"size": 2,
|
||||
"type": "write",
|
||||
"condition": "value > 0x00FF",
|
||||
"description": "Monitor game state overflow"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Response:**
|
||||
```json
|
||||
{
|
||||
"watchpoint_id": 5,
|
||||
"status": "active",
|
||||
"message": "Watchpoint set on $7E0020-$7E0021 for writes > 0x00FF"
|
||||
}
|
||||
```
|
||||
|
||||
## Phase 2 (Full) Features
|
||||
|
||||
### Advanced Analysis
|
||||
- **Control Flow Graphs**: Generate CFG for routines
|
||||
- **Data Flow Analysis**: Track value propagation through code
|
||||
- **Symbolic Execution**: Analyze possible execution paths
|
||||
- **Pattern Matching**: Detect specific code patterns (e.g., DMA setup, HDMA tables)
|
||||
- **Performance Profiling**: Cycle-accurate performance analysis
|
||||
|
||||
### Enhanced Debugging
|
||||
- **Conditional Breakpoints**: Complex expressions (e.g., "A > 0x10 && X == 0")
|
||||
- **Trace Recording**: Record full execution traces to file
|
||||
- **Reverse Debugging**: Step backwards through recorded execution
|
||||
- **Memory Diffing**: Visual diff between memory states
|
||||
- **SPC700 Debugging**: Full audio processor debugging support
|
||||
|
||||
### AI-Specific Features
|
||||
- **Semantic Analysis**: Understanding game logic from assembly
|
||||
- **Bug Pattern Database**: ML-trained bug detection
|
||||
- **Automated Fix Suggestions**: Propose assembly patches for bugs
|
||||
- **Test Case Generation**: Generate test scenarios for ROM hacks
|
||||
- **Documentation Generation**: Auto-document assembly routines
|
||||
|
||||
## Implementation Priority
|
||||
|
||||
### Phase 1A (Immediate - Week 1-2)
|
||||
1. Basic step control (single, over, out)
|
||||
2. Simple breakpoints (address-based)
|
||||
3. Memory read/write operations
|
||||
4. Basic disassembly at address
|
||||
|
||||
### Phase 1B (Short-term - Week 3-4)
|
||||
1. Call stack tracking
|
||||
2. Symbol resolution
|
||||
3. Memory watchpoints
|
||||
4. Execution trace (last N instructions)
|
||||
|
||||
### Phase 1C (Medium-term - Week 5-6)
|
||||
1. Pattern-based bug detection
|
||||
2. Memory snapshots and comparison
|
||||
3. Advanced breakpoint conditions
|
||||
4. Performance metrics
|
||||
|
||||
### Phase 2 (Long-term - Month 2+)
|
||||
1. Full analysis suite
|
||||
2. SPC700 debugging
|
||||
3. Reverse debugging
|
||||
4. AI-specific enhancements
|
||||
|
||||
## Success Metrics
|
||||
|
||||
### Technical Metrics
|
||||
- Response time < 100ms for step operations
|
||||
- Support for 100+ simultaneous breakpoints without performance impact
|
||||
- Accurate disassembly for 100% of valid 65816 opcodes
|
||||
- Symbol resolution for all loaded ASM files
|
||||
|
||||
### User Experience Metrics
|
||||
- AI agents can identify crash causes in < 5 interactions
|
||||
- Step debugging provides sufficient context without overwhelming
|
||||
- Memory inspection clearly shows relevant game state
|
||||
- Bug detection has < 10% false positive rate
|
||||
|
||||
## Integration Points
|
||||
|
||||
### With Existing yaze Components
|
||||
- **Rom Class**: Read-only access to ROM data
|
||||
- **Emulator Core**: Direct CPU/PPU/APU state access
|
||||
- **Symbol Files**: Integration with usdasm output
|
||||
- **Canvas System**: Visual debugging overlays (Phase 2)
|
||||
|
||||
### With AI Infrastructure
|
||||
- **Tool Dispatcher**: Seamless tool call routing
|
||||
- **Prompt Builder**: Context-aware debugging prompts
|
||||
- **Agent Memory**: Persistent debugging session state
|
||||
- **Response Formatter**: Human-readable debug output
|
||||
|
||||
## Security Considerations
|
||||
|
||||
1. **Read-Only by Default**: Prevent accidental ROM corruption
|
||||
2. **Sandboxed Execution**: Limit memory access to emulated space
|
||||
3. **Rate Limiting**: Prevent runaway debugging loops
|
||||
4. **Audit Logging**: Track all debugging operations
|
||||
5. **Session Isolation**: Separate debug sessions per agent
|
||||
|
||||
## Testing Strategy
|
||||
|
||||
### Unit Tests
|
||||
- Disassembler accuracy for all opcodes
|
||||
- Step controller call stack tracking
|
||||
- Breakpoint manager hit detection
|
||||
- Symbol provider resolution
|
||||
|
||||
### Integration Tests
|
||||
- Full debugging session workflows
|
||||
- gRPC service communication
|
||||
- Tool dispatcher routing
|
||||
- Memory state consistency
|
||||
|
||||
### End-to-End Tests
|
||||
- AI agent debugging scenarios
|
||||
- Bug detection accuracy
|
||||
- Performance under load
|
||||
- Error recovery paths
|
||||
|
||||
## Documentation Requirements
|
||||
|
||||
1. **API Reference**: Complete gRPC service documentation
|
||||
2. **Tool Guide**: How to use each debugging tool
|
||||
3. **Assembly Primer**: 65816 basics for AI agents
|
||||
4. **Common Patterns**: Debugging patterns for Zelda3
|
||||
5. **Troubleshooting**: Common issues and solutions
|
||||
|
||||
## Conclusion
|
||||
|
||||
This debugging API design provides a comprehensive foundation for AI agents to effectively debug SNES ROM hacks. The phased approach ensures quick delivery of core features while building toward advanced analysis capabilities. The integration with existing yaze infrastructure and focus on 65816-specific debugging makes this a powerful tool for ROM hacking assistance.
|
||||
|
||||
The API balances technical depth with usability, providing both low-level control for precise debugging and high-level analysis for pattern recognition. This enables AI agents to assist with everything from simple crash debugging to complex performance optimization.
|
||||
772
docs/internal/plans/message_editor_implementation_roadmap.md
Normal file
772
docs/internal/plans/message_editor_implementation_roadmap.md
Normal file
@@ -0,0 +1,772 @@
|
||||
# Message Editor Implementation Roadmap
|
||||
|
||||
**Status**: Active Development
|
||||
**Last Updated**: 2025-11-21
|
||||
**Owner**: Frontend/UI Team
|
||||
**Related Docs**:
|
||||
- `docs/internal/architecture/message_system.md` (Gemini's architecture vision)
|
||||
- `docs/internal/plans/message_system_improvement_plan.md` (Gemini's feature proposals)
|
||||
|
||||
---
|
||||
|
||||
## Executive Summary
|
||||
|
||||
This roadmap bridges Gemini's architectural vision with practical implementation steps for completing the Message Editor. The current implementation has the **core foundation** in place (message parsing, dictionary system, preview rendering) but lacks several key features proposed in Gemini's plan, particularly around **JSON import/export**, **translation workflows**, and **theme integration**.
|
||||
|
||||
---
|
||||
|
||||
## Current State Analysis
|
||||
|
||||
### What's Working (Completed Features)
|
||||
|
||||
#### Core Data Layer ✅
|
||||
- **MessageData**: Full implementation with raw/parsed representations
|
||||
- **DictionaryEntry**: Compression system with dictionary optimization
|
||||
- **TextElement**: Command and special character parsing
|
||||
- **Character Encoding**: Complete CharEncoder table (0x00-0x66)
|
||||
- **ROM Reading**: `ReadAllTextData()` successfully loads all 396 messages
|
||||
- **ROM Writing**: `Save()` handles two-bank text data with overflow detection
|
||||
|
||||
#### Message Preview System ✅
|
||||
- **MessagePreview**: Live rendering of messages as they appear in-game
|
||||
- **Font Graphics**: 2BPP font tiles loaded and displayed at 0x70000
|
||||
- **Character Widths**: Proportional font support via width table at 0x74ADF
|
||||
- **Preview Bitmap**: Real-time message rendering with proper palette support
|
||||
|
||||
#### Editor UI ✅
|
||||
- **Card System**: Four dockable cards (Message List, Editor, Font Atlas, Dictionary)
|
||||
- **Message List**: Table view with ID, contents, and address columns
|
||||
- **Text Editor**: Multiline input with live preview updates
|
||||
- **Command Insertion**: Buttons to insert text commands and special characters
|
||||
- **Dictionary Display**: Read-only view of all 97 dictionary entries
|
||||
- **Expanded Messages**: Basic support for loading external message bins
|
||||
|
||||
#### Testing Coverage ✅
|
||||
- **Unit Tests**: 20+ tests covering parsing, encoding, dictionary optimization
|
||||
- **Integration Tests**: ROM-dependent tests verify actual game data
|
||||
- **Command Parsing**: Regression tests for argument handling bugs
|
||||
|
||||
#### CLI Integration ✅
|
||||
- **Message List**: `z3ed message list --format json --range 0-100`
|
||||
- **Message Read**: `z3ed message read --id 5 --format json`
|
||||
- **Message Search**: `z3ed message search --query "Link"`
|
||||
- **Message Stats**: `z3ed message stats --format json`
|
||||
|
||||
### What's Missing (Gaps vs. Gemini's Vision)
|
||||
|
||||
#### 1. JSON Import/Export ❌ (HIGH PRIORITY)
|
||||
**Status**: Not implemented
|
||||
**Gemini's Vision**:
|
||||
```json
|
||||
[
|
||||
{
|
||||
"id": 0,
|
||||
"address": 917504,
|
||||
"text": "[W:00][SPD:00]Welcome to [D:05]...",
|
||||
"context": "Uncle dying in sewers"
|
||||
}
|
||||
]
|
||||
```
|
||||
|
||||
**Current Gap**:
|
||||
- No `SerializeMessages()` or `DeserializeMessages()` in `MessageData`
|
||||
- No UI for export/import operations
|
||||
- No context field for translator notes
|
||||
- CLI has JSON output but not JSON input
|
||||
|
||||
**Impact**: Cannot version control text, cannot use external editors, cannot collaborate with translators
|
||||
|
||||
---
|
||||
|
||||
#### 2. Translation Workspace ❌ (MEDIUM PRIORITY)
|
||||
**Status**: Not implemented
|
||||
**Gemini's Vision**: Side-by-side view with reference ROM/JSON and editable translation
|
||||
|
||||
**Current Gap**:
|
||||
- No reference text display
|
||||
- No side-by-side layout
|
||||
- No translation progress tracking
|
||||
- No language-specific dictionary optimization
|
||||
|
||||
**Impact**: Manual translation workflows are tedious and error-prone
|
||||
|
||||
---
|
||||
|
||||
#### 3. Search & Replace ⚠️ (PARTIAL)
|
||||
**Status**: Stub implementation exists
|
||||
**Gemini's Vision**: Regex support, batch replace across all messages
|
||||
|
||||
**Current Implementation**:
|
||||
- `Find()` method exists in `MessageEditor` (lines 574-600)
|
||||
- Basic UI skeleton present (search input, case sensitivity toggle)
|
||||
- **Missing**: Replace functionality, regex support, "Find All", multi-message operations
|
||||
|
||||
**Impact**: Global text edits require manual per-message changes
|
||||
|
||||
---
|
||||
|
||||
#### 4. Theme Integration ❌ (LOW PRIORITY - UI POLISH)
|
||||
**Status**: Not implemented
|
||||
**Current Issues**:
|
||||
- No hardcoded `ImVec4` colors found (GOOD!)
|
||||
- Not using `AgentUITheme` system for consistency
|
||||
- Missing semantic color names for message editor components
|
||||
|
||||
**Impact**: Message Editor UI may not match rest of application theme
|
||||
|
||||
---
|
||||
|
||||
#### 5. Expanded ROM Support ⚠️ (PARTIAL)
|
||||
**Status**: Basic implementation exists
|
||||
**Gemini's Vision**: Repointing text blocks to expanded ROM space (Banks 10+), automatic bank switching
|
||||
|
||||
**Current Implementation**:
|
||||
- Can load expanded message bins (lines 322-334)
|
||||
- Can save expanded messages (lines 497-508)
|
||||
- **Missing**: Repointing logic, bank management, automatic overflow handling
|
||||
|
||||
**Impact**: Cannot support large translation projects that exceed vanilla space
|
||||
|
||||
---
|
||||
|
||||
#### 6. Scripting Integration ❌ (FUTURE)
|
||||
**Status**: Not planned
|
||||
**Gemini's Vision**: Lua/Python API for procedural text generation
|
||||
|
||||
**Current Gap**: No scripting hooks in message system
|
||||
|
||||
**Impact**: Low - nice-to-have for advanced users
|
||||
|
||||
---
|
||||
|
||||
## Architectural Decisions Required
|
||||
|
||||
### Decision 1: JSON Schema Design
|
||||
**Question**: What fields should the JSON export include?
|
||||
|
||||
**Proposal**:
|
||||
```json
|
||||
{
|
||||
"version": "1.0",
|
||||
"rom_name": "zelda3.sfc",
|
||||
"messages": [
|
||||
{
|
||||
"id": 0,
|
||||
"address": 917504,
|
||||
"address_hex": "0xE0000",
|
||||
"text": "[W:00][SPD:00]Welcome...",
|
||||
"context": "Optional translator note",
|
||||
"dictionary_optimized": true,
|
||||
"expanded": false
|
||||
}
|
||||
],
|
||||
"dictionary": [
|
||||
{
|
||||
"id": 0,
|
||||
"token": "[D:00]",
|
||||
"contents": "the"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
**Trade-offs**:
|
||||
- Verbose but human-readable
|
||||
- Includes metadata for validation
|
||||
- Context field for translator workflow
|
||||
|
||||
**Status**: ✅ RECOMMENDED
|
||||
|
||||
---
|
||||
|
||||
### Decision 2: Translation Workspace Layout
|
||||
**Question**: How should reference vs. translation be displayed?
|
||||
|
||||
**Option A**: Side-by-side split pane
|
||||
```
|
||||
┌────────────────┬────────────────┐
|
||||
│ Reference │ Translation │
|
||||
│ (English) │ (Spanish) │
|
||||
│ [Read-only] │ [Editable] │
|
||||
│ │ │
|
||||
│ Message 0: │ Message 0: │
|
||||
│ "Welcome to │ "Bienvenido a │
|
||||
│ Hyrule" │ Hyrule" │
|
||||
└────────────────┴────────────────┘
|
||||
```
|
||||
|
||||
**Option B**: Top-bottom with context panel
|
||||
```
|
||||
┌────────────────────────────────┐
|
||||
│ Reference: "Welcome to Hyrule" │
|
||||
│ Context: Uncle's dying words │
|
||||
├────────────────────────────────┤
|
||||
│ Translation: │
|
||||
│ [Editable text box] │
|
||||
└────────────────────────────────┘
|
||||
```
|
||||
|
||||
**Recommendation**: Option A for large screens, Option B for narrow windows
|
||||
|
||||
**Status**: ⚠️ NEEDS USER FEEDBACK
|
||||
|
||||
---
|
||||
|
||||
### Decision 3: Dictionary Auto-Optimization
|
||||
**Question**: Should we auto-generate optimal dictionary for new languages?
|
||||
|
||||
**Challenges**:
|
||||
- Dictionary optimization is NP-hard (longest common substring problem)
|
||||
- Need to preserve ROM space constraints (97 entries max)
|
||||
- Different languages have different common phrases
|
||||
|
||||
**Proposal**:
|
||||
1. Provide "Analyze Translation" button that suggests optimal dictionary
|
||||
2. Let user accept/reject suggestions
|
||||
3. Preserve manual dictionary entries
|
||||
|
||||
**Status**: ⚠️ NEEDS RESEARCH
|
||||
|
||||
---
|
||||
|
||||
## Implementation Priority Matrix
|
||||
|
||||
### Phase 1: Foundation (Sprint 1-2 weeks)
|
||||
**Goal**: JSON import/export with UI integration
|
||||
|
||||
#### Task 1.1: Implement JSON Serialization
|
||||
**Location**: `src/app/editor/message/message_data.h`, `message_data.cc`
|
||||
**Priority**: P0 (Blocker for translation workflow)
|
||||
**Estimated Effort**: 3 days
|
||||
|
||||
**Implementation**:
|
||||
```cpp
|
||||
// In MessageData
|
||||
nlohmann::json SerializeToJson() const;
|
||||
static absl::StatusOr<MessageData> DeserializeFromJson(const nlohmann::json& j);
|
||||
|
||||
// Free functions
|
||||
absl::Status ExportMessagesToJson(
|
||||
const std::vector<MessageData>& messages,
|
||||
const std::vector<DictionaryEntry>& dictionary,
|
||||
const std::string& output_path);
|
||||
|
||||
absl::StatusOr<std::vector<MessageData>> ImportMessagesFromJson(
|
||||
const std::string& input_path);
|
||||
```
|
||||
|
||||
**Dependencies**: nlohmann/json (already in project via CPM)
|
||||
|
||||
**Acceptance Criteria**:
|
||||
- [ ] Export all 396 messages to valid JSON
|
||||
- [ ] Import JSON and verify byte-for-byte ROM equivalence
|
||||
- [ ] Handle malformed JSON with clear error messages
|
||||
- [ ] Preserve dictionary optimization
|
||||
- [ ] Include context field in schema
|
||||
|
||||
---
|
||||
|
||||
#### Task 1.2: Add Export/Import UI
|
||||
**Location**: `src/app/editor/message/message_editor.cc`
|
||||
**Priority**: P0
|
||||
**Estimated Effort**: 2 days
|
||||
|
||||
**UI Additions**:
|
||||
```cpp
|
||||
void MessageEditor::DrawExportImportPanel() {
|
||||
if (ImGui::Button("Export to JSON")) {
|
||||
std::string path = util::FileDialogWrapper::ShowSaveFileDialog("json");
|
||||
PRINT_IF_ERROR(ExportMessagesToJson(list_of_texts_,
|
||||
message_preview_.all_dictionaries_,
|
||||
path));
|
||||
}
|
||||
|
||||
if (ImGui::Button("Import from JSON")) {
|
||||
std::string path = util::FileDialogWrapper::ShowOpenFileDialog();
|
||||
auto result = ImportMessagesFromJson(path);
|
||||
if (result.ok()) {
|
||||
list_of_texts_ = result.value();
|
||||
RefreshMessageList();
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Acceptance Criteria**:
|
||||
- [ ] File dialogs open with correct filters
|
||||
- [ ] Progress indicator for large exports
|
||||
- [ ] Confirmation dialog on import (warns about overwriting)
|
||||
- [ ] Error popup on import failure with details
|
||||
|
||||
---
|
||||
|
||||
#### Task 1.3: CLI JSON Import Support
|
||||
**Location**: `src/cli/handlers/game/message.cc`
|
||||
**Priority**: P1
|
||||
**Estimated Effort**: 1 day
|
||||
|
||||
**Implementation**:
|
||||
```bash
|
||||
z3ed message import --json messages.json --rom zelda3.sfc --output zelda3_translated.sfc
|
||||
```
|
||||
|
||||
**Acceptance Criteria**:
|
||||
- [ ] Import JSON and write to ROM
|
||||
- [ ] Validate JSON schema before import
|
||||
- [ ] Verify ROM size constraints
|
||||
- [ ] Dry-run mode (validate without writing)
|
||||
|
||||
---
|
||||
|
||||
### Phase 2: Translation Workflow (Sprint 2-3 weeks)
|
||||
**Goal**: Side-by-side translation UI
|
||||
|
||||
#### Task 2.1: Add Translation Mode Card
|
||||
**Location**: `src/app/editor/message/message_editor.h`, `message_editor.cc`
|
||||
**Priority**: P1
|
||||
**Estimated Effort**: 5 days
|
||||
|
||||
**New Components**:
|
||||
```cpp
|
||||
class TranslationWorkspace {
|
||||
public:
|
||||
void Initialize(Rom* reference_rom, Rom* translation_rom);
|
||||
void DrawUI();
|
||||
void LoadReferenceFromJson(const std::string& path);
|
||||
|
||||
private:
|
||||
void DrawSideBySideView();
|
||||
void DrawProgressTracker();
|
||||
void UpdateTranslationProgress();
|
||||
|
||||
std::vector<MessageData> reference_messages_;
|
||||
std::vector<MessageData> translation_messages_;
|
||||
std::map<int, bool> translation_complete_flags_;
|
||||
Rom* reference_rom_ = nullptr;
|
||||
Rom* translation_rom_ = nullptr;
|
||||
};
|
||||
```
|
||||
|
||||
**UI Mockup**:
|
||||
```
|
||||
┌─────────────────────────────────────────────────┐
|
||||
│ Translation Progress: 42/396 (10.6%) │
|
||||
├──────────────────────┬──────────────────────────┤
|
||||
│ Reference (EN) │ Translation (ES) │
|
||||
├──────────────────────┼──────────────────────────┤
|
||||
│ Message 0: │ Message 0: │
|
||||
│ "Welcome to Hyrule" │ [Editable input box] │
|
||||
│ │ │
|
||||
│ Dictionary: [D:05] │ Dictionary: [D:05] │
|
||||
├──────────────────────┴──────────────────────────┤
|
||||
│ [Previous] [Next] [Mark Complete] [Skip] │
|
||||
└─────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
**Acceptance Criteria**:
|
||||
- [ ] Load reference ROM or JSON
|
||||
- [ ] Display messages side-by-side
|
||||
- [ ] Track translation progress (per-message completion)
|
||||
- [ ] Keyboard shortcuts for navigation (Ctrl+N, Ctrl+P)
|
||||
- [ ] Auto-save translated ROM on completion
|
||||
|
||||
---
|
||||
|
||||
#### Task 2.2: Context/Notes System
|
||||
**Location**: `src/app/editor/message/message_data.h`
|
||||
**Priority**: P2
|
||||
**Estimated Effort**: 2 days
|
||||
|
||||
**Schema Addition**:
|
||||
```cpp
|
||||
struct MessageData {
|
||||
// ... existing fields ...
|
||||
std::string context; // Translator notes, scene context
|
||||
std::string screenshot_path; // Optional screenshot reference
|
||||
|
||||
nlohmann::json SerializeToJson() const {
|
||||
return {
|
||||
{"id", ID},
|
||||
{"address", Address},
|
||||
{"text", RawString},
|
||||
{"context", context},
|
||||
{"screenshot", screenshot_path}
|
||||
};
|
||||
}
|
||||
};
|
||||
```
|
||||
|
||||
**UI Addition**:
|
||||
```cpp
|
||||
void MessageEditor::DrawContextPanel() {
|
||||
ImGui::InputTextMultiline("Context Notes", ¤t_message_.context);
|
||||
if (!current_message_.screenshot_path.empty()) {
|
||||
ImGui::Image(LoadScreenshot(current_message_.screenshot_path));
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Acceptance Criteria**:
|
||||
- [ ] Context field persists in JSON export/import
|
||||
- [ ] Context displayed in translation workspace
|
||||
- [ ] Optional screenshot attachment (stored as relative path)
|
||||
|
||||
---
|
||||
|
||||
### Phase 3: Search & Replace (Sprint 3-1 week)
|
||||
**Goal**: Complete Find/Replace implementation
|
||||
|
||||
#### Task 3.1: Implement Replace Functionality
|
||||
**Location**: `src/app/editor/message/message_editor.cc`
|
||||
**Priority**: P2
|
||||
**Estimated Effort**: 2 days
|
||||
|
||||
**Implementation**:
|
||||
```cpp
|
||||
absl::Status MessageEditor::Replace(const std::string& find_text,
|
||||
const std::string& replace_text,
|
||||
bool case_sensitive,
|
||||
bool whole_word,
|
||||
bool all_messages) {
|
||||
int replaced_count = 0;
|
||||
|
||||
if (all_messages) {
|
||||
for (auto& message : list_of_texts_) {
|
||||
replaced_count += ReplaceInMessage(message, find_text, replace_text,
|
||||
case_sensitive, whole_word);
|
||||
}
|
||||
} else {
|
||||
replaced_count += ReplaceInMessage(current_message_, find_text,
|
||||
replace_text, case_sensitive, whole_word);
|
||||
}
|
||||
|
||||
return absl::OkStatus();
|
||||
}
|
||||
```
|
||||
|
||||
**UI Updates**:
|
||||
```cpp
|
||||
void MessageEditor::DrawFindReplacePanel() {
|
||||
static char find_text[256] = "";
|
||||
static char replace_text[256] = "";
|
||||
|
||||
ImGui::InputText("Find", find_text, IM_ARRAYSIZE(find_text));
|
||||
ImGui::InputText("Replace", replace_text, IM_ARRAYSIZE(replace_text));
|
||||
|
||||
ImGui::Checkbox("Case Sensitive", &case_sensitive_);
|
||||
ImGui::Checkbox("Whole Word", &match_whole_word_);
|
||||
ImGui::Checkbox("All Messages", &replace_all_messages_);
|
||||
|
||||
if (ImGui::Button("Replace")) {
|
||||
PRINT_IF_ERROR(Replace(find_text, replace_text, case_sensitive_,
|
||||
match_whole_word_, false));
|
||||
}
|
||||
|
||||
if (ImGui::Button("Replace All")) {
|
||||
PRINT_IF_ERROR(Replace(find_text, replace_text, case_sensitive_,
|
||||
match_whole_word_, true));
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Acceptance Criteria**:
|
||||
- [ ] Replace in current message
|
||||
- [ ] Replace in all messages
|
||||
- [ ] Case-sensitive/insensitive options
|
||||
- [ ] Whole word matching
|
||||
- [ ] Undo support (requires history stack)
|
||||
|
||||
---
|
||||
|
||||
#### Task 3.2: Add Regex Support
|
||||
**Location**: `src/app/editor/message/message_editor.cc`
|
||||
**Priority**: P3 (Nice-to-have)
|
||||
**Estimated Effort**: 2 days
|
||||
|
||||
**Implementation**:
|
||||
```cpp
|
||||
absl::Status MessageEditor::ReplaceRegex(const std::string& pattern,
|
||||
const std::string& replacement,
|
||||
bool all_messages) {
|
||||
std::regex regex_pattern;
|
||||
try {
|
||||
regex_pattern = std::regex(pattern);
|
||||
} catch (const std::regex_error& e) {
|
||||
return absl::InvalidArgumentError(
|
||||
absl::StrFormat("Invalid regex: %s", e.what()));
|
||||
}
|
||||
|
||||
// Perform replacement...
|
||||
}
|
||||
```
|
||||
|
||||
**Acceptance Criteria**:
|
||||
- [ ] Regex validation with error messages
|
||||
- [ ] Capture group support ($1, $2, etc.)
|
||||
- [ ] Preview matches before replacement
|
||||
|
||||
---
|
||||
|
||||
### Phase 4: UI Polish (Sprint 4-1 week)
|
||||
**Goal**: Theme integration and UX improvements
|
||||
|
||||
#### Task 4.1: Integrate AgentUITheme
|
||||
**Location**: `src/app/editor/message/message_editor.cc`
|
||||
**Priority**: P3
|
||||
**Estimated Effort**: 1 day
|
||||
|
||||
**Implementation**:
|
||||
```cpp
|
||||
void MessageEditor::DrawMessageList() {
|
||||
const auto& theme = AgentUI::GetTheme();
|
||||
|
||||
AgentUI::PushPanelStyle();
|
||||
ImGui::PushStyleColor(ImGuiCol_Header, theme.panel_bg_darker);
|
||||
ImGui::PushStyleColor(ImGuiCol_HeaderHovered, theme.accent_color);
|
||||
|
||||
// ... table rendering ...
|
||||
|
||||
ImGui::PopStyleColor(2);
|
||||
AgentUI::PopPanelStyle();
|
||||
}
|
||||
```
|
||||
|
||||
**Acceptance Criteria**:
|
||||
- [ ] All panels use `AgentUI::PushPanelStyle()`
|
||||
- [ ] Section headers use `AgentUI::RenderSectionHeader()`
|
||||
- [ ] Buttons use `AgentUI::StyledButton()` where appropriate
|
||||
- [ ] Color scheme matches rest of editor
|
||||
|
||||
---
|
||||
|
||||
#### Task 4.2: Add Keyboard Shortcuts
|
||||
**Location**: `src/app/editor/message/message_editor.cc`
|
||||
**Priority**: P3
|
||||
**Estimated Effort**: 1 day
|
||||
|
||||
**Shortcuts**:
|
||||
- `Ctrl+F`: Open Find/Replace
|
||||
- `Ctrl+E`: Export to JSON
|
||||
- `Ctrl+I`: Import from JSON
|
||||
- `Ctrl+S`: Save ROM
|
||||
- `Ctrl+N`: Next message (in translation mode)
|
||||
- `Ctrl+P`: Previous message (in translation mode)
|
||||
|
||||
**Implementation**:
|
||||
```cpp
|
||||
void MessageEditor::HandleKeyboardShortcuts() {
|
||||
if (ImGui::IsKeyPressed(ImGuiKey_F) &&
|
||||
ImGui::GetIO().KeyCtrl) {
|
||||
show_find_replace_ = true;
|
||||
}
|
||||
|
||||
// ... other shortcuts ...
|
||||
}
|
||||
```
|
||||
|
||||
**Acceptance Criteria**:
|
||||
- [ ] Shortcuts don't conflict with global shortcuts
|
||||
- [ ] Shortcuts displayed in tooltips
|
||||
- [ ] Configurable shortcuts (future enhancement)
|
||||
|
||||
---
|
||||
|
||||
## Test Strategy
|
||||
|
||||
### Unit Tests
|
||||
**Location**: `test/unit/message_data_test.cc` (new file)
|
||||
```cpp
|
||||
TEST(MessageDataTest, SerializeToJson_BasicMessage) {
|
||||
MessageData msg;
|
||||
msg.ID = 0;
|
||||
msg.Address = 0xE0000;
|
||||
msg.RawString = "Hello World";
|
||||
msg.context = "Test message";
|
||||
|
||||
auto json = msg.SerializeToJson();
|
||||
|
||||
EXPECT_EQ(json["id"], 0);
|
||||
EXPECT_EQ(json["text"], "Hello World");
|
||||
EXPECT_EQ(json["context"], "Test message");
|
||||
}
|
||||
|
||||
TEST(MessageDataTest, DeserializeFromJson_RoundTrip) {
|
||||
MessageData original;
|
||||
original.ID = 5;
|
||||
original.RawString = "[W:00][K]Test";
|
||||
|
||||
auto json = original.SerializeToJson();
|
||||
auto result = MessageData::DeserializeFromJson(json);
|
||||
|
||||
ASSERT_TRUE(result.ok());
|
||||
EXPECT_EQ(result.value().ID, 5);
|
||||
EXPECT_EQ(result.value().RawString, "[W:00][K]Test");
|
||||
}
|
||||
```
|
||||
|
||||
### Integration Tests
|
||||
**Location**: `test/integration/message_export_test.cc` (new file)
|
||||
```cpp
|
||||
TEST_F(MessageRomTest, ExportImport_RoundTrip) {
|
||||
// Export all messages to JSON
|
||||
std::string json_path = "/tmp/messages.json";
|
||||
EXPECT_OK(ExportMessagesToJson(list_of_texts_, dictionary_, json_path));
|
||||
|
||||
// Import back
|
||||
auto imported = ImportMessagesFromJson(json_path);
|
||||
ASSERT_TRUE(imported.ok());
|
||||
|
||||
// Verify identical
|
||||
EXPECT_EQ(imported.value().size(), list_of_texts_.size());
|
||||
for (size_t i = 0; i < list_of_texts_.size(); ++i) {
|
||||
EXPECT_EQ(imported.value()[i].RawString, list_of_texts_[i].RawString);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### E2E Tests
|
||||
**Location**: `test/e2e/message_editor_workflow_test.cc` (new file)
|
||||
```cpp
|
||||
TEST_F(MessageEditorE2ETest, TranslationWorkflow) {
|
||||
// Open translation workspace
|
||||
EXPECT_OK(ClickButton("Translation Mode"));
|
||||
|
||||
// Load reference ROM
|
||||
EXPECT_OK(OpenFileDialog("reference_rom.sfc"));
|
||||
|
||||
// Navigate to message 0
|
||||
EXPECT_EQ(GetCurrentMessageID(), 0);
|
||||
|
||||
// Edit translation
|
||||
EXPECT_OK(SetTextBoxValue("Bienvenido a Hyrule"));
|
||||
|
||||
// Mark complete
|
||||
EXPECT_OK(ClickButton("Mark Complete"));
|
||||
|
||||
// Verify progress
|
||||
EXPECT_EQ(GetTranslationProgress(), "1/396");
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Dependencies & Risks
|
||||
|
||||
### External Dependencies
|
||||
1. **nlohmann/json**: Already integrated via CPM ✅
|
||||
2. **ImGui Test Engine**: Available for E2E tests ✅
|
||||
3. **File Dialog**: `util::FileDialogWrapper` already exists ✅
|
||||
|
||||
### Technical Risks
|
||||
|
||||
#### Risk 1: JSON Schema Evolution
|
||||
**Impact**: Breaking changes to JSON format
|
||||
**Mitigation**:
|
||||
- Include version number in schema
|
||||
- Implement forward/backward compatibility
|
||||
- Provide migration tool for old exports
|
||||
|
||||
#### Risk 2: Dictionary Auto-Optimization Complexity
|
||||
**Impact**: Algorithm may be too slow for real-time use
|
||||
**Mitigation**:
|
||||
- Run optimization in background thread
|
||||
- Provide progress indicator
|
||||
- Allow cancellation
|
||||
|
||||
#### Risk 3: Large ROM Size with Expanded Messages
|
||||
**Impact**: May exceed bank boundaries
|
||||
**Mitigation**:
|
||||
- Implement repointing logic early (Phase 5)
|
||||
- Warn user when approaching limits
|
||||
- Suggest dictionary optimization
|
||||
|
||||
---
|
||||
|
||||
## Success Metrics
|
||||
|
||||
### Quantitative Metrics
|
||||
- [ ] 100% message export/import success rate (no data loss)
|
||||
- [ ] JSON schema supports all 396 vanilla messages
|
||||
- [ ] Translation workspace reduces edit time by 50% vs. current workflow
|
||||
- [ ] Search/Replace handles batch operations in <1 second
|
||||
- [ ] 90%+ test coverage for new code
|
||||
|
||||
### Qualitative Metrics
|
||||
- [ ] Translator feedback: "Translation workflow is intuitive"
|
||||
- [ ] No hardcoded colors in Message Editor
|
||||
- [ ] UI matches yaze style guide
|
||||
- [ ] Documentation complete for all new features
|
||||
|
||||
---
|
||||
|
||||
## Timeline Estimate
|
||||
|
||||
| Phase | Duration | Effort (Dev Days) |
|
||||
|-------|----------|-------------------|
|
||||
| Phase 1: JSON Export/Import | 2 weeks | 6 days |
|
||||
| Phase 2: Translation Workspace | 3 weeks | 9 days |
|
||||
| Phase 3: Search & Replace | 1 week | 4 days |
|
||||
| Phase 4: UI Polish | 1 week | 2 days |
|
||||
| **Total** | **7 weeks** | **21 dev days** |
|
||||
|
||||
**Note**: Timeline assumes single developer working full-time. Adjust for part-time work or team collaboration.
|
||||
|
||||
---
|
||||
|
||||
## Future Enhancements (Post-MVP)
|
||||
|
||||
1. **Scripting API** (Gemini's vision)
|
||||
- Expose MessageData to Lua/Python
|
||||
- Allow procedural text generation
|
||||
- Useful for randomizers
|
||||
|
||||
2. **Cloud Translation Integration**
|
||||
- Google Translate API for quick drafts
|
||||
- DeepL API for quality translations
|
||||
- Requires API key management
|
||||
|
||||
3. **Collaborative Editing**
|
||||
- Real-time multi-user translation
|
||||
- Conflict resolution for concurrent edits
|
||||
- Requires network infrastructure
|
||||
|
||||
4. **ROM Patch Generation**
|
||||
- Export as `.ips` or `.bps` patch files
|
||||
- Useful for distribution without ROM sharing
|
||||
- Requires patch generation library
|
||||
|
||||
5. **Message Validation**
|
||||
- Check for overlong messages (exceeds textbox width)
|
||||
- Verify all messages have terminators
|
||||
- Flag unused dictionary entries
|
||||
|
||||
---
|
||||
|
||||
## Open Questions
|
||||
|
||||
1. **Q**: Should we support multiple translation languages simultaneously?
|
||||
**A**: TBD - May require multi-ROM workspace UI
|
||||
|
||||
2. **Q**: How should we handle custom dictionary entries for expanded ROMs?
|
||||
**A**: TBD - Need research into ROM space allocation
|
||||
|
||||
3. **Q**: Should translation progress be persisted?
|
||||
**A**: TBD - Could store in `.yaze` project file
|
||||
|
||||
4. **Q**: Do we need undo/redo for message editing?
|
||||
**A**: TBD - ImGui InputTextMultiline has built-in undo, may be sufficient
|
||||
|
||||
---
|
||||
|
||||
## Conclusion
|
||||
|
||||
The Message Editor has a **solid foundation** with core parsing, preview, and UI systems in place. The main gaps are **JSON export/import** (P0), **translation workspace** (P1), and **search/replace** (P2).
|
||||
|
||||
**Recommended Next Steps**:
|
||||
1. Start with Phase 1 (JSON export/import) - this unblocks all translation workflows
|
||||
2. Get user feedback on translation workspace mockups before Phase 2
|
||||
3. Defer theme integration to Phase 4 - not blocking functionality
|
||||
|
||||
**Estimated Effort**: ~7 weeks to MVP, ~21 dev days total.
|
||||
|
||||
**Success Criteria**: Translator can export messages to JSON, edit in external tool, and re-import without data loss. Side-by-side translation workspace reduces manual comparison time by 50%.
|
||||
56
docs/internal/plans/message_system_improvement_plan.md
Normal file
56
docs/internal/plans/message_system_improvement_plan.md
Normal file
@@ -0,0 +1,56 @@
|
||||
# Message System Improvement Plan
|
||||
|
||||
**Status**: Proposal
|
||||
**Last Updated**: 2025-11-21
|
||||
|
||||
This document outlines a plan to enhance the dialogue editing capabilities of YAZE, focusing on translation workflows and data portability.
|
||||
|
||||
## 1. JSON Import/Export
|
||||
|
||||
**Goal**: Enable external editing and version control of text.
|
||||
|
||||
* **Format**:
|
||||
```json
|
||||
[
|
||||
{
|
||||
"id": 0,
|
||||
"address": 917504,
|
||||
"text": "[W:00][SPD:00]Welcome to [D:05]...",
|
||||
"context": "Uncle dying in sewers"
|
||||
}
|
||||
]
|
||||
```
|
||||
* **Implementation**:
|
||||
* Add `SerializeMessages()` and `DeserializeMessages()` to `MessageData`.
|
||||
* Integrate with the existing CLI `export` commands.
|
||||
|
||||
## 2. Translation Workspace
|
||||
|
||||
**Goal**: Facilitate translating the game into new languages.
|
||||
|
||||
* **Side-by-Side View**: Show the original text (Reference) next to the editable text (Translation).
|
||||
* **Reference Source**: Allow loading a second "Reference ROM" or a JSON file to serve as the source text.
|
||||
* **Dictionary Management**:
|
||||
* **Auto-Optimization**: Analyze the full translated text to propose a *new* optimal dictionary for that language.
|
||||
* **Manual Editing**: Allow users to define custom dictionary entries.
|
||||
|
||||
## 3. Expanded Text Support
|
||||
|
||||
**Goal**: Break free from vanilla size limits.
|
||||
|
||||
* **Repointing**: Allow the text blocks to be moved to expanded ROM space (Banks 10+).
|
||||
* **Bank Management**: Handle bank switching commands automatically when text exceeds 64KB.
|
||||
|
||||
## 4. Search & Replace
|
||||
|
||||
**Goal**: Global editing operations.
|
||||
|
||||
* **Regex Support**: Advanced search across all messages.
|
||||
* **Batch Replace**: "Replace 'Hyrule' with 'Lorule' in all messages".
|
||||
|
||||
## 5. Scripting Integration
|
||||
|
||||
**Goal**: Allow procedural generation of text.
|
||||
|
||||
* **Lua/Python API**: Expose message data to the scripting engine.
|
||||
* **Usage**: "Generate 100 variations of the shopkeeper dialogue".
|
||||
56
docs/internal/plans/ui_modernization.md
Normal file
56
docs/internal/plans/ui_modernization.md
Normal file
@@ -0,0 +1,56 @@
|
||||
# UI Modernization & Architecture Plan
|
||||
|
||||
## Overview
|
||||
This document outlines the standard for UI development in `yaze`, focusing on the transition to a component-based architecture and full utilization of ImGui Docking.
|
||||
|
||||
## Core Architecture
|
||||
|
||||
### 1. The "Modern Editor" Standard
|
||||
New editors should follow the pattern established by `DungeonEditorV2`.
|
||||
|
||||
**Key Characteristics:**
|
||||
- **Component-Based**: The Editor class acts as a coordinator. Logic is delegated to specialized components (e.g., `RoomSelector`, `CanvasViewer`).
|
||||
- **Dependency Injection**: Use `EditorDependencies` struct for passing core systems (`Rom`, `EditorCardRegistry`, `Renderer`).
|
||||
- **ImGui Docking**: Use `ImGuiWindowClass` to group related windows (e.g., all Dungeon Editor tool windows dock together).
|
||||
- **No "Mega-Functions"**: Avoid massive `Draw()` methods. Each component handles its own drawing.
|
||||
|
||||
### 2. Window Management
|
||||
- **DockSpace**: The main application DockSpace is managed by `Controller` and `DockSpaceRenderer`.
|
||||
- **Editor Windows**: Editors should create their own top-level windows using `ImGui::Begin()` with appropriate flags.
|
||||
- **Card System**: Use `EditorCardRegistry` for auxiliary tool windows (e.g., "Room List", "Object Properties"). This allows users to toggle them via the "View" menu or Sidebar.
|
||||
|
||||
### 3. UI Coordinator
|
||||
`UICoordinator` is the central hub for application-level UI.
|
||||
- **Responsibilities**:
|
||||
- Drawing global UI (Command Palette, Welcome Screen, Dialogs).
|
||||
- Managing global popups.
|
||||
- coordinating focus between editors.
|
||||
- **Future Goal**: Move the main DockSpace creation from `Controller` to `UICoordinator` to centralize all UI logic.
|
||||
|
||||
## Immediate Improvements (Implemented)
|
||||
|
||||
### 1. Fix DockSpace Lifecycle
|
||||
`Controller::OnLoad` was missing the call to `DockSpaceRenderer::EndEnhancedDockSpace()`. This has been corrected to ensure proper cleanup and potential future post-processing effects.
|
||||
|
||||
### 2. Branch Organization
|
||||
Unstaged changes have been analyzed and a plan for organizing them into feature branches has been created (`docs/internal/plans/branch_organization.md`).
|
||||
|
||||
## Future Work
|
||||
|
||||
### 1. Centralize Main Window Logic
|
||||
Move the "DockSpaceWindow" creation from `Controller` to `UICoordinator::BeginFrame()`. This will allow `Controller` to remain agnostic of the specific UI implementation details.
|
||||
|
||||
### 2. Standardize Editor Flags
|
||||
Create a helper method `Editor::BeginWindow(const char* name, bool* p_open, ImGuiWindowFlags flags)` that automatically applies standard flags (like `ImGuiWindowFlags_UnsavedDocument` if dirty).
|
||||
|
||||
### 3. Visual Polish
|
||||
- **Background**: Enhance `DockSpaceRenderer` to support more dynamic backgrounds (currently supports grid/gradient).
|
||||
- **Theming**: Fully utilize `ThemeManager` for all new components. Avoid hardcoded colors.
|
||||
|
||||
## Migration Guide for Legacy Editors
|
||||
To convert a legacy editor (e.g., `GraphicsEditor`) to the new system:
|
||||
1. Identify distinct functional areas (e.g., "Tile Viewer", "Palette Selector").
|
||||
2. Extract these into separate classes/components.
|
||||
3. Update the main Editor class to initialize and update these components.
|
||||
4. Register the components as "Cards" in `EditorCardRegistry`.
|
||||
5. Remove the monolithic `Draw()` method.
|
||||
Reference in New Issue
Block a user