From 7777800a5d425c3a100c068a2692896c327b6e61 Mon Sep 17 00:00:00 2001 From: Frank Tovar Date: Wed, 13 May 2026 23:25:18 +0200 Subject: [PATCH] Document pulse-based simulation timing --- docs/UX.md | 21 ++++++++++++++------ docs/design.md | 53 ++++++++++++++++++++++++++++++-------------------- 2 files changed, 47 insertions(+), 27 deletions(-) diff --git a/docs/UX.md b/docs/UX.md index 651d58c..7357970 100644 --- a/docs/UX.md +++ b/docs/UX.md @@ -166,7 +166,7 @@ Primary controls: - visible hazards with safe/caution/critical bands - forecast warnings - `ActionBar` - - contextual action buttons: move, interact, repair, remedy, heat shield, wait, activate reactor + - contextual action buttons: move, interact, repair, remedy, heat shield, activate reactor - disabled buttons must show why the action is unavailable - `InventoryPanel` - fuel neutralizer count @@ -176,14 +176,23 @@ Primary controls: Behavior: -- Selection and inspection are quick actions and must not advance the simulation. -- Movement is a quick action and must update robot position without advancing the turn. -- Interact, repair, remedy, heat shield, wait, and activate reactor are lengthy actions and must resolve one simulation step when accepted. +- Selection and inspection are quick actions and must not trigger a pulse. +- Movement is a quick action and must update robot position without triggering a pulse. +- Interact, repair, remedy, and heat shield are environment-changing actions and must trigger one animated pulse when accepted. +- Activate reactor must be visually prominent when ready and should resolve immediately without requiring a wait or extra pulse. - Invalid actions should produce a short refusal message and not mutate level state. - When the level state becomes `Lost`, show `LoseOverlay`. - When the level state becomes `Won`, show `WinOverlay`. - When the reactor is ready, make `Activate Reactor` visually prominent but keep other valid actions available. +Pulse playback behavior: + +- During a pulse, animate the configured steps as one short cascade of hazard motion, leak growth, quenching, ignition, shorts, and readiness updates. +- Disable conflicting action commands while pulse playback is running so the player cannot queue hidden actions into an unresolved environment state. +- Present the final post-pulse state as the next decision point. +- Do not make pulse length vary by action type, forecast outcome, or danger level. +- Do not expose a normal campaign fast-forward loop; the player goal is to solve the cascade and activate the reactor as soon as a pulse leaves its needs fulfilled. + ### LoseOverlay.tscn Purpose: immediate failure response while preserving context. @@ -293,7 +302,7 @@ Controls: Behavior: -- Keep tutorial text focused on action economy, hazards, forecasts, remedies, and reactor activation. +- Keep tutorial text focused on action economy, pulses, hazards, forecasts, remedies, and reactor activation. - Tutorial level can reuse `LevelScreen` with a tutorial mode flag and guided prompts. ## Reusable Controls @@ -302,7 +311,7 @@ Behavior: - `StateBadge`: color-coded label for `Stable`, `Caution`, `Critical`, `Ready`, `Lost`, and `Won`. - `LevelHeader`: level metadata, global state, and campaign progress. - `CellInspector`: selected cell details, visible hazards, prop state, underground details when available. -- `ForecastList`: ordered warnings from soonest to latest turn. +- `ForecastList`: ordered warnings from soonest to latest pulse. - `InventoryStrip`: remedy and heat shield counts. - `OutcomeOverlay`: shared base layout for win and loss overlays. - `ConfirmDialog`: save overwrite, abandon run, and return-to-menu confirmations. diff --git a/docs/design.md b/docs/design.md index d2a5ebb..ed4acec 100644 --- a/docs/design.md +++ b/docs/design.md @@ -18,24 +18,31 @@ The game should feel logical, tactical, readable, and systemic. It should avoid ## Action Economy -There is no per-turn action budget. Player choices are either quick or lengthy. +There is no action budget. Player choices are either quick or lengthy. -Quick actions do not mutate the level state and do not advance the simulation: +Quick actions do not mutate the environment and do not trigger a pulse: - `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: +Lengthy actions commit an intervention and immediately trigger one pulse: -- `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, +- `InteractProp`: toggle flow props, toggle consumers, cycle junction ratios, open or close doors, pick up remedy supplies, or activate all-seeing-eye access 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. +- `ActivateReactor`: activate a ready reactor at the current reactor control prop. Invalid actions report refusal and do not mutate gameplay state. +## Pulses And Steps + +A step is the low-level deterministic simulation iteration. One step injects leaks, resolves same-cell reactions, resolves adjacent surface flow, accumulates deltas, and clamps visible surface values. + +A pulse is the player-facing environment response after an accepted lengthy action. One pulse contains a fixed balance-defined number of steps and is animated as a short cascade. The pulse length is the same for every lengthy action and must not vary by action type, forecast outcome, or current danger level. + +Movement, inspection, and layer viewing do not trigger pulses. The campaign loop should not rely on a player-facing wait or fast-forward command; the puzzle is to solve cascading failures and activate the reactor as soon as a pulse leaves its needs fulfilled. Editor, debug, and automated-test tools may still advance isolated steps or pulses when needed. + ## Goal And Failure Each reactor starts offline. A reactor becomes ready when: @@ -159,7 +166,7 @@ An enabled consumer derives one service state per underground network present be - `Supplied`: enough carrier and pressure or voltage reaches the underground cell. - `Starved`: supply predicates fail. -- `Producing`: the consumer was supplied this simulation step and emits service. +- `Producing`: the consumer was supplied during the current pulse and emits service. 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. @@ -340,7 +347,7 @@ Structural integrity is resolved after network propagation and before leak injec For every present underground cell: -1. If the cell is already max integrity, high intensity does not weaken it during that step. +1. If the cell is already max integrity, high intensity does not weaken it during that pulse. 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. @@ -366,28 +373,32 @@ Data-driven rule predicates and effects are not part of level data. Effects happ - 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. +- forecast refresh simulates copied state over the configured pulse horizon. Warnings are generated by fixed forecast and status systems when conditions can be proven. -## Simulation Order +## Pulse And Step Order -One lengthy interaction resolves in this order: +One accepted lengthy interaction resolves one pulse in this order: 1. Apply the accepted player mutation. 2. Validate runtime state. 3. Propagate underground networks. 4. Resolve consumers and service production. 5. Resolve structural integrity and automatic leak creation. -6. Inject leaks. -7. Evaluate same-cell surface interactions. -8. Evaluate adjacent floor interactions across unblocked door cells. -9. Accumulate and apply deltas in deterministic priority order. -10. Clamp values. -11. Resolve robot safety. -12. Derive reactor readiness and level state. -13. Advance remedy blocks and heat immunity. -14. Refresh forecasts. +6. Resolve the configured number of deterministic steps. +7. Resolve robot safety from the final post-pulse hazard state. +8. Derive reactor readiness and level state. +9. Advance remedy blocks and heat immunity once for the pulse. +10. Refresh forecasts. + +Each step inside the pulse resolves in this order: + +1. Inject leaks fractionally for this step. +2. Evaluate same-cell surface interactions. +3. Evaluate adjacent floor interactions across unblocked door cells. +4. Accumulate and apply deltas in deterministic priority order. +5. Clamp values. ## Forecasts @@ -401,7 +412,7 @@ Forecast output includes: - growing hazard warnings when values cross caution or critical bands, - structural integrity leak warnings when weakened cells are expected to leak. -The forecast horizon is balance data. +Forecast timing is reported in pulses, for example `Pulse +2`. The forecast horizon is balance data. ## Validation