# Sprint 9a — Complete Specification: `godotiq_build_scene`

## Problem Statement

The AI agent cannot efficiently create complex 3D scenes (e.g., 8x8 tile grid for Tower Defense). Current `node_ops` requires one dict per node, leading the agent to generate runtime GDScript instead. Runtime-generated nodes are invisible in the editor and impossible to debug. The MCP prompt also lacks a creation workflow.

## Solution: Three Deliverables

### Deliverable 1: `godotiq_build_scene` Tool

A bridge tool that creates multiple nodes in one call using high-level patterns (grid, line, scatter, nodes). Communicates via WebSocket → addon, following the existing bridge tool pattern.

#### Python-side API

```python
@mcp.tool()
async def godotiq_build_scene(
    scene: str = "",
    parent: str = "",
    detail: str = "brief",
    grid: dict | None = None,
    line: dict | None = None,
    scatter: dict | None = None,
    nodes: list[dict] | None = None,
) -> dict:
```

- Exactly ONE mode must be specified (grid, line, scatter, or nodes)
- Max 256 nodes per call (validated Python-side before sending)
- Python validates mode exclusivity and node count, then forwards to addon
- Pattern expansion happens in GDScript (addon-side)

#### Mode: Grid
Creates NxM grid of nodes. Parameters:
- `scene`: res:// path to instantiate
- `prefix`: name prefix (→ Prefix_row_col)
- `rows`, `cols`: grid dimensions
- `spacing`: distance between nodes (Godot units)
- `origin`: [x, y, z] starting position
- `axis`: "xz" (3D floor) or "xy" (2D)
- `overrides`: dict of "row,col" → spec overrides (scene, name, rotation, etc.)

#### Mode: Line
Creates nodes along a multi-segment path. Parameters:
- `scene`: res:// path to instantiate
- `prefix`: name prefix (→ Prefix_N)
- `points`: array of [x, y, z] waypoints (minimum 2)
- `spacing`: distance between nodes
- `align_to_path`: rotate nodes to face path direction
- **Includes endpoint**: a node is placed at the last point too

#### Mode: Scatter
Places nodes at explicit positions. Parameters:
- `items`: array of node specs, each with scene/type, position, name, optional rotation/scale/properties

#### Mode: Nodes
Batch add_child with clean syntax. Each item has:
- `type` or `scene`: what to create
- `name`: node name
- `position`, `rotation`, `scale`: optional transform
- `properties`: optional dict of property name → value

#### 2D Support
Auto-detect based on node type:
- Node3D → Vector3 position, rotation_degrees, scale
- Node2D/Control → Vector2 position

### GDScript Handler

Added to `godotiq_server.gd` dispatch:

```
"build_scene" → _handle_build_scene(peer_id, id, params)
```

**Undo/redo pattern: DEFERRED** (matching existing `_op_add_child`):
- `ur.add_do_method(parent, "add_child", node)` — deferred
- `ur.add_do_method(self, "_set_owner_recursive", node, scene_root)` — deferred
- `ur.add_do_reference(node)` — keep alive
- `ur.add_undo_method(parent, "remove_child", node)` — deferred
- `ur.add_do_property(node, "position", Vector3(...))` — deferred
- NO immediate `parent.add_child()` calls

**Error handling: Partial success**
- If a node spec fails (bad scene path, unknown type), log error and continue
- Single undo action covers all successfully created nodes
- Response includes both `created` count and `errors` array

**Pattern expansion functions:**
- `_expand_grid(grid)` → Array of node specs
- `_expand_line(line)` → Array of node specs (includes endpoint node)
- Scatter/nodes pass through directly

**Response:**
```json
{
    "created": 64,
    "errors": [],
    "total_requested": 64,
    "parent": "Terrain"
}
```

### Deliverable 2: Creation Workflow in MCP Prompt

Add "Creation Workflow" section to `godot_development_prompt_v2.md` covering:
1. Phase 1: Setup scene structure (nodes mode)
2. Phase 2: Build terrain (grid mode)
3. Phase 3: Add decorations (scatter mode)
4. Phase 4: Add key objects (placement + scatter)
5. Phase 5: Create scripts (logic only, NOT scene construction)
6. Phase 6: Verify (spatial_audit + signal_map + save)

Key principles: everything static in .tscn, one build_scene per group, save after each phase.

### Deliverable 3: Tests

**Python-side unit tests** (no bridge needed):
1. Parameter validation: mode exclusivity, node count limit (256)
2. Grid expansion: correct count, positions, overrides
3. Line expansion: spacing, rotation, multi-segment, endpoint inclusion
4. Scatter/nodes pass-through

**Integration tests** (against running addon, if available):
5. Grid 3x3 → 9 nodes created
6. Scatter 3 items → correct positions
7. Nodes 4 items → correct types

**Backward compatibility**: all existing tests pass.

## File Changes

| File | Action | Purpose |
|------|--------|---------|
| `src/godotiq/tools/bridge/build_scene.py` | CREATE | Python-side implementation |
| `src/godotiq/tools/bridge/__init__.py` | MODIFY | Register godotiq_build_scene |
| `src/godotiq/bridge/protocol.py` | MODIFY | Add build_scene timeout (30s) |
| `godot-addon/addons/godotiq/godotiq_server.gd` | MODIFY | Add handler + expansion functions |
| `src/godotiq/prompts/godot_development_prompt_v2.md` | MODIFY | Add Creation Workflow section |
| `tests/test_tools/test_build_scene.py` | CREATE | Unit + integration tests |

## Decision Log

| Decision | Choice | Rationale |
|----------|--------|-----------|
| Undo/redo pattern | Deferred (match existing) | Consistency with _op_add_child |
| Error handling | Partial success | More useful than all-or-nothing for large batches |
| Node limit | 256 per call | Supports 16x16 grid |
| 2D support | Yes, auto-detect | Node2D/Control get Vector2 |
| Line endpoint | Included | Node placed at final point |
| Pattern expansion | GDScript-side | Minimal WebSocket payload |
| Prompt file | godot_development_prompt_v2.md | Current active prompt |
| Timeout | 30s | Large batches may take time |
