ludic/docs/language/anim/anim-play.md
Orkuncakilkaya 1f5e3c1c1a
All checks were successful
bootstrap / cfree-fixpoint (push) Successful in 18s
ci / build-and-test (push) Successful in 1m21s
commit-lint / conventional-commits (push) Successful in 5s
docs / build-and-deploy (push) Successful in 20s
feat(anim): animation ergonomics — named clips, Anim.play/Motion.to, frame events, fluent Tween handles (#48)
The ergonomic layer over the engine-owned SpriteAnim/Motion systems (#43):

- Named clips: Anim.clip("run", frames, fps, mode) registers a clip by name and
  Anim.play(entity, "run") plays it; Anim.play(entity, fps, frames, mode) sets
  the clip directly. A name-keyed registry in systems.ludic.
- Frame events: Anim.on_frame(entity, frame) arms optional SpriteAnim
  event_frame/event_fired fields; the engine flags the tick the clip first lands
  on that frame, and Anim.fired(entity) reads it — the game reacts, so it stays
  inside the no-runtime-dispatch event model.
- Motion.to(entity, from, to, dur, ease) starts a value tween over the Motion
  component in one call (reflection-ABI writes, resetting the timer).
- Fluent Tween handles (runtime/native/tween.ludic): Tween.to / Tween.chain /
  Tween.delay build a sequenced, disposable handle advanced by a new engine-owned
  system (esys_tween, run each Update tick); Tween.value / Tween.done /
  Tween.parallel / Tween.stop read and control it. The 1-arg Tween.done(handle)
  is disambiguated from the 2-arg pure Tween.done(timer, dur).

Splicing: g_uses_anim_rt pulls in systems.ludic; g_uses_tween_rt pulls in
tween.ludic and inserts esys_tween into the Update phase. All integer and
deterministic, so animation and motion reproduce exactly under replay/lockstep.

Worked example + regression: examples/library/anim_sugar.ludic
(4 8 2 1 0 100 100 0 0 1 20 20 30 0 1). Twelve new docs pages (Anim, the new
Motion namespace, Tween handles). Full suite 77 passed, self-host C-free fixpoint
intact, no golden drift.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-08-31 16:53:16 +03:00

1.5 KiB

id name category kind tokens sig tip order ns member
anim-play Anim.play anim namespace-method Anim.play Anim.play(entity, clip) | Anim.play(entity, fps, frames, mode) Start (or restart) a spritesheet clip on an entity in one call. 30 Anim play

Starts a spritesheet clip on an entity's SpriteAnim component and rewinds it to its first cell, so gameplay swaps or replays an animation with one call instead of setting five fields by hand. Two forms: Anim.play(entity, "run") plays a named clip registered with Anim.clip; Anim.play(entity, fps, frames, mode) sets the clip directly (mode 0 loop, 1 once, 2 ping-pong). A no-op if the entity has no SpriteAnim. The engine advances the clip from there each tick.

Parameters:

  • entity — the entity carrying SpriteAnim
  • clip — a registered clip name (2-argument form), or
  • fps, frames, mode — the clip rate, cell count and play mode (4-argument form)
program Demo {
  property SpriteAnim { ticks: int = 0, fps: int = 0, frames: int = 0, mode: int = 0, frame: int = 0 }
  model Hero { SpriteAnim }
  entry {
    Anim.clip("run", 6, 12, 0)
    spawn Hero { SpriteAnim { } }
    let e = World.query_next(World.prop_id("SpriteAnim"), 0)
    Anim.play(e, "run")                 # by name
    Anim.play(e, 8, 4, 1)               # or directly: 4 frames @ 8fps, once
    quit()
  }
}