Skip to content

Calendar Time v2.1.0

Calendar Time Examples

These examples use the current Calendar Time public API: - Bind a GameClock directly in UI and gameplay scripts. - Put that clock in TimeHost.clocks so the host drives it. - Subscribe to clock.signalb

Status
Current
Version
v2.1.0
Source updated
2026-08-09
Generated on
2026-09-01

These examples use the current Calendar Time public API:

  • Bind a GameClock directly in UI and gameplay scripts.
  • Put that clock in TimeHost.clocks so the host drives it.
  • Subscribe to clock.signal_bus for time events.
  • Use clock.to_dict() / clock.from_dict() for one clock.
  • Use time_host.get_group_serializer() / time_host.load_state() for all clocks.

Beginner setup reminder: the examples assume your scene has a TimeHost node and that its clocks array contains the same GameClock assigned to the script.

Demo helpers are not required API

The repository demo may include extra helper scripts.

Examples: crop/resource-node behavior, demo save UX, runtime wiring, or export proof.

Copy and adapt them when useful.

They are not part of Calendar Time's core addon API.

The examples below stay on the stable seam: GameClock, TimeHost, clock.signal_bus, and save/load APIs.

Treat the demo as reference code, not as guaranteed addon API. Files under addons/calendar_time/ and templates/calendar_time/ are the supported plugin surface. Project-level demo scripts are examples you can copy into your own game namespace, rename, and adapt to your game's save UX, interactions, or export requirements.

React when the month changes

Subscribe on the clock's signal bus. The clock owns all clock-boundary events; the host only drives time forward.

class_name DateChangeMonitor
extends Node

@export var clock :GameClock

func _ready()-> void:
    if clock== null:
        push_error("GameClock not set in DateChangeMonitor")
        return

    clock.signal_bus.date_changed.connect(_on_date_changed)

func _on_date_changed(event:DateChangeEvent)-> void:
    if event.old_date!= null and event.new_date!= null and event.old_date.month!= event.new_date.month:
        # Add month-change behavior here.
        pass

Bind the GameClock your node cares about and subscribe through clock.signal_bus.

Skip time from a pause menu or bed interaction

Use the host when you want to drive every clock it owns. Use the clock directly when the action belongs to one specific timeline.

class_name DayController
extends Node

@export var time_host :TimeHost
@export var clock :GameClock

func _ready()-> void:
    if time_host== null:
        push_error("TimeHost not set in DayController")
        return
    if clock== null:
        push_error("GameClock not set in DayController")
        return

# Example: advance this clock to the start of its next calendar day.
func advance_to_tomorrow_morning()-> void:
    clock.advance_to_next_day(HoursTime.new(6,0))# 6:00 AM next day

# Example: add a fixed span of game time to every clock driven by the host.
func skip_24_hours_for_host()-> void:
    time_host.drive_seconds(86_400.0)

For deterministic integer-µsMANUAL mode examples, see
[TimeScale & DriveMode](/docs/calendar-time/v2-0/timescale-and-drive-modes/).

Most games use one `TimeHost` with one `GameClock`in `TimeHost.clocks`.Add
more clocks to the same host onlywhen you intentionally need independent
timelines, suchas world timeand a paused festival timeline.

## Save and load one clock

Use per-clock save/loadwhen your game has a single clockor when you are saving
one timeline separately.

```gdscript
@export var clock :GameClock

func save_clock()-> Dictionary:
    return clock.to_dict()

func load_clock(data :Dictionary)-> void:
    clock.from_dict(data)

clock.from_dict(data) restores the clock's canonical microsecond count and publishes a state-loaded event so UI, day/night, and other derived consumers can refresh.

Save and load every clock on a host

Use the host's group serializer when your save file should include all clocks in TimeHost.clocks, including age state when configured.

@export var time_host :TimeHost

func save_all_time()-> Dictionary:
    return time_host.get_group_serializer().to_dict()

func load_all_time(data :Dictionary)-> void:
    time_host.load_state(data)

The grouped save shape is reorder-safe. Each GameClock has a stable clock_id, so adding or reordering clocks does not send one timeline's save data into a different clock when ids match.

See also

  • Game Facts Driven by Clock Time — derive game-local facts (e.g. is_night) from the clock's authoritative time-of-day and feed them into gameplay systems additively. Use this when AI, planning, or event logic needs to react to TOD as a fact rather than a signal.
  • Game-Owned Schedules and World Rules — put shop hours and other game-specific policy on top of the one authoritative Calendar Time clock.