13 KiB
13 KiB
Reactor Maintenance Tasks
This backlog tracks what must change so the implementation matches docs/design.md, docs/UX.md, and docs/CAMPAIGN.md.
Audit Snapshot
- Current simulation tests pass:
54/54intests/ReactorMaintenance.Simulation.Tests. - Godot has a usable UX scaffold and grid renderer; the full pulse playback, terminal-gated layer controls, and campaign content pass remain in later tasks.
- Existing campaign data is the older placeholder set. These levels and manifest entries must be replaced by the tutorial plus six-group campaign from
docs/CAMPAIGN.md. - Unrelated Godot metadata or generated
.uidfiles are not part of this backlog unless a later implementation task intentionally touches them.
P0 Simulation Contract
- Rename the public environment tick model from turn-based
AdvanceTurn/EndTurnsemantics toPulsesemantics.- One accepted
LengthyActiontriggers exactly onePulse. - One
Pulsecontains a fixed balance-defined number of deterministicSteps. - The fixed step count must not vary by action type, forecast result, or danger level.
- Keep isolated step or pulse advancement available only for tests, editor tooling, or debug use.
- One accepted
- Remove player-facing wait/fast-forward behavior from normal gameplay.
MoveRobot, selection, inspection, and terminal layer viewing remainQuickActions.InteractProp,InteractLeak,ApplyHeatShield, and accepted powered-prop no-op interactions areLengthyActions.ActivateReactorwins whenReactorReadinessis true and must not require a separate wait.
- Add
IsolationValvePropas a first-class prop.- Store carrier binding and
Open/Closedstate. - Block intentional underground propagation across the authored branch boundary.
- Preserve downstream starvation/readiness consequences for consumers and reactor feed.
- Add editor placement, validation, serialization, and rendering support.
- Store carrier binding and
- Add
SprinklerControlPropand wall-mountedSprinklerValve.- A
SprinklerControlProplinks to exactly oneSprinklerValve. - The valve is wall-mounted, not directly interactive, and has exactly one outlet/access floor face.
- Discharge creates
Wateronly while linked control isEnabledand the water branch is fed. - Discharge applies deterministic local water pressure debt.
- Add editor placement/linking, validation, serialization, and rendering support.
- A
- Rework surface water into
Water.- Rename code-facing concepts where practical; otherwise make names and UI text consistently mean water, not a generic hazard.
waterpipe failures should injectWater, not a damaging liquid.Wateralone must not causeUnsafeEntryLoss.
- Update leak injection.
- Leaks inject only when the underground leak cell has positive amount and positive pressure/voltage after propagation.
- Isolating a leak stops fresh injection without repairing the underlying fault.
- Repair restores structural integrity and stops future injection but does not clean existing surface values.
- Implement the approved surface interaction order.
- Resolve leak/sprinkler injection per
Step. - Resolve water mitigation before ignition and electrical spread.
- Implement
Dilute,Quench, value-basedEvaporate, wet-electricConduct, andIgnite. - Preserve deterministic same-cell and adjacent-cell delta accumulation.
- Closed powered doors and remedy blocks must gate only the interactions they explicitly block.
- Resolve leak/sprinkler injection per
- Implement value-based evaporation.
- Add balance values for ambient evaporation, heat-driven evaporation, and evaporation cooling.
- Hot cells should evaporate
Waterfaster than cold cells. - Evaporation happens during useful action pulses; there is no campaign wait command.
- Implement
Unsafeas derived movement safety.Unsafeis recalculated after authored setup and after eachPulse.Unsafeis caused by unsafeHeat, unsafeLeakedElectricity, or the wet-electric unsafe rule.LeakedFuelalone andWateralone are notUnsafe.UnsafeEntryLosshappens only whenMoveRobotenters anUnsafedestination without applicable protection.- A
Pulsemust not kill a stationary robot just because the current cell becomesUnsafe.
- Implement powered prop behavior.
DoorPropandAllSeeingEyeTerminalrequire positive local electricity amount and voltage for their interactions to take effect.- Interacting with an unpowered
PoweredPropis accepted as aLengthyAction, changes no prop state, reveals no terminal information, and still triggers onePulse. - Powered doors keep their last physical open/closed state when power is lost.
- Gate all-seeing-eye information.
- Underground topology, numeric underground values, and
Forecastoutput are visible only while the robot is at an active and poweredAllSeeingEyeTerminal. - Terminal access is local and does not persist after the robot leaves.
- Forecasts are systemic simulations over copied state, never authored level prose.
- Underground topology, numeric underground values, and
- Update
ReactorReadinesschecks as the invariant source of victory.- Every network present beneath
ReactorControlPropmust have positive amount and intensity. - Required per-carrier consumer counts must be
EnabledandProducing. - Missing readiness blocks
Readybut does not directly causeLost.
- Every network present beneath
P0 Simulation Tests
- Update existing tests so their names and assertions use
Pulse,Step,Water,Unsafe, andReactorReadinessterminology. - Add tests for fixed pulse length.
- Every accepted
LengthyActionadvances onePulse. - Each pulse resolves the configured number of
Steps. MoveRobotand inspection-like calls do not resolve a pulse.
- Every accepted
- Add tests for no normal wait/fast-forward dependency.
- Player-facing session/action APIs should not require
EndTurnto reach readiness after a lengthy action. - Debug/test-only pulse advancement, if retained, must be clearly named and excluded from campaign UI.
- Player-facing session/action APIs should not require
- Add tests for
IsolationValveProp.- Open valve allows branch propagation.
- Closed valve isolates damaged branches and can starve downstream consumers/reactor feed.
- Toggling a valve triggers exactly one
Pulse.
- Add tests for
SprinklerControlPropandSprinklerValve.- Valve discharge requires a linked enabled control and fed water branch.
- Direct valve interaction is invalid or unavailable.
- Discharge creates
Waterat the authored outlet and applies pressure debt. - Disabling the linked control or isolating the sprinkler branch stops fresh discharge.
- Add tests for updated leak injection.
- Fed fuel, water, and electricity leaks inject to the correct access face.
- Isolated leaks stop new surface injection.
- Repairs restore structural integrity without cleaning existing surface values.
- Add tests for surface interactions.
WaterdilutesLeakedFuel.WaterquenchesHeat.- Evaporation removes water and cools heat according to balance values.
- Wet cells conduct electricity faster than dry cells.
- Fuel plus electricity or heat can ignite and create heat while consuming fuel.
- Closed doors block designed surface propagation paths.
- Add tests for
Unsafe.- Moving into unsafe heat loses without active heat protection.
- Moving into unsafe electricity loses.
- Moving into wet-electric unsafe cells loses.
- Moving into fuel-only or sprinkler-water-only cells does not lose.
- A pulse that makes the robot's current cell unsafe does not immediately lose.
- Add tests for powered props.
- Powered door toggles and blocks/unblocks surface propagation.
- Unpowered door interaction changes no door state but still triggers a pulse.
- Powered terminal interaction enables local visibility and forecasts.
- Unpowered terminal interaction reveals nothing and still triggers a pulse.
- Leaving the terminal removes underground/forecast visibility.
- Add tests for campaign authoring invariants.
- Every campaign level loads and validates.
- Tutorial is solvable with exactly one
LengthyActionbeforeActivateReactor. - Every non-tutorial level has at least two valid first
LengthyActionchoices. - No campaign level requires a wait/fast-forward command.
- No level before 3-2 requires underground visibility to understand the intended first decisions.
- Campaign manifest order matches
docs/CAMPAIGN.md.
P1 Editor, Schema, And Level Data
- Bump the level schema version when adding new prop/link/outlet state.
- Update serialization round trips for new fields.
IsolationValvePropcarrier and open/closed state.SprinklerControlPropenabled/disabled state and linked valve id or position.SprinklerValvewall position, outlet/access face, linked control, and water connection.- Powered terminal active state if it becomes serialized runtime state.
- Update
LevelEditortools.- Add isolation valve placement.
- Add sprinkler control placement.
- Add wall-mounted sprinkler valve placement and outlet/access cycling.
- Keep electricity leak wall access cycling.
- Prevent invalid prop placement on walls except designed wall-mounted sprinkler valves.
- Update
LevelValidator.- Validate powered doors have valid geometry and local electricity.
- Validate terminal power requirements where needed.
- Validate wall-mounted sprinkler valve geometry, outlet/access face, water connection, and exactly one linked control.
- Validate isolation valves sit on exactly one matching underground carrier.
- Warn on initially unready reactors, initially starved required consumers, unused supplies, and sprinkler valves with no useful suppression or pressure tradeoff.
- Replace placeholder campaign files.
- Create tutorial plus Groups 1-6 from
docs/CAMPAIGN.md. - Update
default_campaign_manifest.jsonto the final order. - Remove or demote old placeholder levels so they are not presented as campaign content.
- Add stable ids and short flavor text for every authored level.
- Create tutorial plus Groups 1-6 from
- Add test/build helpers for level construction.
- Prefer shared builders for linear networks, forks, leaks, wall electricity faces, doors, controls, consumers, and reactors.
- Avoid duplicating low-level array setup across tests.
P1 Godot UX Integration
- Remove player-facing
End Turnfrom the normal action bar.- Replace it with contextual
LengthyActioncommands andActivateReactorwhen ready. - Keep any debug pulse control behind an explicit development-only path.
- Replace it with contextual
- Update
GameSessionAPI names and events to match pulse semantics.- Use
PulseAdvancedor equivalent instead ofTurnAdvanced. - Ensure accepted no-op powered-prop interactions still notify pulse playback.
- Ensure refused invalid actions do not mutate state or trigger pulse playback.
- Use
- Animate
Pulseplayback as a short cascade ofSteps.- Show leak growth, sprinkler discharge, evaporation, quenching, ignition, wet conduction, and readiness updates.
- Disable conflicting inputs during playback.
- End playback on the final post-pulse decision state.
- Gate underground layer controls and forecasts.
- Hide or disable layer toggles unless the robot is at an active and powered
AllSeeingEyeTerminal. - Show why terminal access is unavailable when unpowered or away from the terminal.
- Use
Pulse +Nwording in forecast UI.
- Hide or disable layer toggles unless the robot is at an active and powered
- Update grid rendering and inspector text.
- Render
Waterseparately from undergroundwater. - Render
Unsafecells with a distinct movement warning treatment. - Render isolation valve state, sprinkler control state, wall-mounted sprinkler outlet, powered door state, and powered terminal state.
- Inspector should display visible surface values, prop state, consumer per-carrier state, and underground values only when terminal access allows it.
- Render
- Update action affordances.
- Movement remains direct and quick.
- Prop interactions should explain unavailable power, invalid position, missing remedy, depleted supply, and reactor-not-ready causes.
- Disabled actions remain inspectable so players can understand why an action is unavailable.
P2 Polish And Release Tasks
- Add concise pulse-result feedback for major outcomes: isolated leak, restored pressure, downstream starvation, reactor ready, wet-electric risk, and terminal heat danger.
- Add campaign completion flow for the final Group 6 level.
- Add loading and malformed-level error states for campaign level loading.
- Verify Win2D editor export and Godot loader compatibility for the new schema.
- Revisit art labels/icons for
Water,Unsafe, powered props, and sprinkler controls after mechanics are implemented.
Verification Rules
- After each implementation iteration, run the focused simulation tests that cover the changed system.
- Run full
dotnet testbefore committing simulation or serializer changes. - For code changes on Windows, run the repo-required CRLF normalization and cleanup steps after implementation.
- For documentation-only iterations, no cleanup pass is required.
- Keep documentation aligned whenever code changes terminology or behavior.
- Commit each completed iteration with a brief summary.