Load Emotecraft emotes into a registry and add a whole-player bone #5

Merged
selimaj-dev merged 1 commits from emote-loader into master 2026-09-26 18:54:44 +00:00
Owner

The last piece before Saturn can switch from player-animation-lib: loading its existing emotes by ID.

Usage

Emotes.registry().loadEmotecraft("facepalm", inputStream);   // at startup
Emotes.play(uuid, "facepalm");                                // false if the ID isn't registered
Emotes.registry().all();                                      // name, description, author for the wheel

Core

  • EmotecraftLoader reads Emotecraft / player-animation-lib JSON into a KeyframeAnimation: per-channel keyframes with Easing (all 32 curves). It follows player-animation-lib's own reader, which I checked against its source:
    • absolute part pivots become offsets
    • body is the whole player, in blocks. So is torso before format version 3, which back_flip relies on.
    • angles are degrees unless "degrees": false
    • turn adds whole turns
    • loops jump back to returnTick after endTick, and only when returnTick is set
  • Emote and EmoteRegistry: emotes by ID, in the order they were added, with name, description and author.
  • Animation.loopStart: lets a loop restart after an intro.
  • Jackson: 2.17.0, the version Saturn Client ships.

Whole-player bone

Bone.ROOT moves the whole player, which flips and dances need. It turns around the model's middle (0.7 blocks above the feet, the same point player-animation-lib uses) through the model's root part, so armor and held items follow.

Fabric

  • Emotes.registry() and Emotes.play(uuid, id).
  • Core and Jackson are bundled in the jar.

Tester

  • Loads Saturn's six emotes into the library's registry; play them with /emotes play <id>.
  • The hand-written test animations stay in a separate registry of the testmod's own, played with /emotes test <name>, so the two can reuse names.
  • The gametest now shoots the loaded emotes too.

Testing

  • 57 core tests pass, including loading all six shipped emotes, timing, the torso rule, degrees and turns.
  • buildAll builds all 8 versions.
  • Checked in screenshots on 1.21.11:
    • facepalm and cry put their hands on the face, which confirms the bend direction.
    • tpose and giga_chad look right.
    • Both flips leave the ground and turn the right way.

Not supported yet

  • Blending with the vanilla pose (#4). Until then, emotes hold their first and last keyframes and snap on and off.
  • Scale channels, easingArg, and the cape following ROOT.

🤖 Generated with Claude Code

The last piece before Saturn can switch from player-animation-lib: loading its existing emotes by ID. ## Usage ```java Emotes.registry().loadEmotecraft("facepalm", inputStream); // at startup Emotes.play(uuid, "facepalm"); // false if the ID isn't registered Emotes.registry().all(); // name, description, author for the wheel ``` ## Core - **`EmotecraftLoader`** reads Emotecraft / player-animation-lib JSON into a **`KeyframeAnimation`**: per-channel keyframes with **`Easing`** (all 32 curves). It follows player-animation-lib's own reader, which I checked against its source: - absolute part pivots become offsets - `body` is the whole player, in blocks. So is `torso` before format version 3, which `back_flip` relies on. - angles are degrees unless `"degrees": false` - `turn` adds whole turns - loops jump back to `returnTick` after `endTick`, and only when `returnTick` is set - **`Emote`** and **`EmoteRegistry`**: emotes by ID, in the order they were added, with name, description and author. - **`Animation.loopStart`**: lets a loop restart after an intro. - **Jackson**: 2.17.0, the version Saturn Client ships. ## Whole-player bone `Bone.ROOT` moves the whole player, which flips and dances need. It turns around the model's middle (0.7 blocks above the feet, the same point player-animation-lib uses) through the model's root part, so armor and held items follow. ## Fabric - `Emotes.registry()` and `Emotes.play(uuid, id)`. - Core and Jackson are bundled in the jar. ## Tester - Loads Saturn's six emotes into the library's registry; play them with `/emotes play <id>`. - The hand-written test animations stay in a separate registry of the testmod's own, played with `/emotes test <name>`, so the two can reuse names. - The gametest now shoots the loaded emotes too. ## Testing - 57 core tests pass, including loading all six shipped emotes, timing, the `torso` rule, degrees and turns. - `buildAll` builds all 8 versions. - Checked in screenshots on 1.21.11: - `facepalm` and `cry` put their hands on the face, which confirms the bend direction. - `tpose` and `giga_chad` look right. - Both flips leave the ground and turn the right way. ## Not supported yet - Blending with the vanilla pose (#4). Until then, emotes hold their first and last keyframes and snap on and off. - Scale channels, `easingArg`, and the cape following `ROOT`. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
selimaj-dev added 1 commit 2026-09-26 18:51:54 +00:00
- core: EmotecraftLoader reads Emotecraft / player-animation-lib JSON
  into a KeyframeAnimation (per-channel keyframes with Easing), following
  player-animation-lib's reader: absolute pivots become offsets, body
  (and torso before version 3) is the whole player in blocks, angles are
  degrees unless "degrees": false, turn adds whole turns, and loops jump
  back to returnTick after endTick. Emote and EmoteRegistry hold emotes
  by ID with their name, description and author. Animation.loopStart
  lets loops restart after an intro. Uses Jackson 2.17.0, the version
  Saturn Client ships.
- Bone.ROOT moves the whole player around its middle (0.7 blocks above
  the feet), through the model's root part, so armor and held items
  follow.
- fabric: Emotes.registry() and Emotes.play(uuid, id). Core and Jackson
  are bundled in the jar.
- testmod: loads Saturn's six emotes into the library's registry
  (/emotes play), and keeps its test animations in a separate registry
  (/emotes test). The gametest shoots the loaded emotes too.

Blending with the vanilla pose is issue #4.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
selimaj-dev merged commit 7f8de39253 into master 2026-09-26 18:54:44 +00:00
selimaj-dev deleted branch emote-loader 2026-09-26 18:54:46 +00:00
Sign in to join this conversation.