Skip to content
ct

Calendar Time v2.0.4

TimeScale & DriveMode — Ownership and Contract

This guide covers the two concepts that look similar but mean very different things in Calendar Time.

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

This guide covers the two concepts that look similar but mean very different things in Calendar Time.

TL;DR

Rate and schema symbols:

  • TimeHost.time_scale — host-wide engine→game rate (delta_multiplier). Default 1000×.
  • GameClock.speed_multiplier — per-clock runtime speed on the same host.
  • GameCalendar.time_scale — calendar unit schema (seconds per minute/hour/day).
  • TimeHost.drive_modePROCESS (default), PHYSICS_PROCESS, or MANUAL.

The names overlap deliberately because they answer different questions about the same value object (TimeScale). The deciding question is: are you changing host rate, one clock's speed, or calendar structure?

The type split

TimeScale has been split into CalendarUnits and ClockPacing. See MIGRATION.md §2.0.2 for the migration steps and TimeScale.to_clock_pacing() guidance.

TimeHost.time_scale (host-wide rate)

TimeHost.time_scale : TimeScale is the engine→game rate bridge. Its only field that the host reads for ticking is delta_multiplier. The host multiplies engine delta by this number, then by MICROSECONDS_PER_SECOND, before advancing the clocks in _process(delta) or _physics_process(delta).

# Default 1000× — 1 real second ≈ 16 game minutes of in-clock time.
host.time_scale= TimeScale.new()
host.time_scale.delta_multiplier= 1000.0

# Slow-mo:
host.time_scale.delta_multiplier= 0.5

# Pause the game clock without pausing Godot rendering/input:
host.time_scale.delta_multiplier= 0.0

A single TimeHost.time_scale applies to all clocks in that host's group. Use it for host-wide calibration: "how fast does this host turn real seconds into game seconds?"

GameClock.speed_multiplier (per-clock rate)

GameClock.speed_multiplier is applied after the host converts engine delta into host game-time microseconds. It answers: "how fast does this specific timeline run relative to the host?"

# Speed up only the world clock. Other clocks on the same host can remain 1×.
world_clock.speed_multiplier= 30.0

# Pause only a festival timeline.
festival_clock.speed_multiplier= 0.0

The automatic engine-driven path is:

engine_delta_seconds
→ TimeHost.time_scale.delta_multiplier
→ GameClock.speed_multiplier
→ GameClock.advance_microseconds()

Formula:

final_clock_delta = engine_delta * host_multiplier * clock_multiplier

For the full speed composition walkthrough and slider calibration, see Speed Stack and Clock Pacing.

GameCalendar.time_scale (unit schema)

GameCalendar.time_scale : TimeScale is the calendar's unit definition. Its seconds_per_minute, seconds_per_hour, and seconds_per_day fields decide how a count of game-seconds decomposes into minutes / hours / days. The default is Earth-like; a fantasy calendar with 20-hour days and 90-minute hours overrides these fields.

The calendar's time_scale is also used by DayNightCycleService to translate TimeOfDay enter-times, stored as HoursTime, into seconds for transition_progress math.

This has nothing to do with the engine→game rate. Setting calendar.time_scale.delta_multiplier = 1000.0 does not speed up the clock. The host only reads TimeHost.time_scale.delta_multiplier for ticking.

DriveMode

enum DriveMode {
    PROCESS,# default — auto-advance from _process(delta)
    PHYSICS_PROCESS,# auto-advance from _physics_process(delta)
    MANUAL,# no auto-advance; call host.drive_microseconds() yourself
}

drive_mode replaces the old auto_increment_time boolean. The boolean remains as a backward-compatible alias:

auto_increment_time alias:

  • host.auto_increment_time = truehost.drive_mode = TimeHost.DriveMode.PROCESS.
  • host.auto_increment_time = falsehost.drive_mode = TimeHost.DriveMode.MANUAL.

Reading host.auto_increment_time returns true for both automatic modes (PROCESS and PHYSICS_PROCESS) and false for MANUAL. The new Inspector field is drive_mode; use it for new scenes and docs.

When to pick each mode

  • PROCESS — default for most games. Advances once per rendered frame.
  • PHYSICS_PROCESS — follows the physics tick for physics-driven sims.
  • MANUAL — deterministic replay, lockstep, tests, or tools. Call drive_microseconds() yourself.

Manual fixed-step example:

host.drive_mode= TimeHost.DriveMode.MANUAL
host.drive_microseconds(16_667)# one 60 Hz step

What should use Calendar Time vs raw engine delta?

For the beginner-first version of this decision, including fixed-step simulation ownership, see What Should Drive What?.

For the speed-knob comparison (whole-sim vs calendar-only), see the Whole-sim speed vs calendar speed section in What Should Drive What?.

Edge cases

  • Switching drive mode at runtime is supported. Setting drive_mode = MANUAL stops automatic advancement on the next callback check; manual drive_microseconds(...) calls still work.
  • Only the selected automatic callback advances time. In PROCESS, _physics_process returns without advancing. In PHYSICS_PROCESS, _process returns without advancing.
  • MANUAL mode + a missing clocks export leaves the host with nothing to drive. Author real scenes with at least one GameClock in clocks.