Gessa Docs
Recipes

Recipe

Day night cycle and moving sun by script

The sun arcs overhead and the scene warms into sunset then dark. The sky preset, fog, and tone mapping are a static world look (see atmosphere-sky-and-lighting); a MOVING cycle is a script that patches a LightComponent over time. The TimerComponent contract itself names day/night cycles as a use case.
engine v1.0.234since script-semantic-patch-ops.v1, action-catalog.v1.0.232, timer.v1, rendering.v1, mutation.v1Copy for LLM

Use this for

a sun that moves across the sky and a day that turns to night; scripted lighting changes over time; flickering, pulsing, or strobing lights; dimming or tinting the scene on a schedule

Not for

a one-time static sky, fog, or lighting look (see atmosphere-sky-and-lighting); post-processing or tone-mapping profiles (see atmosphere-sky-and-lighting); global weather simulation, which has no atomic

Pairs with: Atmosphere sky lighting fog and time of day, Timers countdowns cooldowns and enemy waves, Moving platforms, elevators, rotating hazards, and objects on a patrol path

The recipe

Author with project_apply_script_semantic_patch using the ai_safe op pack. The sun is an entity with a directional LightComponent (mode:"directional").

  1. Advance a clock: keep a timeOfDay phase (0 to 1) in durable state. Drive it from addTickHandler scaled by ctx.delta, or from a TimerComponent plus addTimerHandler for coarse steps. incrementNumericState { "field":"timeOfDay", "by": <delta / dayLengthSeconds> } and wrap at 1.
  2. Move the sun: in the body (whole-body GessaScript via replaceScriptFromGessaScript), map timeOfDay to a sun angle and ctx.entity.patchComponent the light's rotation (a directional light's direction follows its transform). This is the moving-sun arc.
  3. Change the look: patch intensity down toward night and back up toward day, and patch color warm at dawn and dusk, cool at noon, dark at night. Turn castShadow on for a hard midday sun if desired.
  4. No script needed for oscillating light: set LightComponent.modulation (mode one of none, strobe, pulse, flicker, disco, plus rateHz and depth) for a torch flicker or a club strobe directly on the component.
  5. Reuse the same phase to drive ambient fill: patch a second ambient-mode light's intensity so shadows do not go pure black at night.

Pitfalls

  • Scale the phase step by ctx.delta; a fixed per-tick step makes day length depend on frame rate.
  • Store timeOfDay in durable state so a reload resumes at the same time and all clients read one clock.
  • There is NO per-field AI tool to set the world sky's built-in time-of-day (WorldAuthoredEnvState.simTimeSeconds/timeOfDayRate); animate an authored LightComponent yourself instead of expecting a sky-clock setter.
  • Keep intensity at or above a small floor; a directional light at 0 with no ambient fill renders a black scene.
  • Prefer LightComponent.modulation over a per-tick script for pure flicker or strobe; it is cheaper and deterministic.

Verify

  • simulation_run (qa.run.start) to watch a full cycle move the sun and shift intensity and color from day to night.
  • project_get_graph_snapshot to confirm the tick or timer handler and the directional LightComponent are present.
Was this helpful?Report an issueContact support

On this page