diff --git a/TASKS.md b/TASKS.md index c8bbbce..927f295 100644 --- a/TASKS.md +++ b/TASKS.md @@ -3,6 +3,7 @@ ## Current State - Approved design iteration targets the simulation model, rule removal, action economy, reactor requirements, and editor layer workflow. - Work is proceeding on branch `design-iteration-structural-editor` in methodical commits: docs/tasks, simulation rework, editor rework, cleanup. +- Design documentation must preserve every existing system-level rule unless a change explicitly supersedes it. Superseded sections must document the replacement behavior with equal detail. ## Completed Work - Created the approved implementation plan for: @@ -16,7 +17,7 @@ - layer-aware editor visualization and tools. ## Current Work -- Update design documentation to match the approved model. +- Repair design documentation gaps before simulation implementation. - Rework simulation state, validation, serialization, forecasts, and tests. - Rework Win2D editor layer selection, rendering, tool filtering, drag behavior, and removed panels. diff --git a/docs/design.md b/docs/design.md index 8acbbb1..2897743 100644 --- a/docs/design.md +++ b/docs/design.md @@ -22,18 +22,17 @@ There is no per-turn action budget. Player choices are either quick or lengthy. Quick actions do not mutate the level state and do not advance the simulation: -- robot movement, -- selection and inspection, -- all-seeing-eye viewing. +- `MoveRobot`: move the robot to an adjacent floor cell, reduce heat immunity movement steps if applicable, and reject movement into walls or out of bounds, +- selection and inspection: change only UI selection state, +- all-seeing-eye viewing: when the robot is at an all-seeing-eye terminal, allow the player to view every surface and underground layer. Lengthy actions mutate level state and immediately advance one simulation step: -- enabling or disabling a prop, -- opening or closing a door, -- repairing a leak, -- applying a remedy, -- using a heat shield, -- waiting or ending the current interaction beat. +- `InteractProp`: toggle flow props, toggle consumers, cycle junction ratios, open or close doors, pick up remedy supplies, or activate all-seeing-eye viewing from a terminal, +- `InteractLeak`: repair a reachable leak or apply a matching elemental remedy, +- `ApplyHeatShield`: spend one heat shield and set heat immunity movement steps, +- `ActivateReactor`: activate a ready reactor at the current reactor control prop, +- `Wait`: advance one simulation step without applying another player mutation. Invalid actions report refusal and do not mutate gameplay state. @@ -101,6 +100,14 @@ Underground cells use one structural state: Underground cells store carrier amount, pressure or voltage intensity, and structural integrity on a 0-10 scale. Max structural integrity supports the highest pressure. Non-max integrity under high pressure worsens proportionally to excess pressure. Low integrity with positive pressure creates a leak. Repairing a leak restores integrity to max. +Structural integrity is persistent authored and runtime state: + +- absent cells have no meaningful structural integrity, +- newly authored present cells start at max structural integrity, +- network propagation updates amount and intensity but does not reset integrity, +- structural integrity cannot exceed max and cannot fall below zero, +- existing leaks keep their current integrity until repaired. + Same-carrier underground cells connect by inferred cardinal adjacency. Surface floor cells store: @@ -154,12 +161,22 @@ An enabled consumer derives one service state per underground network present be - `Starved`: supply predicates fail. - `Producing`: the consumer was supplied this simulation step and emits service. -A disabled consumer consumes nothing, produces nothing, and cannot satisfy reactor readiness. A consumer on multiple underground layers consumes all present layers and can satisfy one requirement for each carrier that is producing. +A disabled consumer consumes nothing, produces nothing, and cannot satisfy reactor readiness. A consumer on no underground layer is valid but produces no service and contributes no readiness requirement. A consumer on one underground layer consumes that service. A consumer on multiple underground layers consumes all present layers and can satisfy one requirement for each carrier that is producing. + +The aggregate consumer prop still exposes a single switch state. Per-carrier service state is derived from the underground layers beneath the prop and is used by reactor readiness, forecasts, and inspection. If any consumed carrier is starved, the consumer contributes a warning for that carrier without blocking other carriers on the same prop from producing. ### Reactor Control Props A reactor control prop is the activation site for one reactor. Reactor readiness is derived from level-level consumer count requirements and the networks beneath the reactor control cell. +The reactor control prop itself is not bound to any individual consumer. It is considered a local consumer for any underground network present beneath its cell: + +- if no underground layer is present beneath the reactor, the local reactor feed requirement is satisfied, +- if one or more underground layers are present, every present layer must have positive amount and positive intensity after network propagation, +- a present but starved reactor-under-network blocks readiness but does not directly lose the level. + +Level properties define `RequiredFuelConsumers`, `RequiredCoolantConsumers`, and `RequiredElectricityConsumers`. For each carrier, readiness requires at least that many enabled consumer props whose per-carrier service state is `Producing`. + ### Junction Props A junction prop must be on a floor cell whose coordinate has exactly one underground carrier. That carrier is the regulated network. @@ -175,6 +192,13 @@ A door is a prop on one floor cell. Its orientation is derived from opposing wal A door must have exactly one valid opposing wall pair. Closed doors block fuel, coolant, electricity, and heat propagation across the corridor cell. They do not block robot movement, underground network flow, source feeding, consumer supply, or hazards already present on either side. +Door blocking is evaluated by the door cell and its inferred corridor axis: + +- east-west corridor doors block surface interaction between the west neighbor, the door cell, and the east neighbor while closed, +- north-south corridor doors block surface interaction between the north neighbor, the door cell, and the south neighbor while closed, +- open doors do not block surface interaction, +- door props on invalid terrain or with ambiguous opposing walls are validation errors. + ### Terminals And Supplies An all-seeing-eye terminal allows full underground inspection when visited. @@ -248,16 +272,101 @@ During leak injection: - electricity leaks add leaked electricity to the stored floor emission face, - active matching remedy blocks prevent matching element entry. -Injection magnitude is balance data and may depend on local carrier amount, pressure, or voltage. +Injection magnitude is balance data and may depend on local carrier amount, pressure, or voltage. If the target floor cell has an active matching remedy block, that matching element is not injected into the cell for that step. Remedy blocks do not block other elements or heat. After injection, the engine evaluates local interactions between leaked fuel, leaked coolant, leaked electricity, and heat on the same floor cell and across unblocked adjacent floor cells. +Surface interaction resolution is deterministic: + +- same-cell interactions evaluate every unordered quantity pair on each floor cell, +- adjacent interactions evaluate every unordered pair of adjacent floor cells once, +- same-carrier leaked fuel, coolant, electricity, and heat equalize across adjacent floor cells using `Flow(amount)`, +- wall cells never store surface hazards and do not participate, +- closed doors and remedy blocks gate the interactions they explicitly block, +- deltas accumulate during an interaction pass and are applied together before clamping. + +## Hazard Bands And Pair Table + +Balance thresholds project numeric values into safe, caution, and critical bands: + +- `FuelSafe`, `FuelCaution`, `FuelCritical`, +- `CoolantSafe`, `CoolantCaution`, `CoolantCritical`, +- `ElectricitySafe`, `ElectricityCaution`, `ElectricityCritical`, +- `HeatSafe`, `HeatCaution`, `HeatCritical`. + +The pair table maps projected bands to parameterized verbs: + +- `Hold`: no direct change, +- `Flow(amount)`: equalize a surface quantity by a balance-defined transfer amount, +- `Warm(amount)`: increase heat by a balance-defined amount, +- `Quench(amount)`: reduce heat by a balance-defined amount, +- `Short(heat, discharge)`: add heat and discharge electricity by balance-defined amounts, +- `Ignite(heat, fuel)`: add heat and consume fuel by balance-defined amounts. + +| Row\Col | FuelSafe | FuelCaution | FuelCritical | CoolantSafe | CoolantCaution | CoolantCritical | ElectricitySafe | ElectricityCaution | ElectricityCritical | HeatSafe | HeatCaution | HeatCritical | +| ------- | -------- | ----------- | ------------ | ----------- | -------------- | --------------- | --------------- | ------------------ | ------------------- | -------- | ----------- | ------------ | +| FuelSafe | Hold | Flow | Flow | Hold | Hold | Hold | Hold | Warm | Ignite | Hold | Warm | Ignite | +| FuelCaution | | Hold | Flow | Hold | Hold | Hold | Warm | Ignite | Ignite | Warm | Ignite | Ignite | +| FuelCritical | | | Hold | Hold | Hold | Hold | Ignite | Ignite | Ignite | Ignite | Ignite | Ignite | +| CoolantSafe | | | | Hold | Flow | Flow | Hold | Short | Short | Hold | Quench | Quench | +| CoolantCaution | | | | | Hold | Flow | Short | Short | Short | Hold | Quench | Quench | +| CoolantCritical | | | | | | Hold | Short | Short | Short | Hold | Quench | Quench | +| ElectricitySafe | | | | | | | Hold | Flow | Flow | Hold | Hold | Hold | +| ElectricityCaution | | | | | | | | Hold | Flow | Hold | Hold | Hold | +| ElectricityCritical | | | | | | | | | Hold | Hold | Hold | Hold | +| HeatSafe | | | | | | | | | | Hold | Flow | Flow | +| HeatCaution | | | | | | | | | | | Hold | Flow | +| HeatCritical | | | | | | | | | | | | Hold | + +Blank lower-triangle entries mirror the corresponding upper-triangle entry. Fuel and coolant do not directly react with each other; leaked coolant plus leaked fuel is `Hold` unless another pair on that cell or an adjacent cell involves heat, electricity, or same-carrier flow. + +Design rules: + +- fuel becomes dangerous through electricity or heat, +- coolant becomes dangerous through electricity, +- coolant opposes heat, +- heat equalizes between neighboring floor cells, +- same-carrier leaked surface amounts equalize between neighboring floor cells, +- doors and remedy blocks gate local interactions. + +## Structural Integrity + +Structural integrity is resolved after network propagation and before leak injection. It is deterministic and uses balancing values: + +- `MaxStructuralIntegrity`: the maximum integrity value, `10` for the approved scale, +- `StructuralIntegrityHighIntensityThreshold`: the pressure or voltage threshold above which a weakened cell degrades, +- `StructuralIntegrityDamageScale`: difficulty-specific multiplier, initially `0.25` in Normal difficulty, +- `StructuralIntegrityLeakThreshold`: integrity at or below this value can become a leak when positive intensity exists. + +For every present underground cell: + +1. If the cell is already max integrity, high intensity does not weaken it during that step. +2. If integrity is below max and intensity is greater than the high threshold, integrity is reduced by `(intensity - threshold) * StructuralIntegrityDamageScale`. +3. Integrity is clamped to the 0-10 range. +4. If the final integrity is at or below the leak threshold and intensity is positive, the cell becomes `Leaking` and a `LeakState` is created if one does not already exist. + +Automatic leak access follows the same rules as authored leaks: + +- fuel and coolant leaks use the underground cell as their floor access and can only auto-start under floor cells, +- electricity leaks require one adjacent floor access face; if multiple valid faces exist, the deterministic order is north, east, south, west, +- if no valid floor access exists, the weakened cell remains damaged but no reachable leak state is created. + +Repairing a leak sets the underground cell to `Intact`, sets structural integrity to max, marks the leak repaired, and leaves existing surface hazards unchanged. + ## Fixed Rule Systems Data-driven rule predicates and effects are not part of level data. Effects happen through fixed systems: -- player-issued lengthy interactions toggle props, use inventory, open or close doors, repair leaks, and activate reactors, -- automatic simulation systems propagate networks, resolve consumers, weaken structural integrity, create leaks, spread and react hazards, resolve robot safety, derive reactor state, and refresh forecasts. +- player-issued lengthy interactions toggle props, cycle junctions, use inventory, open or close doors, repair leaks, and activate reactors, +- network propagation clears transient amount and intensity, then recomputes flow from enabled sources, +- consumer resolution derives per-carrier service states from present underground layers, +- structural integrity resolution weakens damaged high-pressure cells and creates leaks from low-integrity positive-pressure cells, +- leak injection adds carrier hazards to valid floor access cells, +- surface interaction resolution spreads and reacts hazards according to the hazard pair table, +- robot safety resolves terminal loss from unsafe final hazard states after surface interactions, +- reactor state derives readiness or terminal heat loss, +- duration advancement reduces remedy blocks and heat immunity counters, +- forecast refresh simulates copied state over the configured horizon. Warnings are generated by fixed forecast and status systems when conditions can be proven.