Skip to content

The Timeline Model

You never set frames manually. agentwood computes the shot length from what the actors do.

The two rules

Natural end, then clip ceiling

  1. Natural end = max(cursor_frame across all actors) — the longest actor's animation / walk / dialog drives the length.
  2. clip(seconds) is a hard ceiling: final length = min(natural_end, clip). It can only shorten, never extend.
bob.idle()                 # frames 1..end
bob.set_frame(30)          # jump the cursor forward
bob.walk_to((5, 0, 0))     # this walk starts at frame 30
shot.clip(6.0)             # cap the whole shot at 6 s
  • No clip() → the shot runs to its natural end.
  • Actors that finish early are auto-extended with a held idle, so nobody vanishes.
  • One frame for a quick look: shot.clip(1/24).
  • shot.duration() / shot.max_duration() are back-compat aliases of clip().

Sequencing within a shot

set_frame(n) moves an actor's cursor so the next action begins at frame n:

a.actor.idle()        # 1 .. N
a.set_frame(150)      # leave a gap
a.actor.perform("waving")   # starts at frame 150

Per-action duration is currently unreliable

For in-place (non-locomotion) actions, the duration= argument is ignored — the clip plays its full native length. To bound a shot, use shot.clip() instead. (Tracked as a known issue.)

Quick reference

You write Result
only idle() / say() / walk_to() length = the longest of them
+ shot.clip(s) where s < natural capped to s
+ shot.clip(s) where s > natural no effect (ceiling only)
set_frame(n) then an action that action starts at frame n

Next: Sets & Locations