# The Model An interaction is composed from five concepts, smallest to largest: | Concept | Map key on the IC | What it is | |---|---|---| | **State** | `ActionStates` | A named pose (relative Location / Rotation / Scale / Visibility) plus everything else it triggers (audio, FX, physics, lights, materials, animation, params, gate). Written once, referenced by name everywhere. | | **KeyFrame** | (inside an Action) | A `Time` (seconds) paired with a `State` name: "be in this pose/state at this moment". | | **Action** | (inside a Group) | One `Target` driven along an ordered list of KeyFrames. | | **Group** | `ActionGroups` | A set of Actions that play together as a unit, with easing, looping, ramps, carry, and confirm-hold settings. | | **Cycle** | `ActionCycles` | An ordered list of Group names. Each trigger moves to the next (closed → opening → open → closing → ...). `StartIndex` seeds where it begins. | You can trigger a **Cycle** to step it, a **Group** to fire it directly, or an **Action** for the finest grain. ```{mermaid} graph LR Cycle -->|steps through| Group1[Group: Open] Cycle -->|steps through| Group2[Group: Close] Group1 -->|plays together| Action1[Action: target @Panel] Group1 -->|plays together| Action2[Action: target @Handle] Action1 -->|ordered| KF1["KeyFrame 0.0 → @Zero"] Action1 -->|ordered| KF2["KeyFrame 1.0 → Open"] ``` ## Why this shape Each layer answers a different setup question: - **State** answers *"what does this pose look like, and what does it trigger?"*: written once, reused by every keyframe that needs it. - **KeyFrame** answers *"when does the target reach that pose?"*: pure timing. - **Action** answers *"which single component is this timeline for?"* - **Group** answers *"what plays together as one interaction?"*: the unit a gate, a loop, or an easing curve applies to. - **Cycle** answers *"what happens on the next press?"*: the state machine a player actually experiences (closed → opening → open → closing → closed ...). Because a State is independent of any one Action, the same `Open` state can be referenced by multiple Actions (a door panel *and* its handle rotate together, each with its own KeyFrame timing) without duplicating pose data. ## Special states A KeyFrame's `State` can be a written state **or** one of these runtime markers: | Marker | Meaning | |---|---| | `@Zero` | The object's original captured pose (reset). | | `@Current` | Hold whatever pose it's in now. | | `@Start` | The pose captured when the group started. | | `@Loop` | Loop marker: cycles the group back to its `LoopStartTime` (endless fan, escalator). | | `@Stop` | Stop smoothly (coast a loop out / ease a one-shot). | | `@StopNow` | Stop immediately, no coast. | These are resolved by logic, not looked up by name, so they are always valid and never appear in the "did you mean" typo suggestions. ## See also - {doc}`states`: everything one State can drive (audio, FX, physics, lights, anim). - {doc}`groups-and-cycles`: Group settings (easing, ramps, carry) and Cycle auto-detect. - {doc}`tag-grammar`: how a tag names a Cycle or Group to trigger, and what. - {cpp:class}`FMovaIxActionState`, {cpp:class}`FMovaIxAction`, {cpp:class}`FMovaIxActionGroup`, {cpp:class}`FMovaIxActionCycle` in the API reference.