This guide is the single source of truth for understanding how time advances in a Calendar Time scene. It exists because "how fast is the clock running?" has four answers, depending on which question you're asking. Getting them confused is the most common source of "the clock is going way too fast / way too slow" bugs.
The four things, in one place
| Layer | Where it lives | Default value | What it controls |
|---|---|---|---|
Engine.time_scale |
Godot global | 1.0 | Multiplies every Godot tick: physics, animation, signals, audio, etc. A UI dialog scales by it. |
TimeHost.time_scale.delta_multiplier |
TimeHost Node in your scene |
1000.0 (in default_time_scale.tres) |
Engine→game rate bridge: how many game-seconds one real-second becomes. |
GameClock.speed_multiplier |
GameClock resource (per-clock) |
1.0 (slider default 3.0) | Per-clock runtime rate. One clock on the host can be 30x while another is 1x. |
GameClockSpeedSlider.slider_time_multipliers[i] |
UI control on the demo | ticks: [0.25, 0.5, 0.75, 1.0, 1.25, 1.5, 2, 3, 10, 30, 60] |
The value the slider writes to clock.speed_multiplier on each tick. Tick 0 is now handled separately. |
EngineTimeScaleSlider (demo code) |
UI control in demo/ui/ |
ticks: [0.25, 0.5, 0.75, 1.0, 1.25, 1.5, 2, 3] |
Tick 0 = get_tree().paused = true (engine paused, rendering intact). Ticks 1+ = Engine.time_scale directly. Copy from demo to use. |
The composition formula, end-to-end, is:
game_seconds_advanced_per_frame =
Engine.time_scale
× TimeHost.time_scale.delta_multiplier
× GameClock.speed_multiplier
× engine_delta_seconds_per_frameThat's the same formula documented in TimeScale and DriveModes; this guide is about the slider part specifically.
"1x slider" — what does that actually mean?
The slider's label shows slider_time_multipliers[i] + "x". So:
- "1x" means
clock.speed_multiplier = 1.0 - "3x" means
clock.speed_multiplier = 3.0 - "60x" means
clock.speed_multiplier = 60.0
The "x" is relative to the host's time_scale.delta_multiplier, NOT
relative to wall-clock real-time. There is no slider position that
equals "1x real-time" unless delta_multiplier = 1.0.
Concretely, with the demo defaults (delta_multiplier = 1000,
Engine.time_scale = 1.0, engine_delta = 1/60):
| Slider tick | clock.speed_multiplier | game-seconds / real-second |
|---|---|---|
| 1x | 1.0 | 1000 |
| 3x | 3.0 | 3000 |
| 10x | 10.0 | 10,000 |
| 30x | 30.0 | 30,000 |
| 60x | 60.0 | 60,000 |
So "1x" in the demo means "1 game-second per millisecond of real time". The slider is for adjusting how far past the base rate you want to be, not for choosing between "real-time" and "fast-forward".
If you want a slider position that is real-time, set the host's
time_scale.delta_multiplier = 1.0. Then "1x slider" = 1 game-second
per real-second. The slider's numeric values still read the same, but
the "x" is now read as "real-time multiplier".
Why is delta_multiplier = 1000 the demo default?
The default is 1000 because Calendar Time is built for idle and simulation games where the world advances faster than the player watches. A typical calendar idle game runs 1000–3000 game-seconds per real-second so a "day" feels like a minute. The slider then amplifies that base rate for "fast forward to next year" type interactions.
If your game is real-time-pacing (1 real-second = 1 game-second),
set the host's time_scale.delta_multiplier = 1.0 and the slider's
"1x" becomes the natural real-time tick.
When to pin to clock time vs. raw engine time
This is the design question that comes up most often. The rule of thumb: anything in the simulated world uses clock time; anything in the UI/host shell uses raw engine time.
| Subsystem | Use | Why |
|---|---|---|
| Date / day / time-of-day progression | Clock time | Calendar Time is the source of truth for the simulated world. |
| Day/night lighting transitions | Clock time | "sunset happens at 7 PM" is a world fact, not a UI animation. |
| NPC idle animations (blink, breathe, foot-tap) | Clock time | Pause the game → NPC should freeze. World fact. |
| Game-owned fixed-step simulation systems | Fixed-step tick drives Calendar Time manually | Your simulation loop owns system order; Calendar Time records the calendar state for the step. |
| NPC "look around" (ninja flip every 10 real-sec) | Clock time (real-time pacing) | Dressing animation that pauses with the world but paces on real-time — interval excludes smult so flip rate is constant regardless of clock speed. |
| Cursor blink, button hover, menu open/close | Raw engine time | UI shell — should not freeze when the game pauses. |
| Tween / animation player for cosmetic effects | Raw engine time | Cosmetic effects are part of the UI shell, not the world. |
| Audio (BGM, ambient sounds) | Raw engine time | Music doesn't pause when you freeze the world. |
| Save/load determinism replay | Raw microseconds (deterministic) | The whole point of replay is to be byte-exact. Direct microsecond injection. |
The "ninja flip every 10 real-seconds" example is a special case worth
calling out: it's a dressing animation, not a game actor, but it
IS driven by the clock (listens to game_seconds_advanced). The
flipper uses clock time so it freezes when the player pauses the world,
but its interval excludes smult so it paces on real-time — exactly
one flip every N real-seconds regardless of clock speed. This is the
"real-time pacing" sub-pattern of clock-driven animation. See the
clock-driven animation pattern guide
for the two sub-patterns (flipper vs. emote) and when to use each.
If you want the ninja to keep flipping while the world is paused
(different design choice), use raw engine time instead. The pattern is
the same; the only thing that changes is which time value the flipper
reads.
GameClockSpeedSlider vs. TimeHost.time_scale vs. Engine.time_scale — what each one does
A common source of confusion: three different "speed" knobs. They control different things, and only one of them is per-clock:
| Knob | What it does to the COMPOSITION |
|---|---|
Engine.time_scale = 0.5 |
Halves physics, animation, audio, and clock speed. EVERYTHING. |
Engine.time_scale = 0.0 |
NEVER DO THIS. Freezes all _process/_physics_process callbacks, breaking tilemap rendering, sprite drawing, and Godot internals. Use host.time_scale.delta_multiplier = 0.0 for clock-time pause, or get_tree().paused = true for engine-time pause (the EngineTimeScale slider's "Paused" tick does this). |
host.time_scale.delta_multiplier = 0.0 |
Stops the host from advancing ANY clock, but Godot still ticks. The intended "pause" mechanism. |
host.time_scale.delta_multiplier = 0.5 |
Halves all clocks under the host, but Godot + UI still tick. Half-speed world. |
clock.speed_multiplier = 0.0 (set by slider) |
Stops JUST this clock. Other clocks on the same host still tick. |
clock.speed_multiplier = 0.5 (set by slider) |
Halves JUST this clock. |
The demo's GameClockSpeedSlider is explicitly bound to a single
clock's speed_multiplier and does NOT touch Engine.time_scale or
host.time_scale. If you want the slider to also control
those, you'd extend the slider — but most projects don't.
The EngineTimeScaleSlider is demo code (not part of the addon)
because it wraps Godot-global Engine.time_scale, not Calendar Time
APIs. To use it in your project, copy demo/ui/engine_time_scale_slider.gd
and demo/ui/engine_time_scale_control.tscn into your project. The
slider's "Paused" tick uses get_tree().paused = true instead of
Engine.time_scale = 0 (which freezes rendering).
The "constant flipping" failure mode
If you set up a clock-driven animation (like the ninja flip or the
mood bubble bob in the demo) and observe it firing way more often
than expected, the most common cause is: delta_multiplier is very
high and interval_real_seconds × delta_multiplier produces a
much smaller game-second interval than you expected.
Math check at demo defaults (flipper, excludes smult):
flips_per_real_second = delta_multiplier / interval_real_seconds
= 1000 / 10
= 100 flips per real-secondThat's still fast — the flipper fires 100 times per real-second, which
to the eye looks like constant flipping. But it's now independent of
speed_multiplier (the flipper paces on real-time, not game-time).
For the mood bubble bob (which divides by dmult × smult):
bobs_per_real_second = (dmult × smult) / bob_period_real_seconds
= (1000 × 3) / 1
= 3000 bobs per real-secondThe fix is either (a) lower delta_multiplier so the math is
realistic, (b) increase interval_real_seconds to compensate, or
(c) explicitly call out the demo's calibration in docs and let users
who want slower flips opt in. The shipped flipper uses (b) and
auto-scales via the math in flipper.gd::_recompute_speed().
The "what does 1x mean" user-facing message
If your game exposes a "speed" setting to the player (e.g. an in-game
menu), the right labeling depends on what your host's
delta_multiplier is:
- For real-time games (
delta_multiplier = 1.0): "1×", "2×", "5×" map cleanly to wall-clock. - For idle games (
delta_multiplier = 1000): "1×", "10×", "100×" is the calibrated range; the game already advances 1000 game-seconds per real-second at "1×", so "100×" is 100,000 game-seconds per real-second.
The shipped GameClockSpeedSlider is calibrated for the demo's
idle-game defaults. If you ship a different host calibration, override
the slider_time_multipliers array in your own scene.
Worked example
Setting: real-time-pacing game, delta_multiplier = 1.0,
Engine.time_scale = 1.0, slider at "3×".
Per frame at 60 fps:
- engine_delta = 1/60 sec
- multiplier chain: 1.0 × 1.0 × 3.0 × 1.0 = 3.0
- game-seconds per frame: (1/60) × 3.0 = 0.05 game-sec
Per real-second:
- 60 × 0.05 = 3.0 game-seconds
So at 3× slider, the world advances 3 game-seconds per real-second. A calendar day (24 game-hours × 60 game-minutes × 60 game-seconds) takes 28,800 game-seconds ÷ 3 = 9,600 real-seconds = 2.67 real-hours per calendar day. That's a slow, watchable pace.
Same setup but delta_multiplier = 1000:
- 60 × (1/60) × 1000 × 3.0 = 3,000 game-seconds per real-second
- 28,800 ÷ 3,000 = 9.6 real-seconds per calendar day
That's an idle-game pace. "1×" already runs 1000× faster than real-time.
See also
clock-driven-animation-pattern.md— the worked code example of converting a Timer-based animation (ninja flip) and a speed-based animation (mood bubble bob) to clock-driven, with real-time-friendly inspector knobs.- TimeScale and DriveModes — the formal ownership
table for the four
TimeScalesymbols. - What Should Drive What? — beginner guide for choosing Calendar Time, Godot, or a game-owned fixed-step tick.