Turn Blockbench models into fully animated, in-world rigs on a Paper server, then drive them with commands, a developer API, MythicMobs mechanics and PlaceholderAPI placeholders.
This page is the complete guide: from building a model in Blockbench to playing animations in game and controlling rigs from your own plugin.
How rigs are rendered. Each cube of your model becomes a Minecraft
BlockDisplay, i.e. a real block. The plugin does not use Blockbench textures/UVs: you assign a Minecraft block material to each cube (defaultSTONE). Design "blocky" models and pick a block per part. Bones, pivots, rotations, scaling and animations are fully respected.
- Requirements
- Installation
- Build a model in Blockbench
- Import the model
- Spawn and animate
- Give cubes their blocks (materials)
- Command reference
- Configuration
- Permissions
- Developer API
- MythicMobs integration
- PlaceholderAPI
- Troubleshooting
- Paper 1.20.4+ (or a fork). Built against 1.20.4; tested only up to 1.21.4.
- Java 17+ on the server.
- Optional: MythicMobs 5.x and PlaceholderAPI (auto-detected, no config needed).
- Drop
MinecraftAnimationTool-1.0.jarinto your server'splugins/folder. - Start the server once. The plugin creates:
plugins/MinecraftAnimationTool/blueprints/— put your.bbmodelfiles here.plugins/MinecraftAnimationTool/cache/— generated, one slim.jsonper model (don't edit by hand).plugins/MinecraftAnimationTool/config.yml.
- That's it. Continue below to add your first model.
Blockbench is free. The plugin reads the model's cubes, bone tree
(outliner) and animations from the raw .bbmodel file.
File > New > Generic Model(or Free Model). Any format that lets you make cubes, group them and animate works. Avoid formats that forbid animations.
- Build your model out of cubes. Scale matters: 16 Blockbench units = 1 block in game.
- Keep it reasonably "blocky" — each cube is rendered as a single Minecraft block.
- In the Outliner, put cubes into groups. Each group is a bone you can animate (e.g.
head,arm_left,leg_right). - Set each group's pivot point (the origin) where it should rotate from. This is essential: rotations happen around the bone pivot.
- Switch to the Animate tab and create an animation. The animation name is what you'll use in
/mat play(e.g.idle,walk,attack). - Add keyframes on bones for the rotation, position and scale channels.
- Set looping (
Loop/Once) in the animation properties. Looping animations repeat automatically. - Easing: per-keyframe easing and interpolation modes are supported (
linear,step, smooth /catmullrom, and the full ease-in/out set). Set them on keyframes for smoother motion. - Math expressions: keyframe values may use MoLang-style math, e.g.
math.sin(query.anim_time*120)*25. Supported:+ - * /, parentheses,sin cos tan abs sqrt log(degrees), and thequery.anim_timevariable.
- Add a sound effect keyframe on the animation timeline (effects/sound channel). Use a Minecraft sound
name such as
ambient.caveorminecraft:ambient.cave(both work). It plays at the rig's location when the playhead crosses that keyframe.
- Use
File > Save Modelto produce a.bbmodelfile. (Do not use "Export" — the plugin reads the native.bbmodel.)
- Copy your file, e.g.
dragon.bbmodel, intoplugins/MinecraftAnimationTool/blueprints/. - In game (or console) run:
This parses every
/mat reload.bbmodel, writes a cache, and loads it. The cache name is the file name without extension —dragon.bbmodelbecomes the cachedragon. - Check it loaded:
/mat reloadprintsLoaded caches: N.
/mat spawn boss dragon # spawn cache "dragon" as a rig named "boss" at your feet
/mat spawn boss dragon 2 # ... at 2x scale
/mat play boss idle # play the "idle" animation (cross-fades from the current pose)
/mat play boss walk # switch animation, smoothly blended
/mat pose boss attack 0.5 # freeze on the frame at 0.5s of "attack"
/mat pause boss # pause / hold the current frame
/mat resume boss
/mat stop boss # stop, keep current pose
/mat reset boss # stop, snap back to the bind pose
/mat tp boss ~ ~ ~ 90 0 # move/orient the rig (here: face yaw 90)
/mat info boss # show details
/mat list # list spawned rigs
/mat kill boss # remove the rig
Names are made unique automatically: spawning boss twice gives boss and boss-2.
Fresh rigs are made of STONE. Two ways to assign a block per cube:
Paint mode (visual, recommended):
/mat edit
Toggles paint mode. Hold a block in your hand and right-click a cube of any rig to paint it. The cube
you're aiming at is highlighted. Run /mat edit again to stop. Changes are saved to the cache and applied
to every rig using that model.
By command:
/mat edit <cache> <part> <material>
# e.g.
/mat edit dragon head_1 RED_WOOL
<part> is a cube label (tab-completed) or a raw index. Material must be a placeable block.
Material assignments persist across /mat reload.
Base command: /mat (alias /minecraftanimationtool). Permission: mat.command (default: op).
| Command | Description |
|---|---|
/mat help |
List commands. |
/mat reload |
Reload config.yml, rebuild caches from blueprints/, reload them. |
/mat spawn <name> <cache> [scale] |
Spawn a rig at your location, optional uniform scale. |
/mat list |
List spawned rigs. |
/mat info <name> |
Show info about a rig. |
/mat play <name> <animation> |
Play an animation (cross-fades from the current pose). |
/mat pose <name> <animation> <time> |
Freeze on a single frame at time seconds. |
/mat pause <name> / /mat resume <name> |
Pause / resume the current animation. |
/mat stop <name> |
Stop the animation, keep the current pose. |
/mat reset <name> |
Stop and restore the initial (bind) pose. |
/mat tp <name> [x y z] [yaw pitch] [world] |
Move / orient a rig. |
/mat edit |
Toggle paint mode (right-click a cube with a block to paint it). |
/mat edit <cache> <part> <material> |
Set one cube's block material. |
/mat kill <name> |
Remove a rig. |
plugins/MinecraftAnimationTool/config.yml:
# Ticks between each interpolation step the plugin computes (minimum 1). Also the period of the
# single global animation ticker.
interpolation-updates: 1
# When true, also use the client's native block-display tweening between the plugin's steps so motion
# looks smooth; when false, each step snaps.
use-minecraft-interpolation: true
# Ticks to cross-fade from the current pose into a newly played animation. 0 disables blending.
animation-blend-ticks: 4
# When no player is within this many blocks of a rig, the plugin stops pushing transform updates but
# keeps advancing animation time (so playback stays in sync and resumes seamlessly). 0 disables culling.
cull-distance: 0Changing these and running /mat reload applies them live.
| Node | Default | Grants |
|---|---|---|
mat.command |
op | All /mat subcommands. |
Other plugins can spawn and control rigs without owning the paid jar — compile against the free API below. At runtime the paid plugin must be installed on the server, otherwise the service is absent and your code degrades gracefully.
Maven:
<repositories>
<repository>
<id>jitpack.io</id>
<url>https://jitpack.io</url>
</repository>
</repositories>
<dependency>
<groupId>com.github.bloupyi</groupId>
<artifactId>MinecraftAnimationTool-API</artifactId>
<version>v1.0</version> <!-- a git tag or commit hash -->
<scope>provided</scope>
</dependency>Gradle:
repositories { maven { url 'https://jitpack.io' } }
dependencies { compileOnly 'com.github.bloupyi:MinecraftAnimationTool-API:v1.0' }Declare the soft dependency in your plugin.yml:
softdepend: [ MinecraftAnimationTool ]Resolve the API through Bukkit's service manager (works with only this API on your classpath; returns
null when the paid plugin is not installed):
import fr.bloup.minecraftAnimationTool.api.MinecraftAnimationToolApi;
import fr.bloup.minecraftAnimationTool.api.AnimatedModel;
MinecraftAnimationToolApi api = getServer().getServicesManager()
.load(MinecraftAnimationToolApi.class);
if (api == null) {
getLogger().warning("MinecraftAnimationTool not installed; animation features disabled.");
return;
}
AnimatedModel model = api.spawn("boss", "dragon", player.getLocation(), 2.0f);
model.play("idle");
model.play("roar", () -> model.play("idle")); // run a callback when a non-looping animation endsAnimatedModel exposes: play, play(anim, onEnd), pose, pause, resume, stop, reset,
setSpeed, getCurrentAnimation, isPlaying, getScale, setScale, teleport, setRotation,
lookAt, setPartMaterial, getLocation, getAnimationNames, getPartNames, remove.
MinecraftAnimationToolApi adds cache queries, reloadCaches, setPartMaterial, spawn(..., scale)
and model lookup (getModel(name|uuid), getModels).
import fr.bloup.minecraftAnimationTool.events.ModelInteractEvent;
@EventHandler
public void onModelClick(ModelInteractEvent e) {
if (e.getClickType() == ModelInteractEvent.ClickType.RIGHT) {
AnimatedModel m = api.getModel(e.getModelUuid());
// e.getPartName(), e.getPartIndex(), e.getPlayer(), e.getCacheName()...
}
}When MythicMobs 5.x is installed, custom mechanics are registered automatically. The targeted rig is
resolved by name= (with <caster.uuid> / <caster.name> substitution), or, when name is omitted, a
deterministic rig owned by the casting mob (mm_<caster uuid>).
| Mechanic | Targeter | Args |
|---|---|---|
matspawn |
@location |
model= (cache), name=, scale=, anim=, replace= (default true) |
mattp |
@location |
name= |
matlookat |
@location |
name= |
matplay |
— | name=, anim= |
matpose |
— | name=, anim=, time= |
matpause / matresume |
— | name= |
matstop / matreset |
— | name= |
matspeed |
— | name=, speed= |
matscale |
— | name=, scale= |
matremove |
— | name= |
matmaterial |
— | name=, part=, material= |
Example — a mob that wears a rig and roars on attack:
Dragon:
Type: ZOMBIE
Options:
Invisible: true
Skills:
- skill{s=DragonSpawn} ~onSpawn
- skill{s=DragonRoar} ~onAttack
- matremove{} ~onDeath
DragonSpawn:
Skills:
# no name -> rig owned by the mob (mm_<uuid>)
- matspawn{model=dragon;scale=2;anim=idle} @origin
DragonRoar:
Skills:
- matplay{anim=roar} @self
- delay 40
- matplay{anim=idle} @selfNaming explicitly (placeholder) when you want several rigs or external control:
- matspawn{model=dragon;name=boss_<caster.uuid>} @origin
- matplay{name=boss_<caster.uuid>;anim=fly} @selfWhen PlaceholderAPI is installed, the mat expansion is registered:
| Placeholder | Returns |
|---|---|
%mat_count% |
Number of spawned rigs. |
%mat_animation_<name>% |
Current animation of the rig, or none. |
%mat_playing_<name>% |
true / false. |
%mat_cache_<name>% |
Cache the rig was spawned from. |
%mat_scale_<name>% |
The rig's uniform scale. |
Cache not foundwhen spawning: run/mat reloadafter adding the.bbmodel; the cache name is the file name without.bbmodel.- Rig is all stone: that's expected — assign blocks with
/mat edit(paint mode) or/mat edit <cache> <part> <material>. - Animation does nothing / wrong rotations: make sure cubes are inside groups (bones) with correct
pivot points, and that the animation has keyframes on those bones. Re-save, delete the previous cache and
/mat reload. - Animation name not found: the name in
/mat playmust match the animation name in Blockbench exactly. - No sound: the sound must be a valid Minecraft sound name (resource-pack sounds need the pack installed
on clients). Both
ambient.caveandminecraft:ambient.caveare accepted. - Rig stutters far away: set
cull-distanceto skip rendering for distant rigs (time keeps advancing, so it stays in sync). - Model too big/small: 16 Blockbench units = 1 block. Re-scale in Blockbench, or spawn with a
[scale].