AppleyAppley Docs
Docs/Lighting

Day/Night Cycles

Create dynamic day and night cycles with sun movement and color transitions.

18 min read Intermediate Updated 2026-07-01 v2.0 ~59 min to complete

Introduction

Day/night cycles add immersion and gameplay variety. This guide covers sun movement, sky color transitions, star fields, and nighttime lighting.

Guide 7 of 25

This is part of the Intermediate Guides collection. Category: Lighting. Estimated completion: 59 minutes. Difficulty: Intermediate.

Screenshot

Day/Night Cycles
Day/Night Cycles

Step-by-Step Guide

1

Create a time system

Add a TimeManager object. Track time as 0-24 (hours). Set time speed (1 in-game hour = 2.5 real minutes).

2

Animate the sun

Rotate the directional light based on time. 6:00 = sunrise (east), 12:00 = overhead, 18:00 = sunset (west).

3

Transition sky colors

Lerp sky colors: dawn (orange), day (blue), dusk (red-orange), night (dark blue). Use gradient presets.

4

Add stars at night

Show a starfield between 20:00 and 5:00. Fade stars in/out smoothly at twilight transitions.

5

Adjust ambient light

Day ambient bright (0.4), night ambient dim (0.05) with blue tint. Moonlight provides minimal directional light.

6

Trigger gameplay events

Use time-based events: enemies spawn at night, shops open during day, certain NPCs appear at specific times.

FluxScript Example

Here is a complete FluxScript implementation for this guide:

Day/Night Cycles — FluxScript
timeOfDay = 8.0
timeSpeed = 0.1

const SKY = {
  dawn:  { light: 0.8 },
  day:   { light: 1.2 },
  dusk:  { light: 0.6 },
  night: { light: 0.1 }
}

on update(dt) {
  timeOfDay += timeSpeed * dt
  if timeOfDay >= 24 timeOfDay -= 24
  sunAngle = (timeOfDay / 24) * 360 - 90
  sun = scene.find("SunLight")
  sun.setRotation(sunAngle, 30, 0)
  phase = getSkyPhase(timeOfDay)
  sun.setIntensity(phase.light)
  stars = scene.find("StarField")
  stars.setOpacity(getStarVisibility(timeOfDay))
  if timeOfDay > 20 || timeOfDay < 6 {
    if !nightSpawned { spawnNightEnemies(); nightSpawned = true }
  } else { nightSpawned = false }
}

func getSkyPhase(t) {
  if t > 5 && t < 8 return SKY.dawn
  if t >= 8 && t < 17 return SKY.day
  if t >= 17 && t < 20 return SKY.dusk
  return SKY.night
}

Node Graph Example

Prefer visual programming? Here is the equivalent Node Graph:

Day/Night Cycles — Node Graph
[On Update] --> [timeOfDay += timeSpeed * dt] --> [Wrap at 24]
   --> [Set Sun Rotation + Intensity]
   --> [Get Sky Phase] --> [Set Sky Colors]
   --> [Set Star Opacity]
   --> [Branch: night time] --> [Spawn Night Enemies]

Optimization Tips

Keep your implementation fast and efficient with these optimization tips:

  • Bake stars into a skybox texture instead of using particle stars. A textured skybox is essentially free.
  • Limit real-time light changes. Gradually lerping sun intensity is fine, but changing shadow quality dynamically causes hitches.
  • Use gradient textures for sky color transitions. Sampling a 1D gradient is cheaper than branching in shaders.
  • Slow down time speed during gameplay-critical moments. A 4-minute day cycle is too fast for combat-heavy games.

Common Mistakes

Sun rotation causing shadow flickering

Shadow maps update when the light moves. Limit sun rotation speed or update shadows less frequently.

Night is too dark to see

Add moonlight (dim directional light) and ambient light at night. Total darkness frustrates players.