# Reactor Maintenance Tasks This backlog tracks procedural level generation, reusable exhaustive solving, Godot random play, and Godot-assisted campaign authoring automation. ## Audit Snapshot - Current simulation tests pass: `60/60` in `tests/ReactorMaintenance.Simulation.Tests`. - Godot level play includes pulse step playback, terminal-gated layer controls, campaign loading, and in-game level editing with JSON save. - Campaign data follows the tutorial plus six-group campaign from `docs/CAMPAIGN.md`. - The next implementation replaces the placeholder random-level flow with seed-driven generation and reusable solver analysis. - Win2D is not part of this backlog. ## P0 Generator Contract - [ ] Add a parameterized `LevelGenerationRequest`. - Include `Seed`, display name, optional max dimensions, `SolverDepthLimit`, target complexity, and `MaxAttempts`. - Require `InvolvedSystems` to contain at least one of `Fuel`, `Water`, or `Electricity`. - Specify exact available consumer counts per involved carrier. - Specify exact required consumer counts per involved carrier. - Specify the exact carrier set directly connected to the reactor control. - Reject impossible specs before generation, including required consumers greater than available consumers. - [ ] Add a player-facing seed profile expander. - Use the seed to choose involved systems. - Use the seed to choose available consumer counts. - Use the seed to choose required consumers as none, some, or all of the placed consumers. - Use the seed to choose how many involved systems directly connect to the reactor. - Expand to a concrete `LevelGenerationRequest` so random play and authoring use one generator path. - [ ] Generate levels without fixed archetypes. - Compose generated content from the requested systems, consumers, reactor connectivity, and difficulty target. - Avoid named campaign-group archetypes as public generation modes. - Let multi-system hazards emerge from generated overlapping fuel, water, electricity, heat, leak, sprinkler, and powered-prop placements. - [ ] Grow levels organically from the reactor. - Start the generated graph at the `ReactorControlProp`. - Grow carrier networks, branches, rooms, corridors, access routes, and player decision points outward from the reactor graph. - Place surrounding walls after gameplay geometry exists. - Calculate the occupied bounding box after generation. - Offset all coordinates into positive level space before creating final arrays. - Preserve valid wall geometry for doors, wall electricity leaks, and wall-mounted sprinkler valves. - [ ] Generate structural-integrity and pressure interactions. - Author weakened underground segments with controlled pressure or voltage exposure. - Generate pressure-fed and voltage-fed leaks that can be isolated, repaired, or allowed to worsen. - Generate hazards that restrict movement through `Unsafe` heat, electricity, or wet-electric combinations. - Include pressure tradeoffs from sprinkler discharge and consumer/reactor starvation. - Ensure generated hazards are reachable, readable, and tied to player choices. ## P0 Reusable Solver - [ ] Add a reusable `LevelSolver` in the simulation project. - Accept a `LevelState` and `SolverRequest`. - Return a `SolverReport` with terminal counts, complexity metrics, diagnostics, and representative traces. - Keep the solver independent from Godot so generator, editor, tests, and future tools can share it. - [ ] Define solver choices as reachable lengthy actions. - Collapse quick movement into safe reachability from the current robot position. - Enumerate all reachable prop interactions, leak repairs, remedy uses, heat shield uses, and reactor activation attempts. - Exclude inspection, selection, terminal viewing, and individual quick movement branches from primary metrics. - Sort canonical choices deterministically before evaluation. - [ ] Evaluate every bounded branch. - Explore all possible choice permutations to the configured lengthy-action depth limit. - Count `Win`, `Lose`, and `Inconclusive` leaves. - Mark branches inconclusive when the depth limit or timeout is reached before terminal outcome. - Treat no-choice non-ready states as losing dead ends. - Preserve exact branch counts while using transposition caching to avoid duplicate expansion work. - [ ] Add solver complexity metrics. - Report min and max player choices to win. - Report min and max player choices to loss. - Report max and average available choices per decision state. - Report lose/win ratio across all bounded permutations. - Report inconclusive ratio. - Report explored node count and cache hit count. - Provide representative shortest winning and losing traces. - [ ] Parallelize branch evaluation. - Issue all canonical choices from a state in parallel when budget allows. - Wait for all choice evaluations from that state. - Aggregate results in canonical order for deterministic diagnostics. - Use ThreadPool or TPL work stealing for nested parallel branch work. - Respect max parallelism, timeout, and cancellation. - [ ] Keep solver performance and memory usage controlled. - Clone level states only at branch boundaries. - Add per-thread reusable buffers or `LevelState` clone pools where practical. - Avoid retaining full state graphs when only metrics are needed. - Keep only bounded representative traces. - Evaluate whether `record struct` or other value-oriented refactors reduce heap pressure without harming maintainability. - Add allocation or stress tests for representative generated levels. ## P1 Generation Acceptance And Difficulty - [ ] Validate every generated candidate. - Run `LevelValidator`. - Run bounded solver analysis. - Reject candidates with validation errors. - Reject candidates with no winning branch. - Reject candidates whose required systems, consumer counts, or reactor-connected carrier set do not exactly match the request. - Reject candidates whose hazards cannot affect movement or meaningful decisions. - [ ] Add difficulty target filtering. - Filter by minimum and maximum choices to win. - Filter by maximum and average available choices. - Filter by lose/win ratio range. - Filter by maximum inconclusive ratio. - Filter by required first-choice variety. - Make defaults suitable for random play and configurable for campaign authoring. - [ ] Support campaign progression targets. - Early targets use fewer involved systems, lower available-choice counts, and low lose/win ratios. - Mid targets increase first-choice variety and introduce more losing branches. - Late targets allow more systems, more branching, higher lose/win ratio, and lower inconclusive tolerance. - Make target definitions data-driven enough for campaign automation scripts or Godot UI. - [ ] Add diagnostics for rejected candidates. - Report invalid spec reasons. - Report validation errors and warnings. - Report solver failure reasons. - Report mismatch against requested systems, consumers, reactor feeds, and complexity target. - Keep diagnostics concise enough for Godot UI and detailed enough for tests. ## P1 Godot Random Play And Authoring Automation - [ ] Replace placeholder random-level flow. - Generate a level from a player seed profile. - Save generated JSON under `user://generated/`. - Load generated levels through `LevelStateLoader`. - Retry the same generated level from the saved JSON. - Complete random levels by returning to generation or regenerating from a new seed. - [ ] Add authoring controls to `GenerationScreen`. - Toggle involved systems. - Set available consumers per carrier. - Set required consumers per carrier. - Toggle reactor-connected carriers. - Set seed, max attempts, solver depth limit, and target complexity. - Generate, regenerate, analyze, save JSON, begin play, and return to menu. - [ ] Surface solver metrics in Godot. - Show win, lose, and inconclusive counts. - Show min and max choices to win. - Show max and average available choices. - Show lose/win ratio and inconclusive ratio. - Show concise representative trace summaries for authoring review. - [ ] Reuse generated JSON in Godot editor mode. - Open generated levels in `LevelScreen`. - Allow normal edit-mode changes. - Validate and save back to the generated JSON path. - Preserve generated metadata needed for retry and review. - [ ] Keep Godot generation responsive. - Run generation and solver analysis off the main UI path. - Show progress, cancellation, and failure diagnostics. - Prevent starting a stale or failed generated candidate. ## P1 Tests - [ ] Add generator determinism tests. - Same request and seed serialize to identical JSON. - Different seeds produce meaningfully different layouts for the same request. - Player seed profile expansion is deterministic. - [ ] Add generation spec-compliance tests. - Generated involved systems match the request exactly. - Available consumer counts match the request exactly. - Required consumer counts match the request exactly. - Reactor-connected carriers match the request exactly. - Organic bounding and coordinate offset produce valid positive coordinates and correct array sizes. - [ ] Add generated hazard tests. - Generated pressure-fed leaks inject only when fed. - Structural-integrity hazards can create or worsen leaks under generated pressure or voltage. - Generated hazards can restrict movement through `Unsafe` rules. - Generated sprinkler pressure debt can affect consumer or reactor service. - [ ] Add solver correctness tests. - Known tiny levels report expected win, lose, and inconclusive counts. - Depth-limited branches become inconclusive. - No-choice non-ready states count as losing dead ends. - Canonical action ordering produces stable diagnostics. - Parallel and single-threaded solver runs produce identical reports. - [ ] Add solver performance tests. - Branch-heavy generated samples finish within the configured timeout. - Representative solving does not retain unbounded traces. - Clone or pooling behavior does not leak mutable state across branches. - [ ] Add Godot integration coverage where practical. - Generated JSON loads through `LevelStateLoader`. - Generated JSON saves through the existing level save path. - `FrontendSession` can point random mode at generated JSON. ## P2 Documentation And Tooling - [ ] Update `docs/design.md`. - Document procedural generation inputs. - Document solver outcomes and metrics. - Document generated structural-integrity and pressure-hazard expectations. - Document random play seed behavior. - [ ] Update `docs/UX.md`. - Replace placeholder random-level wording. - Describe generation controls, authoring controls, metrics display, progress, cancellation, and failure states. - Describe generated JSON editing and save-back flow. - [ ] Add authoring guidance. - Explain how generated levels can be promoted into campaign candidates. - Explain how increasing choices and lose/win ratio supports campaign progression. - Explain recommended solver depth and target complexity ranges. - [ ] Keep task status current. - Check off items as implementation lands. - Remove outdated task text instead of adding past-tense prose. - Keep verification commands aligned with repo instructions. ## Verification Rules - [ ] Run focused solver and generator tests after solver or generation changes. - [ ] Run full `dotnet test` before committing simulation, serializer, or generated-data changes. - [ ] Run `dotnet build ReactorMaintenance.slnx --no-restore` and `dotnet test ReactorMaintenance.slnx --no-restore` sequentially. - [ ] For code changes on Windows, run `python D:\Code\crlf.py` for recognized touched files. - [ ] For code changes on Windows, run `jb cleanupcode --verbosity:ERROR ReactorMaintenance.slnx`. - [ ] For documentation-only iterations, no cleanup pass is required. - [ ] Commit each completed iteration with a brief summary.