Skip to content
ct

Calendar Time v2.0.4

Speed Stack and Clock Pacing

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

Status
Current
Version
v2.0.4
Updated
2026-08-09

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

The four pacing layers:

  • Engine.time_scale — global Godot tick multiplier (default 1.0).
  • TimeHost.time_scale.delta_multiplier — engine→game rate (default 1000.0).
  • GameClock.speed_multiplier — per-clock runtime rate (default 1.0).
  • GameClockSpeedSlider ticks — values written to clock.speed_multiplier.
  • EngineTimeScaleSlider (demo) — wraps Engine.time_scale; tick 0 pauses the tree.

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_frame

That'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):

At demo defaults (delta_multiplier = 1000):

  • 1× slider → 1000 game-seconds per real-second.
  • 3× slider → 3000 game-seconds per real-second.
  • 10× slider → 10,000 game-seconds per real-second.
  • 30× slider → 30,000 game-seconds per real-second.
  • 60× slider → 60,000 game-seconds per real-second.

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.

Pin to clock time: date progression, day/night lighting, schedules, ageing, and date-change events.

Pin to engine time: cursor blink, button hover, menu tweens, cosmetic VFX, and audio. Also walkers and idle dressing that keep moving when the calendar is paused.

See clock-driven-animation-pattern.md for the optional clock-driven recipe and the shipped demo SSOT split.

Production fast-forward: root tick, not camera cheats

Multiple clocks model different timelines. Example: two planets with different day lengths. Keep day length on each calendar or clock. Do not encode it as a camera speed.

To speed up the whole simulation, change the root engine tick. Use Engine.time_scale or your game-owned root step. Every automatic clock, physics body, and normal-delta consumer then adjusts equally. Relative planet day lengths stay intact.

Avoid production patterns that only boost camera pan speed. That desyncs inspection from sim. The demo camera divides out Engine.time_scale so you can still steer while the engine slider changes. Copy the root-tick approach for shipped games, not the camera unscale.

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:

Three speed knobs (only one is per-clock):

  • Engine.time_scale — root tick for the whole session. Prefer this when the full simulation should run faster or slower. Never set to 0.0.
  • host.time_scale.delta_multiplier — host calendar calibration. Idle vs real-time base rate without changing physics feel by itself.
  • clock.speed_multiplier — one timeline only. Festival clocks, local pauses, or per-planet runtime rate on top of shared host calibration.

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.

The "constant flipping" failure mode

Clock-driven animations firing too often usually mean delta_multiplier is very high.

Lower delta_multiplier, increase interval_real_seconds, or start from the example in demo/scripts/calendar_time_examples/clock_driven_flipper_example.gd.

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:

  • Real-time games (delta_multiplier = 1.0): label "1×", "2×", "5×" as wall-clock multipliers.
  • Idle games (delta_multiplier = 1000): "1×" already means 1000 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 with delta_multiplier = 1.0 and slider at 3×:

  • engine_delta = 1/60 sec.
  • Chain: 1.0 × 1.0 × 3.0 = 3.0.
  • Game-seconds per frame: 0.05.
  • Per real-second: 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 with delta_multiplier = 1000:

  • 60 × (1/60) × 1000 × 3.0 = 3,000 game-seconds per real-second.
  • One calendar day takes about 9.6 real-seconds at 3×.

See also