Skip to content
ct

Calendar Time v2.0.4

Clock-Driven Animation Pattern

Use this pattern when a per-frame visual change should pause with a GameClock. Typical case: NPC work animations that freeze when world time pauses. If the motion is presentation-only, prefer Godot pr

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

Use this pattern when a per-frame visual change should pause with a GameClock. Typical case: NPC work animations that freeze when world time pauses.

If the motion is presentation-only, prefer Godot _process delta instead. Idle dressing, mood-bubble bob, and camera feel belong there. The shipped 2D demo uses that split. Calendar Clock Speed and Engine Time Scale stay as distinct knobs.

When to use this pattern

Prefer clock time for these cases.

  • Stop at clock.speed_multiplier = 0.
  • Speed up with calendar fast-forward.
  • Represent a world actor, not UI polish.

When NOT to use this pattern

Prefer raw Godot delta for these cases.

  • Cursor blink, button hover, and menu open/close.
  • Cosmetic idle dressing that keeps playing while world time is paused.
  • Camera follow, particles, and other presentation feel.

Ask if calendar pause should stop the motion. If yes, use the clock. If only engine or SceneTree pause should stop it, use delta.

Shipped demo split

This is the 2.0.2 demo SSOT.

World facts stay on GameClock:

  • Time dial, calendar UI, and TOD presets.
  • Directional light and lighting rig.
  • Stone lanterns and TOD sprites.
  • Berry bush AgeComponent.
  • Weather DateChangeRandomToggler.
  • Emote spawn via DateChangeSpawner.

Presentation stays on Godot delta:

  • Ninja idle flip (_process).
  • OldMan walk (physics).
  • Emote bob after spawn (_process).
  • Demo cameras.

Recipe (optional)

Copy demo/scripts/calendar_time_examples/clock_driven_flipper_example.gd into your project when you want the clock-driven pause contract.

Real-time inspector knob

@export var interval_real_seconds :float = 10.0

Convert to game-seconds with delta_multiplier

_interval_game_seconds= interval_real_seconds* clock.time_scale.delta_multiplier

Exclude speed_multiplier when the host already scales the emitted game_seconds_advanced amount. Including it would double-apply speed.

Advance from game_seconds_advanced

func _on_game_seconds_advanced(p_amount :float, _p_total :float)-> void:
    if p_amount<= 0.0:
        return
    _elapsed_game_seconds+= p_amount
    if _elapsed_game_seconds>= _interval_game_seconds:
        _elapsed_game_seconds= fmod(_elapsed_game_seconds, _interval_game_seconds)
        _flip()

See also