# Task 11: DoorPlacer Pass **Depends on:** Task 6 ## Context Files - `.dev/2026-05-28-procgen-map-core/spec/design.md` — §4.7 (Placer role), §5 (data flow). - `.dev/2026-05-28-procgen-map-core/README.md` — inter-pass data contract (DoorPlacer row). - `reikhelm-core/src/pass.rs` — `Pass`, `GenContext` (Task 6). - `reikhelm-core/src/map.rs`, `reikhelm-core/src/region.rs` — `Tile`, `Region`, `ConnGraph`, `Edge` (Task 5). - `reikhelm-core/src/grid.rs` — neighbor queries (Task 3). - `reikhelm-core/src/passes/mod.rs` — append the module declaration here. ## Files - Create: `reikhelm-core/src/passes/door.rs` — `DoorPlacer`. - Modify: `reikhelm-core/src/passes/mod.rs` — append `pub mod door;` and re-export `DoorPlacer`. ## What to Build A placer (spec §4.7) that puts doors where a corridor meets a room. Scan for boundary `Wall` cells that sit between a room interior and a corridor (a `Wall` whose opposite neighbors are both `Floor`, one belonging to a Room region and one to a Corridor region) and convert them to `Tile::Door`. For each graph edge, record a representative door location into `edge.at = Some(point)` via `ConnGraph::edges_mut()` (Task 5). Use `ctx.regions` to distinguish room floor from corridor floor (membership by `cells`/`bounds`), and `Grid` neighbor queries for adjacency. Bounds-safe; idempotent enough that it won't create doors mid-corridor or mid-room. This is the final pass; it reads `ctx.tiles`/`ctx.regions`/`ctx.graph` and writes `Door` tiles + populates `edge.at`. Tests construct a small room+corridor+wall layout directly. ## Interface Dependencies - **Consumes:** `Pass`, `GenContext`, `Rng` (Task 6); `Tile`, `Region`, `ConnGraph`, `Edge` (Task 5); `Grid` neighbor queries (Task 3). - **Produces:** - `struct DoorPlacer { /* unit or small config; Default */ }` — `default()`/`new()`; `impl Pass` with `name() == "door_placer"`. - **Writes to context:** `Door` tiles at room↔corridor boundaries; `edge.at = Some(point)` for connected edges. ## Tests - Given a hand-built room rect + a corridor reaching its wall (with a single wall cell between room floor and corridor floor), after running: that wall cell becomes `Door`. - No `Door` is placed in the middle of a room or corridor (only at boundaries). - At least one connected `edge` has `at == Some(_)` after running on a connected layout. - Bounds-safe: never panics on doors near the map edge. - Determinism: same input → identical door placement. ## Success Criteria - [ ] `DoorPlacer` converts room↔corridor boundary walls to `Door` and sets `edge.at`. - [ ] No spurious doors inside rooms/corridors; bounds-safe. - [ ] `pub mod door;` appended to `passes/mod.rs`. - [ ] Tests pass: `cargo test -p reikhelm-core door` ## Commit `"feat(core): DoorPlacer pass"`