Skip to content

Loop architecture ​

FrameScheduler turns frame timestamps into fixed steps and a render decision. GameLoop connects it to a frame source and calls the host's callbacks.

A host with its own frame pump skips FrameSource and GameLoop and calls advance() itself.

Frame sources ​

Sources only supply timestamps. They never cap the frame rate.

SourceFrames come fromUse for
RequestAnimationFrameSourcerequestAnimationFramebrowsers, the default
AnimationLoopFrameSourcea renderer's setAnimationLoop()renderers that own the frame pump
ManualFrameSourcestep() and run() on a ManualClocktests and replays

Utilities ​

None of these are required by the core.

UtilityWhere it plugs in
Interpolatedpush a sample after each fixedUpdate, read at(alpha) in update
FrameBudgeta deadline for optional work inside a frame, timed by a Clock
FrameRateGovernorreads each FrameSchedule from frame, sets scheduler.maxFps
suspendWhenHiddenstops and restarts a GameLoop as its element leaves and enters view
Clocktime for FrameBudget and ManualFrameSource

One frame ​

CaseFrameScheduleGameLoop
First advance()zero delta, render: truecalls update only
Long gapclamped: trueemits clamp
Overloadpanicked: true, droppedMsemits panic
maxFps caprender: falsestill runs fixed steps
Pausedeffective timeScale is 0keeps receiving and rendering frames

The lag policy explains why excess time is dropped.

Lifecycle ​

A sleeping loop stops its source until invalidate() wakes it. Pausing is a separate flag and does not change these states.

See the API section and the glossary for details.