AnimationBehaviorDefinition
AnimationBehaviorDefinition manages behavior pack animation files (BP/animations/*.json), which define animation timelines and scripted events.
Class Signature
class AnimationBehaviorDefinition implements IDefinition {
// Properties
id?: string;
readonly shortId?: string;
readonly isLoaded: boolean;
readonly file?: IFile;
data?: IAnimationBehaviorWrapper;
// Timeline methods
getAllTimeline(): IAnimationBehaviorTimelineWrapper[];
// Loading and persistence
static async ensureOnFile(file: IFile, handler?): Promise<AnimationBehaviorDefinition>;
async load(): Promise<void>;
persist(): boolean;
// Utilities
getFormatVersion(): number[] | undefined;
async getFormatVersionIsCurrent(): Promise<boolean>;
setBehaviorPackFormatVersion(version: string): void;
}
Loading Animation Behaviors
import { AnimationBehaviorDefinition } from 'minecraft-creator-tools';
// Load from file
const animBehavior = await AnimationBehaviorDefinition.ensureOnFile(file);
console.log('Animation ID:', animBehavior.id);
console.log('Format version:', animBehavior.getFormatVersion());
Working with Timelines
Behavior animations contain timeline events that execute commands or scripts at specific timestamps:// Get all timelines
const timelines = animBehavior.getAllTimeline();
for (const timeline of timelines) {
console.log('Animation:', timeline.animationId);
console.log('Timestamp:', timeline.timestamp);
console.log('Commands:', timeline.timeline);
}
Animation Behavior JSON Structure
{
"format_version": "1.12.0",
"animations": {
"animation.custom.attack": {
"animation_length": 1.0,
"loop": false,
"timeline": {
"0.0": [
"/playsound mob.zombie.attack @a ~ ~ ~ 1.0 1.0"
],
"0.5": [
"/particle minecraft:critical_hit_emitter ~ ~1 ~",
"@s custom:deal_damage"
],
"1.0": [
"@s custom:reset_attack"
]
}
},
"animation.custom.spawn": {
"animation_length": 2.0,
"loop": false,
"timeline": {
"0.0": [
"/particle minecraft:huge_explosion_emitter ~ ~ ~"
],
"2.0": [
"@s custom:spawn_complete"
]
}
}
}
}
Creating Behavior Animations
// Ensure data initialized
animBehavior._ensureDataInitialized();
if (animBehavior.data?.animations) {
// Add animation
animBehavior.data.animations['animation.custom.special_move'] = {
animation_length: 3.0,
loop: false,
timeline: {
'0.0': [
'/playsound custom.special_charge @a ~ ~ ~ 1.0 1.0'
],
'1.5': [
'/particle minecraft:explosion_emitter ~ ~1 ~',
'@s custom:execute_special'
],
'3.0': [
'@s custom:special_complete'
]
}
};
}
// Save
animBehavior.persist();
AnimationResourceDefinition
AnimationResourceDefinition manages resource pack animation files (RP/animations/*.json), which define visual bone transformations and keyframes.
Class Signature
class AnimationResourceDefinition implements IDefinition {
// Properties
id?: string;
readonly shortId?: string;
readonly isLoaded: boolean;
readonly file?: IFile;
readonly data?: IResourceAnimationWrapper;
readonly animations?: { [name: string]: IAnimationResource };
readonly idList?: Set<string>;
// Animation management
ensureAnimation(name: string): IAnimationResource;
// Loading and persistence
static async ensureOnFile(file: IFile, handler?): Promise<AnimationResourceDefinition>;
async load(): Promise<void>;
persist(): boolean;
// Utilities
getFormatVersion(): number[] | undefined;
async getFormatVersionIsCurrent(): Promise<boolean>;
setResourcePackFormatVersion(version: string): void;
ensureDefault(): IResourceAnimationWrapper;
}
Loading Animation Resources
import { AnimationResourceDefinition } from 'minecraft-creator-tools';
// Load from file
const animResource = await AnimationResourceDefinition.ensureOnFile(file);
console.log('Animation ID:', animResource.id);
// Get all animation IDs
const animIds = animResource.idList;
if (animIds) {
for (const id of animIds) {
console.log('Animation:', id);
}
}
// Get animations object
const animations = animResource.animations;
if (animations) {
for (const name in animations) {
const anim = animations[name];
console.log('Animation:', name);
console.log('Loop:', anim.loop);
console.log('Animation length:', anim.animation_length);
}
}
Creating Animations
// Ensure animation exists
const walkAnim = animResource.ensureAnimation('animation.custom.walk');
// Configure animation
walkAnim.loop = true;
walkAnim.animation_length = 1.0;
walkAnim.bones = {
'leftleg': {
rotation: {
'0.0': [0, 0, 0],
'0.5': [45, 0, 0],
'1.0': [0, 0, 0]
}
},
'rightleg': {
rotation: {
'0.0': [0, 0, 0],
'0.5': [-45, 0, 0],
'1.0': [0, 0, 0]
}
}
};
// Save
animResource.persist();
Animation Resource JSON Structure
{
"format_version": "1.12.0",
"animations": {
"animation.custom.walk": {
"loop": true,
"animation_length": 1.0,
"bones": {
"leftleg": {
"rotation": {
"0.0": [0, 0, 0],
"0.5": [45, 0, 0],
"1.0": [0, 0, 0]
}
},
"rightleg": {
"rotation": {
"0.0": [0, 0, 0],
"0.5": [-45, 0, 0],
"1.0": [0, 0, 0]
}
},
"body": {
"position": {
"0.0": [0, 0, 0],
"0.25": [0, 0.5, 0],
"0.5": [0, 0, 0],
"0.75": [0, 0.5, 0],
"1.0": [0, 0, 0]
},
"rotation": {
"0.0": [0, 0, 0],
"0.5": [0, 5, 0],
"1.0": [0, 0, 0]
}
},
"head": {
"rotation": {
"0.0": [0, 0, 0],
"0.5": [0, -5, 0],
"1.0": [0, 0, 0]
}
}
}
},
"animation.custom.attack": {
"loop": false,
"animation_length": 0.5,
"bones": {
"rightarm": {
"rotation": {
"0.0": [0, 0, 0],
"0.25": [-90, 0, 0],
"0.5": [0, 0, 0]
}
}
}
}
}
}
Working with Bone Transformations
// Create complex animation
const attackAnim = animResource.ensureAnimation('animation.custom.powerful_attack');
attackAnim.loop = false;
attackAnim.animation_length = 1.5;
attackAnim.bones = {
'rightarm': {
rotation: {
'0.0': [0, 0, 0],
'0.5': [-120, 0, 45], // Wind up
'0.7': [-120, 0, 45], // Hold
'0.8': [45, 0, -45], // Swing
'1.5': [0, 0, 0] // Return
},
position: {
'0.5': [0, 2, 0],
'0.8': [0, -1, 2],
'1.5': [0, 0, 0]
}
},
'body': {
rotation: {
'0.0': [0, 0, 0],
'0.5': [0, -30, 0],
'0.8': [0, 30, 0],
'1.5': [0, 0, 0]
}
},
'head': {
rotation: {
'0.0': [0, 0, 0],
'0.5': [-10, 30, 0],
'0.8': [10, -30, 0],
'1.5': [0, 0, 0]
}
}
};
animResource.persist();
Complete Example: Creating Full Animation
import {
AnimationBehaviorDefinition,
AnimationResourceDefinition
} from 'minecraft-creator-tools';
// Create behavior animation (timeline/events)
const animBehavior = await AnimationBehaviorDefinition.ensureOnFile(behaviorFile);
animBehavior.setBehaviorPackFormatVersion('1.20.0');
animBehavior._ensureDataInitialized();
if (animBehavior.data?.animations) {
animBehavior.data.animations['animation.dragon.fire_breath'] = {
animation_length: 3.0,
loop: false,
timeline: {
'0.0': [
'/playsound mob.enderdragon.growl @a ~ ~ ~ 2.0 0.8'
],
'1.0': [
'/particle minecraft:dragon_breath_fire ~ ~2 ~3 1 1 1 0.1 100'
],
'1.5': [
'@s custom:deal_fire_damage'
],
'3.0': [
'@s custom:breath_complete'
]
}
};
}
animBehavior.persist();
// Create resource animation (visual keyframes)
const animResource = await AnimationResourceDefinition.ensureOnFile(resourceFile);
animResource.setResourcePackFormatVersion('1.20.0');
const breathAnim = animResource.ensureAnimation('animation.dragon.fire_breath');
breathAnim.loop = false;
breathAnim.animation_length = 3.0;
breathAnim.bones = {
'head': {
rotation: {
'0.0': [0, 0, 0],
'0.5': [-20, 0, 0], // Head tilts back
'1.0': [-10, 0, 0], // Head forward
'2.0': [-10, 0, 0], // Hold
'3.0': [0, 0, 0] // Return
}
},
'jaw': {
rotation: {
'0.5': [0, 0, 0],
'1.0': [30, 0, 0], // Mouth opens
'2.0': [30, 0, 0], // Hold open
'2.5': [0, 0, 0] // Close
}
},
'neck': {
rotation: {
'0.0': [0, 0, 0],
'0.5': [-15, 0, 0],
'1.0': [10, 0, 0],
'3.0': [0, 0, 0]
}
},
'body': {
position: {
'1.0': [0, 0, 0],
'1.5': [0, 0, -0.5], // Recoil from breath
'2.0': [0, 0, 0]
}
}
};
animResource.persist();
console.log('Fire breath animation created!');
Animation Properties
Common Animation Properties
interface IAnimationResource {
loop?: boolean; // Loop animation
animation_length?: number; // Duration in seconds
override_previous_animation?: boolean;
blend_weight?: number;
anim_time_update?: string; // Molang expression
bones?: { [boneName: string]: IBoneAnimation };
particle_effects?: any; // Particle timeline
sound_effects?: any; // Sound timeline
timeline?: any; // Generic timeline
}
interface IBoneAnimation {
rotation?: { [timestamp: string]: number[] | string };
position?: { [timestamp: string]: number[] | string };
scale?: { [timestamp: string]: number[] | string };
relative_to?: {
rotation?: string;
};
}
Keyframe Formats
// Numeric array
rotation: {
'0.0': [0, 0, 0],
'1.0': [90, 0, 0]
}
// Molang expression
rotation: {
'0.0': 'math.sin(query.anim_time * 180)',
'1.0': '0'
}
// Lerp keyframes
rotation: {
'0.0': {
pre: [0, 0, 0],
post: [0, 0, 0],
lerp_mode: 'linear'
}
}