# Sprint 11a — Research Findings

## Codebase Analysis

### 1. Current `_handle_run` Implementation (godotiq_server.gd:260-303)

The current run handler:
- Uses `play_main_scene()` when scene is null or "main" (line 294)
- Uses `play_current_scene()` when scene is "current" (line 296)
- Uses `play_custom_scene()` for specific res:// paths (line 298)
- Hardcoded 5-second timeout for `_pending_run` (line 302)
- Polling happens in `_process()` (line 148-156) checking `is_playing_scene()`
- On timeout, sends `RUN_TIMEOUT` error with "Scene did not start within 5 seconds"
- Pre-flight script validation happens before launch (lines 264-291)

**Key issue**: `play_main_scene()` is used for the default case but has been found unreliable — `is_playing_scene()` stays false even though no error occurs.

### 2. Current `run.py` (Python-side)

Very simple — just 29 lines. Forwards action and scene to bridge with no timeout parameter, no adaptive logic. The bridge handles timeout at WebSocket level.

### 3. Current `build_scene` Response (godotiq_server.gd:1324-1330)

Response includes: `created`, `errors`, `total_requested`, `parent`, `truncated`. Does NOT include node names of created nodes.

### 4. Node Search — Already Has Recursive Fallback

`_find_node_by_name_or_path` (line 545-549) already does:
1. Try `get_node_or_null(NodePath(name_or_path))`
2. Fallback to `_find_by_name_recursive(scene_root, name_or_path)`

This is used in build_scene for parent resolution but NOT in state_inspect (which is game-side via `_handle_game_forward`).

### 5. `script_ops.py` — No Bridge Interaction

Pure Python filesystem operations. After writing a .gd file, it does NOT call back to the Godot editor to reload/scan. This is the root cause of script cache staleness.

### 6. Prompt File Status

`src/godotiq/prompts/godot_development.md` is deleted from working tree but exists in git HEAD. Contains ~150 lines of tool reference and workflow documentation. No "Known Godot Quirks" section exists.

### 7. Bridge Tool Registration Pattern

All bridge tools are in `src/godotiq/tools/bridge/`. Each module exports an async function. The `__init__.py` imports them and wraps them in `@mcp.tool()` decorators with error handling. Adding a new tool requires:
1. Create `src/godotiq/tools/bridge/new_tool.py` with async function
2. Import in `src/godotiq/tools/bridge/__init__.py`
3. Add `@mcp.tool()` wrapper
4. Add GDScript handler in `godotiq_server.gd` dispatch table

### 8. Testing Setup

- pytest with `asyncio_mode = "auto"`
- Test files in `tests/test_tools/`
- Bridge tests mock the bridge connection
- `conftest.py` in `tests/test_tools/` provides fixtures
- Tests for build_scene, check_errors, etc. already exist

### 9. Dispatch Table (godotiq_server.gd:184-229)

All methods go through `_dispatch()` match statement. Adding new handlers requires:
1. Add case to match statement
2. Implement `_handle_X` function

Current handlers: ping, editor_context, scene_tree, node_ops, run, stop, screenshot, perf_snapshot, input, exec, state_inspect, nav_query, watch, ui_map, undo_history, exec_editor, save_scene, editor_screenshot, camera, build_scene, check_errors.

---

## Web Research Findings

### 1. Godot EditorInterface: play_main_scene vs play_current_scene

- `play_main_scene()` launches the scene set in `application/run/main_scene` in project.godot
- Known issue: if the main scene path is not properly set or the project hasn't been saved, `play_main_scene()` can silently fail
- `play_current_scene()` is more reliable because it operates on the scene already loaded in the editor tab
- `play_custom_scene(path)` should work but some users report issues with relative paths
- **Recommendation**: Using `play_current_scene()` with explicit `open_scene_from_path()` beforehand is the most reliable pattern

### 2. GDScript Script Reload & Cache Invalidation

- **Godot Issue #75388**: `global_script_class_cache.cfg` must be populated before class_name references work. Autoloaded scripts load before the cache is populated.
- Fixed in PR #92303 for Godot 4.3+, but editor cache staleness still affects runtime operations
- `GDScript.reload()` forces recompilation of a single script
- `EditorInterface.get_resource_filesystem().scan()` triggers a full filesystem rescan, which updates the resource database
- `ResourceLoader.load(path, "", ResourceLoader.CACHE_MODE_REPLACE)` can force cache refresh
- **Recommendation**: After creating a new .gd file, call `load(path).reload()` + `filesystem.scan()` to ensure the editor recognizes it

### 3. Godot Adaptive Timeout / Large Project Loading

- Projects with 100+ GLB files can take 10-67 seconds to load depending on hardware and platform
- Godot issue documents 20,000+ file projects taking ~67 seconds on Windows, ~17 seconds on Linux
- No built-in "scene ready" callback for editor plugins to detect when play completes loading
- `is_playing_scene()` becomes true once the game window appears, but asset loading continues in the game process
- **Recommendation**: 5-second timeout is far too short for asset-heavy projects. 15-20 seconds is safer, with adaptive scaling based on project size.

### 4. Testing Patterns

Existing test setup uses pytest + pytest-asyncio with mock bridge. No changes needed to test framework. New tests should mock bridge.request() and verify parameters passed.
