diff --git a/src/simulator/api-gdext/src/player_api.rs b/src/simulator/api-gdext/src/player_api.rs index dcef1347..74609592 100644 --- a/src/simulator/api-gdext/src/player_api.rs +++ b/src/simulator/api-gdext/src/player_api.rs @@ -276,7 +276,6 @@ fn normalize_int_zero_floats(src: &str) -> String { j += 1; } if bytes[j].is_ascii_digit() { - let digit_start = j; while j < bytes.len() && bytes[j].is_ascii_digit() { j += 1; } diff --git a/tooling/claude-player-mcp/src/harness.ts b/tooling/claude-player-mcp/src/harness.ts index 9c7428c6..dcbd3caa 100644 --- a/tooling/claude-player-mcp/src/harness.ts +++ b/tooling/claude-player-mcp/src/harness.ts @@ -47,6 +47,12 @@ export class HarnessClient { private nextId = 1; private closed = false; + /** True after the child exits (clean or crash). Lets the MCP layer + * detect a dead harness and respawn instead of erroring forever. */ + get isClosed(): boolean { + return this.closed; + } + constructor(opts: HarnessOptions) { this.opts = { env: {}, diff --git a/tooling/claude-player-mcp/src/index.ts b/tooling/claude-player-mcp/src/index.ts index 426d55f8..6dc4533a 100644 --- a/tooling/claude-player-mcp/src/index.ts +++ b/tooling/claude-player-mcp/src/index.ts @@ -108,8 +108,19 @@ interface HarnessHolder { const holder: HarnessHolder = { client: null }; function getOrCreateClient(): HarnessClient { - if (holder.client !== null) return holder.client; - emitStderr(`spawning harness: ${serverScript()}`); + // Auto-respawn: if the held client died (godot child crashed, was killed by + // a developer iterating on the dylib, etc.) treat it as `null` so the next + // request gets a fresh harness. Without this, every Claude Code session + // that hit a single harness crash would need a full restart to recover. + if (holder.client !== null && !holder.client.isClosed) { + return holder.client; + } + if (holder.client !== null) { + emitStderr("previous harness closed; respawning"); + holder.client = null; + } else { + emitStderr(`spawning harness: ${serverScript()}`); + } const client = new HarnessClient({ serverScript: serverScript(), env: harnessEnv(),