GeckoLib Player Compat
GeckoLib Player Compat is a library for applying GeckoLib animations to vanilla player models. It keeps animation state per player, synchronizes it from the server to tracking clients, and allows each mod to ship and use its own animation resources.
Features
- Applies GeckoLib bone transforms to vanilla player models while preserving skin overlay layers.
- Provides separate pose and action channels for every player. An active action takes priority over the pose.
- Stores the authoritative state in a player attachment and synchronizes it to the player and all tracking clients.
- Uses the shared
geckolib_player:playermodel by default, with an optional model override for a single action. - Lets an animation suppress vanilla transforms for selected base body parts through data-driven lock files.
Animation Resources
All regular player animations use the bundled player geometry:
assets/geckolib_player/geckolib/models/player.geo.json
Place each mod's animation file in its own namespace:
assets/examplemod/geckolib/animations/player_combat.animation.json
This file is addressed as examplemod:player_combat.
You can use BlockBench + GeckoLib Models & Animations plugin to create and export animations.
Java API
Declare GeckoLib Player Compat as a required dependency, then register every pose and action before calling it. Registration makes the animation available to GeckoLib and lets the server validate calls.
import com.iafenvoy.geckolib_player.api.PlayerAnimations;
import net.minecraft.resources.Identifier;
public final class CombatPlayerAnimations {
public static final Identifier RESOURCE = Identifier.fromNamespaceAndPath("examplemod", "player_combat");
public static void register() {
PlayerAnimations.registerPose(RESOURCE, "guard");
PlayerAnimations.registerAction(RESOURCE, "slash", 12);
}
}
Call the API on the logical server with a ServerPlayer:
PlayerAnimations.setPose(player, CombatPlayerAnimations.RESOURCE, "guard");
PlayerAnimations.playAction(player, CombatPlayerAnimations.RESOURCE, "slash");
setPose replaces the player's current pose. playAction replaces the current action and plays for its registered
duration in ticks. Both return false when the requested animation was not registered in the corresponding channel.
An action can temporarily use a different GeckoLib model. Poses always use the shared player model.
Identifier model = Identifier.fromNamespaceAndPath("examplemod", "armored_player");
PlayerAnimations.playAction(player, CombatPlayerAnimations.RESOURCE, "slash", model);
The model identifier above resolves to assets/examplemod/geckolib/models/armored_player.geo.json.
Animation Locks
A lock file is optional. It prevents vanilla setupAnim transforms from being applied to specified base body parts
while the matching animation is evaluated. This is useful when the GeckoLib animation fully controls an arm, leg, body,
or head.
For examplemod:player_combat, place the file here:
assets/examplemod/geckolib_player/locks/player_combat.lock.json
The namespace and path of the lock file map directly to the animation resource identifier. Use the same animations
object layout as the animation file:
{
"format_version": "1.8.0",
"animations": {
"guard": {
"locks": [
"right_arm",
"left_arm"
]
},
"slash": {
"locks": [
"body",
"right_arm",
"left_arm"
]
}
}
}
Supported lock names are head, body, right_arm, left_arm, right_leg, and left_leg. Skin overlay parts are
not listed because they inherit the matching base-part transform, which keeps both skin layers aligned. Omit the lock
file, an animation entry, or the locks field when vanilla transforms should remain active.
Runtime Behavior
Each player has one pose channel and one action channel. A new request replaces the previous animation in the same channel. While an action is active, it is evaluated in preference to the pose; once it finishes, the pose resumes. State is sent automatically to the local player and every client tracking that player, so no renderer-specific networking is required by integrations.

