Simple AnimaL

[Open Assets] Simple AnimaL v2.1.5

What permissions do you give others to modify and/or maintain your submission?
Modify: YES - Maintain: YES - I give permission for my entire submission to be modified by others or used in their own work. I give permission for my entire submission to be maintained by others as well.
I made sure my file(s) follow the Submissions Guidelines
  1. Yes
Simple AnimaL (simple animation Lua) is a reusable script made to give everybody easy but powerful control over how characters animate. Characters have Sequences defined which lists which frames to use in which order, and additional Hooks that run every tick influence the character's animation by calling for specific named Sequences. Want to make an animated goalpost? You can do that. Want to use a specific set of frames when you're underwater? You can also do that. The world is your 256-color, 35-tps oyster.

Using Simple AnimaL
Drop the script into your pk3. In a second script (make sure it's lower in your list so that it loads second), specify your character's name, Sequence names, and desired frames as shown below.

"Vanilla"-ish Simple AnimaL definition:
  ["goal"] = {S},
  ["stand"] = {A, B},
  ["stand_left"] = {C, D},
  ["stand_right"] = {E, F},
  ["walk"] = {J, G},
  ["walk_left"] = {K, H},
  ["walk_right"] = {L, I},
  ["run"] = {A, J},
  ["run_left"] = {C, K},
  ["run_right"] = {E, L},
  ["drift_left"] = {M, N},
  ["drift_right"] = {O, P},
  ["spin"] = {Q},
  ["pain"] = {Q},
  ["squish"] = {R}

Due to Lua limitations, all characters will animate between frames J and G on the character select screen. There's nothing I can do about this. Keep this in mind as you're naming frames.

Extended Frame Numbers
Most SRB2Kart characters only use up to frame S (19 frames), and some characters have a "T" frame for Acrobatics tricks. In truth, though, you can use up to 62 frames! The extended frame values are as follows.

T = 19U = 20V = 21W = 22
X = 23Y = 24Z = 25[ = 26
\ or + = 27] = 28^ = 29_ = 30
` = 31a = 32b = 33c = 34
d = 35e = 36f = 37g = 38
h = 39i = 40j = 41k = 42
l = 43m = 44n = 45o = 46
p = 47q = 48r = 49s = 50
t = 51u = 52v = 53w = 54
x = 55y = 56z = 57{ = 58
| = 59} = 60~ = 61

You could make an otherwise normal racer whose goalpost is a 42-frame animation. Fascinating.

Hooking Simple AnimaL
Every tick, all functions that exist as children of the global variable SIMPLE_ANIMAL_HOOKS will be run. If every Hook returns nil, then Simple AnimaL's default animation behaviors will occur. However, if you return a specific string, characters using Simple AnimaL will select that as their next animation Sequence.

To provide two examples:

Hook that makes Sonic freak out when underwater:
function SIMPLE_ANIMAL_HOOKS.ben_didnt_drown_hes_fine_actually(mobj, sequences)
  if sequences[1] ~= "goal" and == "sonic" and mobj.eflags & MFE_UNDERWATER
    if mobj.momz >= 0
      return "pain"
      return "squish"

This makes Sonic (and only Sonic) use pain and squish frames while underwater.

Hook that makes Foot Amy do various extra animations:
function SIMPLE_ANIMAL_HOOKS.togen_foot_amy_hook(mobj, sequences)
  if == "togen_foot_amy"
    local helpers = _G["SIMPLE_ANIMAL_HELPERS"]
    for i = 0,108 do
      S_StopSoundByID(mobj, sfx_krta00 + i)
    if (sequences[1] == "goal")
    elseif helpers.isCountdownCharging(mobj)
      return "walk"
    elseif helpers.isAirborne(mobj) and not helpers.isTricking(mobj) and not (helpers.isSquished(mobj) or helpers.isSpinning(mobj) or helpers.isPained(mobj))
      if helpers.isGliding(mobj)
        return "glide"
      elseif helpers.isAscending(mobj)
        return "ascend"
        return "descend"
    elseif(helpers.isWalkSpeed(mobj)) -- Hack to slow down the walking animation at low speeds.
      local halfspeed = helpers.isWalkSpeedMultiplied(mobj, FRACUNIT/2)
      local quarterspeed = helpers.isWalkSpeedMultiplied(mobj, FRACUNIT/4)
      if(helpers.isMovingBackward(mobj) and not helpers.isAirborne(mobj))
        if ((not quarterspeed and leveltime%4 < 3) or (quarterspeed and not halfspeed) and leveltime%2 < 1)
          mobj.Simple_AnimaL_timer = $ - 1
        return "reverse"
      elseif ((not quarterspeed and leveltime%4 < 3) or (quarterspeed and not halfspeed) and leveltime%2 < 1)
        mobj.Simple_AnimaL_timer = $ - 1
    elseif helpers.isNoSpeed(mobj) and helpers.isFinished(mobj) and not (helpers.isSquished(mobj) or helpers.isSpinning(mobj) or helpers.isPained(mobj))
      return "finished"

This hook makes togen_foot_amy emit no engine sounds (you can even do stuff unrelated to animation!), hold her arms up when paragliding, lets her use special mid-air sprites, slows down her walking animations whenever she's moving really slow, and makes her use a special animation while waiting for a race to end. Check out Togen Tech to grab a few Simple AnimaL demo characters for yourself.

Helper Functions
Simple AnimaLs includes helper functions. You can overwrite these with other mods, or make new ones entirely for your specific use case.

Helper function to check for Paraglider usage:
function SIMPLE_ANIMAL_HELPERS.isGliding(mobj)
  return mobj.paragliding

Hosting with Simple AnimaLs
Simply load a file that includes Simple AnimaLs and host. Simple AnimaL uses PostThinkHook in order to ensure that Simple AnimaL always has top priority when handling animations. PostThinkHook is such a recent addition that hopefully this shouldn't happen, but if another addon is still breaking Simple AnimaLs despite that, consider changing your load order so that your characters are last.

Requests and Feedback
Requests to add features for a specific mod will generally be rejected unless that mod also affects the animations of vanilla characters (such as Acrobatics making characters use their T frame to trick.)
If you want to make it easy for Simple AnimaL editors to trigger animations under specific circumstances, a good way to do this is to document variables that character creators can check in order to activate their animations. In one of the above examples, we check mobj.paragliding, one of several properties helpfully set by the Paragliders addon.

Global Variables
SIMPLE_ANIMAL_VERSION: An integer corresponding to Simple AnimaL's version number.
SIMPLE_ANIMAL_THINKER: The function used to determine which Sequences are most suitable under Simple AnimaL's default behavior.
SIMPLE_ANIMAL_CHANGER: The function used to assign a Sequence to a Simple AnimaL.
SIMPLE_ANIMAL_DEFINITIONS: A table containing every Simple AnimaL definition.
  • SIMPLE_ANIMAL_DEFINITIONS["sonic"]: Sonic's Simple AnimaL definition. This counts as true when Simple AnimaL Sequences are defined for Sonic.
  • SIMPLE_ANIMAL_DEFINITIONS["sonic"]["squish"]: Sonic's "squish" Sequence. This counts as true when a "squish" Sequence is defined for Sonic.
  • SIMPLE_ANIMAL_DEFINITIONS["sonic"]["squish"][1]: This returns the number (A, B, C, etc.) for the first frame of Sonic's "squish" Sequence.
SIMPLE_ANIMAL_HELPERS: A table containing every Simple AnimaL helper function.
SIMPLE_ANIMAL_HOOKS: A table containing every Simple AnimaL hook.

Mobj/Player Properties
mobj.Simple_AnimaL_timer: An integer that lists which frame of the current Sequence a Simple AnimaL is using.
mobj.Simple_AnimaL_sequence_last: A string that lists which was the last sequence used by a Simple AnimaL. If this changes, the Simple AnimaL has started a new animation.
Extension type
File size
17.9 KB
MD5 Hash
First release
Last update
4.50 star(s) 2 ratings

More resources from Togen

Share this resource

Latest updates

  1. He's a Tricky One

    Fixed an oversight in which kl_tricks animation logic did not work correctly for Simple AnimaL...
  2. Second the Color 2

    Fixed a helper function incorrectly using k_respawn. Fixed an issue where Secondcolor skins...
  3. Split the Screen

    Fixed a bug that would cause splitscreen players to animate incorrectly if one of them started...

Latest reviews

Very nice, it allows for so much freedom when creating characters.
Upvote 0
This is really cool, it kind of allows for kart characters to have a sort of pseudo-SPR2 system from 2.2, and I can't wait to see what people do with it!
Upvote 0