# Complete Level Workflows — Incremental Build Patterns

> Use `query_ue_api('EditorActorSubsystem')` and `dir()` to discover the exact spawning, lighting, and level subsystem APIs before writing any code. Never assume API names — discover them at runtime.

All level operations use `execute_python` with `import unreal`. Follow these workflow patterns. Split each phase into a SEPARATE `execute_python` call. Verify with `print()` after every step.

## API Discovery (MANDATORY first step)

Before any level work, discover the current editor subsystem for spawning actors via `query_ue_api('EditorActorSubsystem')`. Find:
- The actor spawning subsystem
- The level saving API
- Actor enumeration methods

Then use `dir()` on the discovered subsystem instance to find exact method names for spawning, destroying, and enumerating actors.

## Enclosed Room Workflow (step-by-step)

This is the REFERENCE pattern for building any enclosed space. Each step is a SEPARATE `execute_python` call.

### Step 1: Define dimensions and place floor

**Workflow:**
1. Define ALL dimensions as named variables at the top (room width, depth, wall height, wall thickness, floor thickness — all in centimeters)
2. Load the engine's built-in Cube mesh from `/Engine/BasicShapes/Cube`
3. Spawn the floor actor at the origin using the discovered spawning subsystem
4. Scale it to `(RoomWidth/100, RoomDepth/100, FloorThickness/100)` — UE basic shapes are 100cm cubes, so dividing by 100 converts cm to scale units
5. Label it with `set_actor_label('Floor_Main')`
6. Assign folder: `set_folder_path('Environment/Blockout')`
7. Print the placed dimensions to verify

### Step 2: Place walls (verify they connect at corners)

**Workflow:**
1. Spawn 4 wall actors (North, South, East, West) using the same Cube mesh
2. Position each wall at `Z = WallHeight / 2` so the bottom edge sits flush on the floor (NOT at Z=0, which embeds half the wall underground)
3. **Corner seam fix:** extend the North/South walls by `WallThickness` in the X direction so they overlap at corners — this prevents visible gaps
4. East/West walls span only the interior depth (no extension needed)
5. Label every wall: `Wall_North`, `Wall_South`, `Wall_East`, `Wall_West`
6. Assign folder: `set_folder_path('Environment/Blockout')` on every wall
7. **VERIFY:** enumerate all level actors, filter by label containing "Wall" or "Floor", print position and scale for each

### Step 3: Add door opening (two wall segments replacing one wall)

**Workflow:**
1. Define door dimensions (width, height) as variables
2. Find and destroy the wall that should contain the door (e.g., `Wall_South`) by iterating actors and matching the label
3. Calculate segment width: `(RoomWidth - DoorWidth) / 2`
4. Spawn two wall segments — one left of the door opening, one right — positioned to leave the gap
5. Spawn a door lintel (horizontal beam above the door) spanning the door width at the door's top edge
6. Label everything: `Wall_South_L`, `Wall_South_R`, `Door_Lintel`
7. Assign folder: `set_folder_path('Environment/Blockout')` on all wall segments
8. Print all new actors to verify positions

### Step 4: Add cover objects and PlayerStart

**Workflow:**
1. Define cover height as a variable (e.g., 90cm for half-cover)
2. Spawn cover objects (Cube meshes) at strategic positions inside the room
3. Position each at `Z = CoverHeight / 2` (same half-height rule as walls)
4. Scale each to desired proportions (e.g., wide and thin for barricades)
5. Label each cover: `Cover_Left`, `Cover_Right`, `Cover_Center`, etc.
6. Assign folder: `set_folder_path('Gameplay/Cover')` on cover actors
7. Spawn a `PlayerStart` actor near the door entrance — discover the PlayerStart class via `query_ue_api('PlayerStart')` or use `unreal.PlayerStart` directly
8. Assign PlayerStart folder: `set_folder_path('Gameplay')`
9. **VERIFY:** enumerate all actors by folder, print labels and positions

### Step 5: Add lighting

**Workflow:**
1. Spawn a main room light (PointLight type) near the ceiling — position at `Z` near the top of the walls
2. Access the light component on the spawned actor (use `get_component_by_class` with the point light component type — discover exact type via `query_ue_api('PointLightComponent')`)
3. Set intensity and attenuation radius via `set_editor_property`
4. Assign folder: `set_folder_path('Lighting')` on the main light
5. Spawn an accent light at the doorway (SpotLight type) — angled downward, warm color to draw the player
6. Set the accent light's rotation, intensity, cone angle, and color via `set_editor_property`
7. Assign folder: `set_folder_path('Lighting')` on the accent light
8. Save the level using the level-saving API — discover via `query_ue_api('EditorLevelUtils')`
9. Print confirmation

### Step 6: Final audit (MANDATORY before attempt_completion)

**Workflow:**
1. Enumerate ALL actors in the level using the discovered subsystem
2. Group actors by folder path — print organized by folder (Environment, Lighting, Gameplay, etc.)
3. For each labeled actor, print: folder, label, class name, position (X, Y, Z), and scale
4. Review the output for:
   - Missing actors (walls, floor, lights, PlayerStart)
   - Incorrect Z positions (embedded in floor, floating above ground)
   - Scale mismatches (walls not matching room dimensions)
   - Missing labels
   - **Missing folder assignments** — every actor MUST have a folder, no actors in (Root)

## Common Mistakes (AVOID)

| Mistake | Why it fails | Fix |
|---------|-------------|-----|
| Wall at Z=0 | Bottom half embedded in floor | Place at Z = WallHeight / 2 |
| Walls don't meet at corners | Gaps visible from player perspective | Extend N/S walls by WallThickness |
| Cover at Z=0 | Half the cover is underground | Place at Z = CoverHeight / 2 |
| All code in one giant script | One error kills everything; hard to debug | Split into steps, verify each |
| No print() verification | You won't see if spawn returned None | ALWAYS print after every spawn |
| No `set_actor_label()` | Can't identify or audit actors later | Label EVERY spawned actor |
| No `set_folder_path()` | Outliner is a flat mess, hard to navigate | Assign folder to EVERY actor |
| Hardcoded magic numbers | Impossible to adjust proportions | Define all dimensions as variables |
| Using deprecated APIs | Calls fail or behave unexpectedly | Always discover APIs via `query_ue_api('ClassName')` with a specific class name first |

## Outdoor Arena Workflow (summary)

Same incremental approach, different phases:
1. Ground plane (large floor, slight terrain with scaled cubes)
2. Boundary walls or natural barriers (rocks = scaled spheres/cylinders from `/Engine/BasicShapes/`)
3. Cover and obstacles in play area
4. 4-layer outdoor lighting: DirectionalLight + SkyLight + SkyAtmosphere + ExponentialHeightFog — discover each via `query_ue_api('DirectionalLight')`, `query_ue_api('SkyLight')`, etc.
5. PlayerStart + navigation audit
6. Final audit with full actor list

## Multi-Room Building Workflow (summary)

1. Define GRID: room sizes, corridor widths, wall thickness as variables
2. Build Room 1 (floor + walls + door opening) -> verify
3. Build Corridor connecting rooms -> verify
4. Build Room 2 -> verify connection with corridor
5. Lighting per room (indoor PointLights) + corridor lights
6. Cover/furniture per room
7. PlayerStart + full audit

## Key Geometry Rules

- **UE basic shapes** (`/Engine/BasicShapes/Cube`, `Sphere`, `Cylinder`) are 100x100x100 cm at scale 1.0. Scale = desired size / 100.
- **Z positioning:** actors pivot at their center. An object meant to sit ON the floor must be at `Z = ObjectHeight / 2`.
- **Wall overlap at corners:** one pair of opposing walls (e.g., N/S) should be extended by wall thickness to cover the corner joints. The other pair (E/W) stays at interior dimensions.
- **Door openings:** never leave a gap — always add a lintel beam above the door, even if it's small.
