# Task 12: Dungeon Recipe + Integration Tests **Depends on:** Task 7, Task 8, Task 9, Task 10, Task 11 ## Context Files - `.dev/2026-05-28-procgen-map-core/spec/design.md` — §4.8 (recipes), §8 (error handling), §9 (testing), §10 (acceptance). - `.dev/2026-05-28-procgen-map-core/README.md` — inter-pass data contract (the full chain). - `reikhelm-core/src/pass.rs` — `Pipeline` (Task 6). - `reikhelm-core/src/passes/mod.rs` — all five passes + their configs (Tasks 7–11). - `reikhelm-core/src/lib.rs` — append the module declaration here. ## Files - Create: `reikhelm-core/src/recipes/mod.rs` — recipes module root; append `pub mod dungeon;`. - Create: `reikhelm-core/src/recipes/dungeon.rs` — `DungeonConfig`, `ConfigError`, `dungeon()`; integration tests. - Modify: `reikhelm-core/src/lib.rs` — append `pub mod recipes;`. ## What to Build The dungeon recipe (spec §4.8): a function that validates a config and assembles the full pipeline — `BspPartition` → `RoomCarver` → `MstConnect` → `CorridorCarver` → `DoorPlacer` — sized to the config. `DungeonConfig` composes the per-pass configs and the map dimensions, with sensible `Default`s. Validation (spec §8) runs at recipe construction: dimensions > 0, and the room min size must be able to fit within the smallest possible BSP leaf (`min_leaf`), returning `ConfigError` rather than panicking. This task also carries the cross-pass **integration tests** (spec §9) that prove the whole chain works. ## Interface Dependencies - **Consumes:** `Pipeline` (Task 6); all five passes + configs (Tasks 7–11). - **Produces:** - `struct DungeonConfig { width: u32, height: u32, bsp: BspConfig, rooms: RoomConfig, connect: ConnectConfig }` (+ `Default`). - `enum ConfigError { /* e.g. ZeroDimension, RoomLargerThanLeaf, ... */ }` (impl `std::error::Error`/`Display`). - `fn dungeon(cfg: DungeonConfig) -> Result`. ## Tests (integration — spec §9) - **Determinism:** `dungeon(cfg)?.run(42)` twice produces equal `Map`s and identical `to_ascii()`. - **`run` == `run_with_snapshots`:** same seed yields the same `Map`; snapshot count == 5. - **Connectivity:** flood-fill the `Floor`/`Door` tiles of a generated dungeon; assert every `Room` region's interior is reachable (no orphaned rooms). - **Bounds:** no non-`Wall` tile lies outside the map; all rooms within bounds. - **Config validation:** zero dimensions and a room-min-size larger than `min_leaf` both return `Err(ConfigError)`, not a panic. - **Door reachability sanity:** at least one `Door` tile exists in a multi-room dungeon, and connected edges have `at == Some(_)`. - (Optional) print one ASCII dungeon in a `#[test]` behind `--nocapture` for eyeball confirmation. ## Success Criteria - [ ] `dungeon(cfg)` validates config and returns a `Pipeline` (or `ConfigError`) assembling all five passes in order. - [ ] A generated dungeon is fully connected, in-bounds, deterministic, and has doors. - [ ] `run` and `run_with_snapshots` agree; snapshot count is 5. - [ ] Module declarations added to `lib.rs`/`recipes/mod.rs`. - [ ] All tests pass: `cargo test -p reikhelm-core` (full suite green) ## Commit `"feat(core): dungeon recipe + end-to-end integration tests"`