diff --git a/.claude/settings.local.json b/.claude/settings.local.json new file mode 100755 index 0000000..7e07ac3 --- /dev/null +++ b/.claude/settings.local.json @@ -0,0 +1,176 @@ +{ + "permissions": { + "allow": [ + "Read", + "Write", + "Edit", + "Glob", + "Grep", + "Bash(node *)", + "Bash(npm *)", + "Bash(npx *)", + "Bash(ls *)", + "Bash(cd *)", + "Bash(mkdir *)", + "Bash(git status*)", + "Bash(git diff*)", + "Bash(git log*)", + "mcp__godot-mcp-pro__get_project_info", + "mcp__godot-mcp-pro__get_filesystem_tree", + "mcp__godot-mcp-pro__search_files", + "mcp__godot-mcp-pro__search_in_files", + "mcp__godot-mcp-pro__get_project_settings", + "mcp__godot-mcp-pro__uid_to_project_path", + "mcp__godot-mcp-pro__project_path_to_uid", + "mcp__godot-mcp-pro__get_scene_tree", + "mcp__godot-mcp-pro__get_scene_file_content", + "mcp__godot-mcp-pro__get_scene_exports", + "mcp__godot-mcp-pro__get_node_properties", + "mcp__godot-mcp-pro__get_node_groups", + "mcp__godot-mcp-pro__get_signals", + "mcp__godot-mcp-pro__find_nodes_in_group", + "mcp__godot-mcp-pro__find_nodes_by_type", + "mcp__godot-mcp-pro__find_signal_connections", + "mcp__godot-mcp-pro__find_node_references", + "mcp__godot-mcp-pro__get_scene_dependencies", + "mcp__godot-mcp-pro__list_scripts", + "mcp__godot-mcp-pro__read_script", + "mcp__godot-mcp-pro__get_open_scripts", + "mcp__godot-mcp-pro__validate_script", + "mcp__godot-mcp-pro__get_editor_errors", + "mcp__godot-mcp-pro__get_output_log", + "mcp__godot-mcp-pro__get_editor_screenshot", + "mcp__godot-mcp-pro__get_game_scene_tree", + "mcp__godot-mcp-pro__get_game_node_properties", + "mcp__godot-mcp-pro__get_game_screenshot", + "mcp__godot-mcp-pro__find_nodes_by_script", + "mcp__godot-mcp-pro__get_autoload", + "mcp__godot-mcp-pro__find_ui_elements", + "mcp__godot-mcp-pro__batch_get_properties", + "mcp__godot-mcp-pro__get_input_actions", + "mcp__godot-mcp-pro__list_animations", + "mcp__godot-mcp-pro__get_animation_info", + "mcp__godot-mcp-pro__get_animation_tree_structure", + "mcp__godot-mcp-pro__get_audio_bus_layout", + "mcp__godot-mcp-pro__get_audio_info", + "mcp__godot-mcp-pro__get_physics_layers", + "mcp__godot-mcp-pro__get_collision_info", + "mcp__godot-mcp-pro__get_performance_monitors", + "mcp__godot-mcp-pro__get_editor_performance", + "mcp__godot-mcp-pro__read_resource", + "mcp__godot-mcp-pro__get_resource_preview", + "mcp__godot-mcp-pro__read_shader", + "mcp__godot-mcp-pro__get_shader_params", + "mcp__godot-mcp-pro__get_navigation_info", + "mcp__godot-mcp-pro__get_particle_info", + "mcp__godot-mcp-pro__get_theme_info", + "mcp__godot-mcp-pro__tilemap_get_cell", + "mcp__godot-mcp-pro__tilemap_get_info", + "mcp__godot-mcp-pro__tilemap_get_used_cells", + "mcp__godot-mcp-pro__find_unused_resources", + "mcp__godot-mcp-pro__analyze_signal_flow", + "mcp__godot-mcp-pro__analyze_scene_complexity", + "mcp__godot-mcp-pro__find_script_references", + "mcp__godot-mcp-pro__detect_circular_dependencies", + "mcp__godot-mcp-pro__get_project_statistics", + "mcp__godot-mcp-pro__get_export_info", + "mcp__godot-mcp-pro__list_export_presets", + "mcp__godot-mcp-pro__compare_screenshots", + "mcp__godot-mcp-pro__navigate_to", + "mcp__godot-mcp-pro__find_nearby_nodes", + "mcp__godot-mcp-pro__get_test_report", + "mcp__godot-mcp-pro__wait_for_node", + "mcp__godot-mcp-pro__set_project_setting", + "mcp__godot-mcp-pro__create_scene", + "mcp__godot-mcp-pro__open_scene", + "mcp__godot-mcp-pro__save_scene", + "mcp__godot-mcp-pro__add_scene_instance", + "mcp__godot-mcp-pro__add_node", + "mcp__godot-mcp-pro__duplicate_node", + "mcp__godot-mcp-pro__move_node", + "mcp__godot-mcp-pro__rename_node", + "mcp__godot-mcp-pro__update_property", + "mcp__godot-mcp-pro__add_resource", + "mcp__godot-mcp-pro__set_anchor_preset", + "mcp__godot-mcp-pro__connect_signal", + "mcp__godot-mcp-pro__disconnect_signal", + "mcp__godot-mcp-pro__set_node_groups", + "mcp__godot-mcp-pro__create_script", + "mcp__godot-mcp-pro__edit_script", + "mcp__godot-mcp-pro__attach_script", + "mcp__godot-mcp-pro__create_animation", + "mcp__godot-mcp-pro__add_animation_track", + "mcp__godot-mcp-pro__set_animation_keyframe", + "mcp__godot-mcp-pro__create_animation_tree", + "mcp__godot-mcp-pro__add_state_machine_state", + "mcp__godot-mcp-pro__add_state_machine_transition", + "mcp__godot-mcp-pro__set_blend_tree_node", + "mcp__godot-mcp-pro__set_tree_parameter", + "mcp__godot-mcp-pro__add_audio_bus", + "mcp__godot-mcp-pro__set_audio_bus", + "mcp__godot-mcp-pro__add_audio_bus_effect", + "mcp__godot-mcp-pro__add_audio_player", + "mcp__godot-mcp-pro__set_input_action", + "mcp__godot-mcp-pro__add_mesh_instance", + "mcp__godot-mcp-pro__setup_lighting", + "mcp__godot-mcp-pro__set_material_3d", + "mcp__godot-mcp-pro__setup_environment", + "mcp__godot-mcp-pro__setup_camera_3d", + "mcp__godot-mcp-pro__add_gridmap", + "mcp__godot-mcp-pro__setup_collision", + "mcp__godot-mcp-pro__set_physics_layers", + "mcp__godot-mcp-pro__add_raycast", + "mcp__godot-mcp-pro__setup_physics_body", + "mcp__godot-mcp-pro__setup_navigation_region", + "mcp__godot-mcp-pro__bake_navigation_mesh", + "mcp__godot-mcp-pro__setup_navigation_agent", + "mcp__godot-mcp-pro__set_navigation_layers", + "mcp__godot-mcp-pro__create_particles", + "mcp__godot-mcp-pro__set_particle_material", + "mcp__godot-mcp-pro__set_particle_color_gradient", + "mcp__godot-mcp-pro__apply_particle_preset", + "mcp__godot-mcp-pro__create_resource", + "mcp__godot-mcp-pro__edit_resource", + "mcp__godot-mcp-pro__create_shader", + "mcp__godot-mcp-pro__edit_shader", + "mcp__godot-mcp-pro__assign_shader_material", + "mcp__godot-mcp-pro__set_shader_param", + "mcp__godot-mcp-pro__create_theme", + "mcp__godot-mcp-pro__set_theme_color", + "mcp__godot-mcp-pro__set_theme_constant", + "mcp__godot-mcp-pro__set_theme_font_size", + "mcp__godot-mcp-pro__set_theme_stylebox", + "mcp__godot-mcp-pro__tilemap_set_cell", + "mcp__godot-mcp-pro__tilemap_fill_rect", + "mcp__godot-mcp-pro__batch_set_property", + "mcp__godot-mcp-pro__cross_scene_set_property", + "mcp__godot-mcp-pro__add_autoload", + "mcp__godot-mcp-pro__reload_plugin", + "mcp__godot-mcp-pro__reload_project", + "mcp__godot-mcp-pro__clear_output", + "mcp__godot-mcp-pro__play_scene", + "mcp__godot-mcp-pro__stop_scene", + "mcp__godot-mcp-pro__simulate_key", + "mcp__godot-mcp-pro__simulate_mouse_click", + "mcp__godot-mcp-pro__simulate_mouse_move", + "mcp__godot-mcp-pro__simulate_action", + "mcp__godot-mcp-pro__simulate_sequence", + "mcp__godot-mcp-pro__set_game_node_property", + "mcp__godot-mcp-pro__capture_frames", + "mcp__godot-mcp-pro__record_frames", + "mcp__godot-mcp-pro__monitor_properties", + "mcp__godot-mcp-pro__start_recording", + "mcp__godot-mcp-pro__stop_recording", + "mcp__godot-mcp-pro__replay_recording", + "mcp__godot-mcp-pro__click_button_by_text", + "mcp__godot-mcp-pro__move_to", + "mcp__godot-mcp-pro__run_test_scenario", + "mcp__godot-mcp-pro__assert_node_state", + "mcp__godot-mcp-pro__assert_screen_text", + "mcp__godot-mcp-pro__run_stress_test" + ] + }, + "enabledMcpjsonServers": [ + "godot-mcp-pro" + ] +} diff --git a/.gitignore b/.gitignore index 4e649ae..607a22f 100644 --- a/.gitignore +++ b/.gitignore @@ -40,3 +40,25 @@ Thumbs.db coverage/ .coverage .nyc_output/ + +# Godot 4 +.godot/ +.import/ +*.translation +export.cfg +export_credentials.cfg +*.tmp + +# Godot exports (built game binaries) +exports/ +*.exe +*.x86_64 +*.app +*.zip + +# Proprietary addons — installed locally from the paid zip, not redistributed +# (Godot MCP Pro lives at D:\godot\mcp\; re-copy on fresh clone — see CLAUDE.md) +addons/godot_mcp/ + +# Local-only Claude Code subagent definitions (personal AI tooling) +.claude/agents/ diff --git a/.mcp.json b/.mcp.json new file mode 100644 index 0000000..85796a5 --- /dev/null +++ b/.mcp.json @@ -0,0 +1,10 @@ +{ + "mcpServers": { + "godot-mcp-pro": { + "command": "node", + "args": [ + "/mnt/d/godot/mcp/server/build/index.js" + ] + } + } +} diff --git a/CLAUDE.md b/CLAUDE.md index a3039ce..0fa9633 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -22,3 +22,29 @@ Working title `rimlike` — rename TBD. - **i18n from day one:** all player-visible strings live in a string table; English-only ship plan but no hardcoded copy in code. - **Conventions:** GDScript with Godot's standard idioms. Class-per-file. Snake_case for files and variables. Tilesets imported from the bundle's `Tilesets/*.png` directly (skip the .unitypackage / .yymps / RPG Maker variants). - **Open scope:** the `Vertical slice` in `memory.md` is the MVP target — realistic timeline 3–6 months solo. Do not silently expand scope; fork choices live in `memory.md` Open questions. + +### MCP Pro integration +AI assistant tools come from **Godot MCP Pro** (172 tools, paid, proprietary). Two pieces: +- **Server** at `D:\godot\mcp\server\` (= `/mnt/d/godot/mcp/server/` from WSL) — Node.js, shared across all Godot projects on this machine, **not** part of this repo. +- **Editor plugin** at `addons/godot_mcp/` — copied from the paid zip, **gitignored** (proprietary license, not redistributed). Re-copy on a fresh clone (once the Godot project is scaffolded): `cp -r /mnt/d/godot/mcp/addons/godot_mcp ./addons/`, then in Godot: Project → Project Settings → Plugins → Godot MCP Pro → Enable. +- `.mcp.json` here wires Claude Code → server. `.claude/settings.local.json` is the pre-built read-only-tool allowlist from the zip (committed). +- The Godot editor must be running with the plugin enabled before Claude can use MCP tools — look for the green dot in the "MCP Pro" bottom panel. +- **Editor vs runtime tools**: editor tools always work; runtime tools (`get_game_*`, `simulate_*`, `assert_*`, etc.) need `play_scene` first. Full split in `addons/godot_mcp/skills.*.md` or `D:\godot\mcp\instructions\CLAUDE.md`. +- Don't set `GODOT_MCP_PORT` in `.mcp.json` — server auto-scans 6505–6509; fixed port causes silent failures with stale Node processes. If "Editor not connected" persists, kill any leftover `node.exe` in Task Manager. + +### Delegation: tiered subagents (cost/speed) +The main conversation runs on Opus. Three project-local subagents in `.claude/agents/` exist to offload work to cheaper, faster models. **Default to delegation** for any well-defined task that fits an agent's description — including small mechanical edits. Don't skip delegation just because the edit is tiny; the user wants the tiered system visibly firing on its natural workload. + +- **`quick-edit`** (Haiku) — mechanical edits to `.gd` files: typos, renames, removing `print()`s, removing unused imports, single-line fixes. **Default for any rename or search-and-replace.** Tools restricted to file-edit + grep. +- **`researcher`** (Haiku) — read-only codebase exploration: "where is X defined", "what connects to signal Y", "which scenes reference resource Z". Returns a digested summary, not raw grep output. **Default for any exploration or audit question** before designing a feature. +- **`gdscript-refactor`** (Sonnet) — medium-scope GDScript work that needs reasoning but no architecture decisions: extract a method, thread a parameter through several call sites, add a save/load seam, write a small new autoload. + +**Keep on Opus only when:** +- the file/files are already loaded in your context from an earlier turn in this conversation (Haiku would re-read from scratch, blowing the savings), OR +- the task needs MCP Pro editor tools (scenes, runtime, `play_scene`, `execute_game_script`), OR +- the user is iterating tightly with you and a subagent would break the loop, OR +- the work is genuinely architectural / ambiguous and needs your judgement. + +When in doubt, delegate — overhead on a wasted dispatch is cheap; missed savings on Opus-doing-Haiku-work compound across the session. + +**Report delegation in the final summary.** When you finish a task, briefly say which subagents you used and what for — e.g. *"Used `researcher` (Haiku) to locate the JobRunner call sites; did the refactor on Opus."* If you handled everything yourself, say *"No delegation — handled on Opus."* One short line at the end of the response is enough; the user wants to see whether the tiered-model system is actually firing.