Chris' Tutorials
Docs/Calendar Time

Class

GameClock

Generated GDScript class reference for CalendarTime.GameClock.

StatusCurrent
Versionv2.0
UpdatedGenerated from GDScript addon source
Source note:This page rendered plugin-owned docs or generated metadata inside unified Astro docs shell.

GameClock — the runtime clock, and the one shared handle consumers reference. A GameClock is a self-contained Resource: it holds the canonical integer microsecond count, the calendar that gives that count meaning, the signal bus, its own time serializer, its own age service, AND it owns all clock-boundary event emission. UI, lighting, the day/night service, and the age service each @export one GameClock (a shared .tres) and read it directly:

  • clock.date_time() → the current DateTime (derived)
  • clock.signal_bus.<event> → subscribe to clock-boundary events
  • clock.get_time_snapshot_serializer() → save/load the clock itself
  • clock.to_dict() / clock.from_dict(...) → convenience delegates
  • clock.age_service → the counter for this clock

Dependency direction (kept honest): GameClock ──► TimeSignalBus ──► consumers (UI, lighting, DayNight, …) │ └─► clock.age_service (counter, optional — see AgeService header) The clock does NOT depend on its consumers, services, or the TimeHost. Services (like AgeService) and consumers subscribe to clock.signal_bus; the host drives clock.advance_microseconds but does not mediate them. Every mutation goes through advance_microseconds and fires the appropriate events on the clock's own bus: game_seconds_advanced, date_time_changed, date_changed (on day-boundary crossings), day_finished, and event_day_started. There is exactly one emit path — the clock — so a driver (the TimeHost, a replay system, a save-load, a unit test) cannot desynchronise consumers by forgetting to emit. date_time() is derived from current_microseconds via the calendar — it is never stored, never stale. You can have as many GameClocks as you like (a world clock, a separate festival timeline at a different rate). Each clock is independent and self-contained. Multi-clock games use a ClockGroup Resource to save / load all clocks in one dict — see clock_group.gd.

Source: addons/calendar_time/game_time/state/game_clock.gd

Syntax

class GameClock extends Resource

Members

NameKindSummary
current_microsecondsPropertyThe canonical clock value: an exact integer count of elapsed game-microseconds. Source of truth. Everything else (date_time, game_seconds) is derived from it. Not @export — it's runtime state, not authored data; saves go through TimeSnapshot.
speed_multiplierPropertyRuntime speed multiplier applied when a TimeHost/ClockGroup drives this clock. This lets one timeline run faster/slower than another without changing global Engine.time_scale or every clock on the host. Direct calls to advance_microseconds() remain exact and unscaled for deterministic seams. Pause/resume semantics: any value `<= 0.0` is a pause from the consumer's point of view. The host/ClockGroup sees the zero and skips `advance_scaled_microseconds` for this clock, so clock-boundary events stop firing while paused. UI/animation consumers that read `clock.date_time()` directly are intentionally not gated here — if a game wants to also freeze presentation, it does that with its own time-scale or by watching `clock_speed_changed` and pausing its own tween/animation systems. The `clock_speed_changed` signal is emitted on every actual change (including pause and resume), so observers can bridge the clock's pause to their own runtime state without polling.
calendarPropertyThe calendar that defines the shape of time (months, days, event days) and the date math + rate (calendar.get_scale()). Authored on the clock resource.
time_scalePropertyOptional per-clock rate override: how many game-seconds one real-second becomes. Leave unset to use the calendar/default time scale fallback. Hosts can still propagate their authored time scale to each clock in a group so the host remains the main editor surface.
epochPropertyOptional reference date used as the zero-point for date_time derivation. date_time() returns calendar.advance_date_time(epoch, elapsed_seconds). Leave unset to use DateTime.new(), the calendar epoch fallback.
clock_id_overridePropertyStable identity for save/load. Optional — empty by default; resolved lazily via `clock_id` to a hash of resource_path (when the resource is loaded from a file) plus a deterministic runtime counter fallback. Used by `ClockGroupSerializer` to key per-clock save data instead of array index, so reordering the host's clocks between save and load doesn't cross-pollinate state. Two clones of the same `.tres` get the same id automatically (no user typing required). Different `.tres` files always get different ids. Two `GameClock.new()` calls (no resource_path) get distinct ids from a monotonic counter. Override `clock_id = "..."` for explicit stable cross-machine identity (e.g. to dedupe clocks that share a resource_path across multiple instances).
signal_busPropertyThe clock event bus. Created eagerly so a consumer can subscribe the moment it holds the clock — before the host has finished _ready. The clock itself emits all clock-boundary events on this bus from `advance_microseconds`.
age_servicePropertyThe age service bound to this clock's time. Optional. Setter wires `age_service.clock = self` so the counter subscribes to this clock's bus. Not @export — the Godot parser fails to resolve a custom-Resource @export on a Resource when the two classes live in the same plugin folder (forward-reference parse order). The game assigns this from the clock .tres (plain property write) or at runtime; the setter still wires `clock = self` so the counter subscribes correctly.
time_snapshot_serializerPropertyThe clock's own time serializer (constructed in _init; self-wired).
age_registryPropertyThe clock's own age registry. Each `GameClock` carries its own `AgeStateRegistry` so age state is hermetically scoped to the clock: `AgeService`s and `AgeComponent`s attached to this clock read/write here. No process singleton — two clocks can run side-by-side without seeing each other's age states. Constructed in `_init`; lifetime matches the clock resource.
clock_idPropertyStable id used by ClockGroupSerializer for save/load identity. Lazy-derives from `clock_id_override` → resource_path → a monotonic counter (see `_derive_clock_id` for the exact priority chain). Once resolved, the value is cached — re-deriving only happens if `clock_id_override` is reassigned, which clears the cache.
pathProperty
seedProperty
seed_strProperty
hProperty
advance_microsecondsMethod
busProperty
old_dtProperty
new_dtProperty
seconds_advancedProperty
days_betweenProperty
new_eventProperty
old_eventProperty
advance_scaled_microsecondsMethod
progress_timeMethod
advance_to_next_dayMethod
old_dtProperty
target_dtProperty
delta_secondsProperty
publish_current_stateMethod
dtProperty
publish_state_loadedMethod
get_time_snapshot_serializerMethod
to_dictMethod
from_dictMethod
date_timeMethod
game_secondsMethod

Source

addons/calendar_time/game_time/state/game_clock.gd

Plugin docs root:gdscript/plugins/calendar_time_dev/docs