Skip to content

GeckoLib

BonsUnleashed edited this page Oct 7, 2026 · 3 revisions

GeckoLib

Minecraft 1.20.1 / Forge: this page documents that build and its measurements. For the separate 170-control Minecraft 1.21.1 port, see Minecraft 1.21.1 NeoForge.

Five controls for GeckoLib 4.8.4 (mod id geckolib): easing computed with primitive numbers, keyframe selection and animation hashes without temporary objects, animation queues reused per bone and, on the client, quads drawn without a new vector per vertex. GeckoLib is a shared library, so a saving per call is multiplied by every mod that uses it. Every switch checks the code it would change against the tested build; another build is left untouched with one WARN line (see How the patches are applied).

Key Target Side Since Kind Result
geckolib_animation_hashes GeckoLib 4.8.4 BOTH 1.0.8 opt 80 → 0 B keyframe hash
geckolib_bone_queue_reuse GeckoLib 4.8.4 BOTH 1.0.28 opt 855 → 552 ns and 6,920 → 40 B per 20-bone controller per frame
geckolib_keyframe_locals GeckoLib 4.8.4 BOTH 1.0.8 opt 120 → 88 B per call
geckolib_primitive_easing GeckoLib 4.8.4 BOTH 1.0.6 opt −49.6 % mixed easing
geckolib_quad_vectors GeckoLib 4.8.4 CLIENT 1.0.28 opt 128 → 0 B per quad

geckolib_primitive_easing

Since: 1.0.6 · Script (1.0.19 and earlier): furious6-EasingType.js · Helper: agentcraft.pure.AcGeckoPrimitive (an empty marker interface) Patched: software.bernie.geckolib.core.animation.EasingType (apply, the composition factories and GeckoLib's 29 own easing lambdas) Mixin (since 1.0.20): EasingTypeMixin

What upstream did. Easing functions are composed and evaluated through boxed Double dispatch (Double2DoubleFunction used as a generic function) at eight call sites, so every keyframe evaluation of a non-linear easing boxes and unboxes several times.

What the patch does. Marks GeckoLib's own 29 lambda factories with the marker interface and calls the primitive get(double) for those. Custom easing functions supplied by other mods are not marked and keep the boxed dispatch.

What stays the same. Null and map-absence behaviour, dynamic arguments, endpoint casts and every easing formula. 8,000,000 float-component comparisons were equal with JOML FMA both off and on.

With Collections Of Optimizations (tested 4.4, since 1.0.27). Its option geckolib.primitiveEasing makes the same change. While that option is on, this control steps aside; while it is off, this control applies and leaves COO's copy out, so only one copy runs. See Compatibility and target versions. COO applies its copy on the client only.

Measured. Mixed easing types 67.35 → 33.92 ns (−49.6 %) and 135.76 → 58.67 B per evaluation; simple linear easing approximately neutral.


geckolib_keyframe_locals

Since: 1.0.8 · Script (1.0.19 and earlier): furious8-keyframe.js Patched: software.bernie.geckolib.core.animation.AnimationController.getAnimationPointAtTick Mixin (since 1.0.20): AnimationControllerMixin

What upstream did. Called a private helper that created a KeyframeLocation object only to unpack it immediately.

What the patch does. Performs the same search at the call site and keeps the frame and time in locals.

What stays the same. Iterator traversal, sum order, the strict boundary, the last-frame fallback, the evaluation order of dynamic expressions and the resulting AnimationPoint. 169,933 comparisons with the installed method were equal (frame identity, output values, signed zero, canonical NaN) plus native boundary, NaN and infinity cases.

Measured. 29.54 → 25.90 ns and 120 → 88 B per call.


geckolib_animation_hashes

Since: 1.0.8 · Scripts (1.0.19 and earlier): furious8-rawhash.js, furious8-framehash.js Patched: software.bernie.geckolib.core.animation.RawAnimation.hashCode and software.bernie.geckolib.core.keyframe.Keyframe.hashCode Mixins (since 1.0.20): KeyframeMixin, RawAnimationMixin

What upstream did. RawAnimation.hashCode used Objects.hash(list), which allocates a one-element varargs array; Keyframe.hashCode built a five-element array and boxed its double length.

What the patch does. Computes the identical 31-based hash directly with Objects.hashCode and Double.hashCode.

What stays the same. Hash values, collisions and hash-based equality; fields are captured before user-defined hash callbacks run, in the original order. 233,363 comparisons were equal (random and exceptional lengths, null fields, live list mutations, callback counts).

Measured. Keyframe hash 18.97 → 10.47 ns and 80 → 0 B; RawAnimation hash warm 18.44 → 19.16 ns with 64 → 64 B (the warm JIT already removes its array), interpreted 80 → 56 B and Keyframe 96 → 32 B.


geckolib_bone_queue_reuse

Since: 1.0.28 · Target: GeckoLib 4.8.4 · Side: BOTH · Kind: opt

Mixin: AnimationControllerQueueMixin

GeckoLib animation queues reused per bone. Every rendered frame, every playing GeckoLib animation controller rebuilt its bone-queue map with a new record and nine new queue lists per bone: ten objects per bone per controller per frame. The map now receives the same clear and put calls in the same order, and a bone keeps its record from the previous frame with its queues emptied, which equals the new record GeckoLib would have made. Same keys, same layout, same iteration order.

Measured: 855 ns and 6,920 B -> 552 ns and 40 B per 20-bone controller per frame on real classes; 5,275,383 checks identical (with the vertex switch below).


geckolib_quad_vectors

Since: 1.0.28 · Target: GeckoLib 4.8.4 · Side: CLIENT · Kind: opt

Mixin: GeoRendererQuadMixin

GeckoLib quads without a new vector per vertex. Every GeckoLib entity, block, item and armour renderer transformed each vertex through a new vector. In play the JIT does not remove it (review-8 profile: 69 MB in 38 seconds, 0.9% of the render thread's time). On the render thread the vertex is now transformed in one reused vector with the same matrix call, so the same floats reach the vertex call. Other threads, and renderers that override the method, keep GeckoLib's code.

Measured: 128 -> 0 B per quad on real classes; 5,275,383 checks identical (with the queue switch above).

Bons and Furious

Minecraft 1.20.1 / Forge 1.0.34

Compatibility

Controls by mod

Links

Clone this wiki locally