Skip to content

Timeline

The Timeline system drives multi-track animations that coordinate property changes, Spine playback, sprite animations, audio events, and entity activation over time. Timelines are created in the editor’s Timeline panel and played back at runtime via the TimelinePlayer component and TimelineControl API.

Editor Workflow

  1. Select an entity in the Hierarchy
  2. Open the Timeline panel
  3. Click + to add tracks (Property, Spine, Sprite Animation, Audio, Activation)
  4. Add keyframes by clicking on the timeline ruler
  5. The timeline is saved as a .estl asset file

Track Types

TypeDescription
PropertyAnimate any numeric component property (position, scale, color, etc.) with keyframe interpolation
SpineTrigger Spine animation clips on a SpineAnimation component
Sprite AnimationPlay sprite animation clips
AudioTrigger audio events at specific times
ActivationEnable/disable entities over time ranges

TimelinePlayer Component

Add TimelinePlayer to an entity to play a timeline asset at runtime. Configure it in the editor Inspector or from code.

PropertyTypeDefaultDescription
timelinestring''Path to the .estl timeline asset
playingbooleanfalseWhether the timeline is currently playing
speednumber1.0Playback speed multiplier
wrapModestring'once''once', 'loop', or 'pingPong'

WrapMode

ValueDescription
oncePlay once and stop at the end
loopRestart from the beginning when finished
pingPongAlternate between forward and reverse playback

TimelineControl API

Use TimelineControl to control timeline playback from systems:

import { defineSystem, addSystem, Query, TimelinePlayer, TimelineControl } from 'esengine';
import { Res, Input } from 'esengine';
addSystem(defineSystem(
[Res(Input), Query(TimelinePlayer)],
(input, query) => {
for (const [entity] of query) {
if (input.isKeyPressed('Space')) {
TimelineControl.play(entity);
}
if (input.isKeyPressed('KeyP')) {
TimelineControl.pause(entity);
}
}
}
));

Methods

MethodReturnsDescription
TimelineControl.play(entity)voidStart or resume playback
TimelineControl.pause(entity)voidPause playback
TimelineControl.stop(entity)voidStop and reset to the beginning
TimelineControl.setTime(entity, time)voidSeek to a specific time (seconds)
TimelineControl.isPlaying(entity)booleanCheck if timeline is playing
TimelineControl.getCurrentTime(entity)numberGet current playback time (seconds)

Registering Timeline Assets

When loading timelines outside the editor (e.g., in a custom asset pipeline), use the registration API:

import { registerTimelineAsset, getTimelineAsset, parseTimelineAsset } from 'esengine';
// Parse raw timeline data
const asset = parseTimelineAsset(jsonData);
// Register for runtime lookup
registerTimelineAsset('timelines/intro.estl', asset);
// Retrieve later
const tl = getTimelineAsset('timelines/intro.estl');

Example: Intro Sequence

import {
defineSystem, addStartupSystem, addSystem,
Query, Mut, TimelinePlayer, TimelineControl, Res, Input
} from 'esengine';
// Play the intro timeline on startup
addStartupSystem(defineSystem(
[Query(Mut(TimelinePlayer))],
(query) => {
for (const [entity, player] of query) {
if (player.timeline === 'timelines/intro.estl') {
TimelineControl.play(entity);
}
}
}
));
// Allow skipping with any key
addSystem(defineSystem(
[Res(Input), Query(TimelinePlayer)],
(input, query) => {
if (input.isKeyPressed('Space')) {
for (const [entity, player] of query) {
if (TimelineControl.isPlaying(entity)) {
TimelineControl.stop(entity);
}
}
}
}
));

Next Steps