02 Lifetime
In this chapter, we will set the watch timeline and learn how it controls entity lifetimes.
Timeline and update_spawn
Players can seek freely in either direction in watch mode. Entity lifetimes must therefore follow the current playback position instead of relying on time that only moves forward.
Every frame, Watch mode calls its update_spawn callback and uses the return value as the current position on the entity-lifetime timeline.
The scaled_time function returns the current playback time after the level's time-scale changes have been applied. Using it here lets the note movement and entity lifetimes share one scaled timeline. This is the same distinction introduced in Play chapter 20.
Edit guide/watch/update_spawn.py. The template version imports time and returns time(). Replace its contents with:
python
from sonolus.script.runtime import scaled_time
def update_spawn():
return scaled_time()The template already imports this callback in guide/watch/mode.py and passes it to WatchMode, so that file needs no change in this chapter. In chapter 05, note times will be converted to this scaled timeline. In chapter 10, replay despawn times will be converted in the same way.
spawn_time and despawn_time
When Sonolus prepares the level, the spawn system calls each entity's spawn_time and despawn_time callbacks. Their return values use the timeline selected by update_spawn. An entity is active while the current timeline position is greater than or equal to spawn_time and less than despawn_time.
Entities spawn and despawn automatically based on the current timeline position. For example, an entity with an active range from 100 to 200 spawns when the timeline advances from 99 to 100, and despawns when it advances from 199 to 200.
Seeking can move the timeline into or out of that range in either direction. Seeking backward from 200 to 199 also enters the example range, while seeking from 100 to 99 leaves it. Each time an entity enters its range, Sonolus spawns it and calls initialize. Each time it leaves, Sonolus calls terminate and despawns it. The same entity can therefore initialize and terminate several times during a watch session. Chapter 09 will use is_skip() to avoid playing a particle effect when seeking causes one of these transitions.