Table of Contents

Animation Clips

Beyond the basic directional movement animation, companions can also have special animation states triggered by either a motion or an ability. These extra animations must live on the same sprite sheet and have the start frame + frame length specified as an entry in Motion AnimClips, with the right key.

The start frame counts up from 0 and can be any frame on the sheet, including the previously discussed movement frames. Consider these 2 situations:

  1. The clip reuses frames in the directional animation:
    • No new frames added.
    • Count to the desired starting frame by going left to right, up to down.
  2. The clip's frames are unique:
    • Append new frames to the end of the animation sheet.
    • Count the length of the directional animation (e.g. 4*4 = 16), this will be the start frame.
    • Additional clips that follow would start even later of course.
Tip

The console command tt.draw_debug is helpful for debugging animation frames in game.

Animation clips can be played back once (oneshot), or continuously played over the directional movement animation (override). This is decided by particular motions/abilities/states that request the animation.

Sample

{
  "Action": "EditData",
  "Target": "mushymato.TrinketTinker/Tinker",
  "TargetField": [
    "{{ModId}}_Sample",
    "Motion"
  ],
  "Entries": {
    "AnimClips": {
      "<anim clip key 1>.<directional id>": {
        "Condition": "<game state query>",
        "FrameStart": <int frame start>,
        "FrameLength": <int frame length>,
        "LoopMode": "<loop enum>",
        "Flip": "<enum SpriteEffects>",
        "Interval": <int frame length>,
        "PauseMovement": "<bool clip should pause movement>",
        "UseExtra": "<bool clip should use TextureExtra as the sheet>",
        "FrameOverrides": [
          {
            "SourceRect": {
              "X": <int source x position>,
              "Y": <int source y position>,
              "Width": <int source width>,
              "Height": <int source height>,
            },
            "Origin": "<int x origin>,<int y origin>",
            "Interval": <double miliseconds>
          }
        ],
        "Nop": <bool no-op clip>,
        "RandomWeight": <int random weight>,
        "RandomClips": [
          {
            // anim clip data, minus RandomClips which does nothing outside of the top level clip
          },
          //...
        ],
      },
      //...
    }
  }
}

Structure

Property Type Default Notes
Condition string "FALSE" A game state query used to check if this clip is allowed to play. Note that unlike most Condition checked by Trinket Tinker, this one does not receive the trinket as Input/Target item and will not work if a given query is meant to check for a trinket item there.
FrameStart int 0 First frame/sprite index of the animation clip.
FrameLength int 4 Length of the animation clip.
LoopMode LoopMode Standard Control animation playback.
  • Standard: 1 2 3 4 1 2 3 4
  • PingPong: 1 2 3 4 3 2 1
    Interval float null Milisecond Interval between animation frames. If this is not set, use the Motion's interval.
    PauseMovement bool false If true, pause movement update of this animation clip if it plays as a one shot anim clip.
    UseExtra bool false If true, try to use TextureExtra instead of Texture from Variant.
    RandomClips List<AnimClipData> null Allows extra random anim clips to be provided for this key, only relevant for the top level anim clip.
    RandomWeight int 1 Weight of random clip, if provided. Higher weight relative to other clips makes it more frequent.
    Nop bool false Indicates a no-op clip that does nothing but takes up time (and thus prevent another clip from being selected in the meantime), for use with RandomClips.

    Priority

    At each update, clips are evaluated in this order: oneshot > override > swiming > moving(anchor) > moving(directional) > idle

    Random Clips

    RandomClips allows one clip key to be associated with multiple clips, to be chosen at random. The base clip is included as part of the random, while RandomClips elements serve as additional possibilities.

    For oneshot clips, the random is checked once before they play. For override clips, random is rechecked at the end of 1 cycle of clip. To have a case where no clip is rolled, set Nop on a clip. When a Nop=true clip is chosen, the next recheck of random will be delayed by Interval * FrameLength, thus the frame number/interval is still meaningful.

    RandomWeight is a way to describe chance that a clip will be picked. If there are 3 clips with RandomWeight of 1 2 3, the weight 1 clip will appear 1 in 6 times, while the weight 3 clip will appear 3 in 6 times, or 1 in 2.

    Clips inside RandomClips may not have their own RandomClips, any data there is ignored.

    The randomization logic here is identical to RandomSpeech for speech bubbles.

    Available Clips

    Directional AnimClip Keys

    All anim keys can take on a directional index suffix such as "{KEY}.1" which depends on the direction mode. The suffix takes the absolute value of the index, no need to manually flip sprites for negative direction index.

    Example: when the direction index is 1 (perhaps because they are facing downwards in DRUL mode) and the player is not moving, "Idle.1" will be picked if available, and if not we fallback to "Idle".

    Motion Defined Keys

    These animation are applied when companion enter a state defined by particular motion, except for "Idle", which applies for all motions. These are considered "override" anim clips, which play until the player or trinket leaves the specified state.

    Key Motion Note
    "Perching" Hover Applies when companion perches on the player after a timeout, this is an override key. Perching follows static motion rules about directions (i.e. always faces same direction as player).
    "Jump" Bounce, Hop Applies when the companion is jumping, this is an override key.
    "Idle" All Motions Played when the player is not moving, Does nothing if companion is marked AlwaysMoving which forces regular directional animation to continue.
    "Swim" All Motions Played when the player is swiming, supercedes movement and idle animation.

    Anchor Defined Keys

    These keys activate while the companion is locked into a particular anchor, and cease once they are no longer targeting that anchor.

    Key Note
    "Anchor.<Mode>" The mode referred to here is an anchor mode, see Anchors.

    Ability Defined Keys

    These keys are defined by mod, in specified models.

    Field Model Note
    ProcOneshotAnim AbilityData Play the clip once on ability proc. This is a oneshot animation, after 1 cycle is finished the companion returns to normal directional animation.