Animation Subsystem
Relevant source files
The following files were used as context for generating this wiki page:
The Animation Subsystem manages the world lifecycle, explicit animation execution, and actor transforms. It provides a renderer-independent framework for playing back character and object animations based on original game data. The subsystem follows strict preservation engine facts and operates with a one-way dependency on cyrus-assets.
Sources: crates/cyrus-world/README.md:1-12
Core Architecture
The subsystem consists of three primary layers: the ActorAnimation state machine, the AnimationPlayback interpreter, and the FrameSequence record. It separates the logical execution of animation commands from the physical representation of model frames.
Key Data Structures
| Component | Description |
|---|---|
ActorAnimation | Owns animation requests and playback direction for a specific actor. |
AnimationPlayback | Consumes a selected animation group and tracks its current execution state. |
FrameSequence | Contains the raw list of commands (opcodes) for a specific animation group. |
Animations Asset | A collection of all animation data for a specific world, including actor groups and decoded models. |
Sources: crates/cyrus-world/README.md:20-45, crates/cyrus-world/src/animation.rs:18-35
Playback Logic and Interpretation
Animation playback advances through AnimationTick messages which supply original nominal-tick increments. Render updates alone do not advance animations. The interpreter handles various opcodes that control frames, sound, and sequence flow.
Command Execution Flow
When an actor advances, the subsystem iterates through commands until it reaches a frame reference, a delay, or the end of the sequence.
Command Types
The subsystem interprets original engine opcodes to control actor behavior:
- ShowFrame (0): Updates the active model frame.
- End (1): Terminates the current sequence and triggers transitions to pending or default groups.
- Loop (2): Repeats sections of an animation sequence a specific number of times.
- PlaySound (4): Dispatches signed effect requests with rate offsets.
- BreakPoint (5): Sets walking-translation gates, allowing the game engine to move the actor.
Sources: crates/cyrus-world/src/animation/playback.rs:105-145, crates/cyrus-world/README.md:30-40
Request Management and Priority
ActorAnimation manages how new animations are queued and prioritized. Ordinary requests replace a pending group based on numeric priority, while forced requests bypass this priority.
State Transitions
Transitions occur when a current sequence reaches an End command or when a high-priority request interrupts the current playback.
| Event | Resulting Behavior |
|---|---|
request | Queues a group; replaces existing pending group if priority is higher. |
force_request | Immediately replaces the pending group regardless of priority. |
End Command | Selects the pending group; if none, returns to the default_group. |
select_default | Changes the fallback animation used when no tasks are active. |
Sources: crates/cyrus-world/src/animation.rs:120-180, crates/cyrus-world/README.md:42-55
Sound Integration
Animation commands can trigger synchronous sound cues. These cues capture the actor's current surface (material) at the moment the command runs.
SoundCue: A message emitted during playback containing the effect ID and positional data.SoundSurface: A component identifying the material the actor is currently standing on, used to remap generic sound IDs to surface-specific effects (e.g., footsteps on wood vs. stone).
Sources: crates/cyrus-world/README.md:25-29, crates/cyrus-world/src/animation.rs:250-270
State Persistence
The subsystem supports two levels of state recovery for actor animations:
Checkpoint and Rollback
Used for collision handling. A checkpoint saves the current command receiver and pending request. rollback restores these to permit re-evaluating movement after a collision.
Snapshots
Captures the complete playback state for save games or world transitions. A snapshot includes:
- Active and pending group indices.
- Command cursors and loop counters.
- Delay counters and frame progress bytes.
- Exit, translation, and sound latches.
Sources: crates/cyrus-world/README.md:85-110, crates/cyrus-world/src/animation.rs:210-240
Summary
The Animation Subsystem ensures faithful reproduction of the original game's movements by strictly adhering to preserved engine facts. It manages a complex state machine for each actor, coordinating command interpretation, priority-based transitions, and integration with the sound and transform systems. By using explicit ticks and renderer-independent logic, it provides a stable foundation for actor presentation across different platforms.