Game speed controls: pause, 1x and fast-forward #103
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
The colony runs at two real minutes per in-game day and roughly two hours per six-month contract (see
docs/colony-game-time-and-calendar.md). That pacing is deliberate, but it means long stretches where nothing needs a decision, and short stretches during a threat window where the player wants to watch closely. Both directions need a control.This is a player-facing feature, not only a debug convenience — but the debug need is what surfaced it, and is the more urgent half.
The clock already supports this
GameClockneeds no changes.speed: floatandpaused: boolare plain properties,delta_for()exists for anything simulating, and #65 already pinned the awkward parts with tests:speed = 0.0behaves as a pauseSo this issue is input actions, a HUD widget, and two decisions — not clock work.
Use the right knob
speed, neverticks_per_second. They look interchangeable and are not:GameClock.speedGameClock.ticks_per_secondticks_per_secondis an engineering constant that content will be calibrated against, is rejected once the clock has started, and is pinned bytest_ticks_per_second_defaults_to_ten. During #87 it was edited in source to watch the contract bar move, which broke that test and would have shipped a 200x game had it not been caught. A runtime speed control removes the temptation.Two things that need deciding
1.
pausedcurrently has exactly one writer, and that is load-bearingGameClock._on_main_menu_changed()setspaused = enabledunconditionally. Add a player-facing pause and there are two writers, so closing the main menu un-pauses a game the player had deliberately paused. The bug is subtle and will be blamed on the menu.Options: a pause-reason set (
_pause_reasons: Dictionary, paused if non-empty), or a separateplayer_pausedflag OR-ed with the menu one. The reason-set generalises better — a threat alert or a modal dialog will each want to pause without fighting the others — but it is more machinery than one extra bool. Worth picking deliberately rather than by accident.2.
reset()does not touchspeedGameClock.reset()zeroes_nowand_accumulatoronly, so a second contract inherits the speed the last one ended on. Landing a new colony at 3x is probably wrong; landing it paused is definitely wrong. Decide whetherreset()should restore 1x, and say so in a test either way — #87 added tests for exactly this class of "the autoload outlives the run" bug.Proposed speeds
Pause, 1x, 2x, 3x. Three forward speeds is what the pacing table supports — a day is 2 min / 1 min / 40 s — and more than that outruns the player's ability to react to a threat. Deliberately not offering an arbitrary slider.
Bind to
speed_pause,speed_normal,speed_fast,speed_fasteras new input actions (the project already declares its actions inproject.godot; see #78). Spacebar for pause and1/2/3are the genre convention.AC
project.godotreset()does tospeedon a new runticks_per_secondagainNot in scope: slow motion below 1x, and per-system time scaling (animations continuing while the sim is paused).
Blocks nothing, but anything needing visual verification over game-months — the threat timeline especially — is painful without it.
Closed in PR #104