Custom Animations

File location

/assets/minecraft/optifine/anim/**/*.properties

Custom Animations allows all textures to be animated, regardless of type and purpose.

Important

For block and item textures, including CTM and CIT replacements, continue using Mojang's mcmeta method instead.

In Minecraft 1.5, Mojang added the ability to animate any block or item texture (originally a feature provided by MCPatcher). However, there is yet no way to animate other textures like mob skins or GUIs. OptiFine fills the gap enabling any rectangular area of any non-block or item texture to be animated.

This includes even textures specific to other OptiFine features such as random mob skins or skyboxes.

To build an animation, first choose a texture and determine the X and Y coordinates, and width and height of the area to animate. Create the animation as a vertical strip of frames.

The width should be the same as the width of the area to animate. The height should be a multiple of the animation area height.

Multiple non-overlapping parts of the same texture can be animated by using the same to value with different from, x, y, w, and h values. They can even have independent timing and frame order information.

Emissive animation is also possible, see Emissive Textures.

Properties

Note

duration, interpolate, skip, tile, duration are optional, rest are required

from

Values: String: File path
Required

Path to source texture of the animation to display.

to

Values: String: File path
Required

Path to destination texture to replace and animate.

x, y

Values: Positive integers
Required

Coordinates of top-left corner of the destination texture to animate to. Normally, this is 0, 0.

w, h

Values: Positive integer
Required

Width and height of an individual animation frame.

duration

Values: Positive integer
Optional

Duration of each individual frame, in ticks. For reference, there are 20 ticks in 1 second.

interpolate

Values: Boolean
Optional

Whether to interpolate between each animated frame.

This furnace has an interpolated animation; focus on the fire inside.

skip

Values: Positive integer
Optional

What frame number to skip/ignore during animation.

Important

Frame numbers start at 0, not 1.

tile.N

Values: Positive integer, N is positive integer
Optional

What frame number (starting from 0) to display at the N-th tick. N can be greater than the number of frames.

duration.N

Values: Positive integer, N is positive integer
Optional

Duration in ticks to display tile N for. This only applies to tiles for which a tile.N is declared.

Example

Rainbow squid

from=./glow_squid_glow.png
to=textures/entity/squid/glow_squid.png
x=0
y=0
w=64
h=32
duration=1
interpolate=true
skip=2

Note

See the Syntax document for how to specify paths to texture files.

This creates an interpolating animation that plays each frame in order from top to bottom once for one tick (1/20th second) each and then loops infinitely.

Frame order and timing

Each custom animation may specify its animation speed and frame order. In the properties file, add a series of entries:

tile.X=Y
duration.X=Z

X starts at 0 and represents the order of animation frames based on tick. Y is the tile number in the animation frames, the first tile being 0, the second 1, etc. Z is the duration that frame should be displayed, in game ticks (1 tick = 1/20 second).

If omitted, duration is assumed to be the default frame duration, or 1 if not configured.

For example, suppose the animation file is 16px x 48px, at 3 frames. To make it run on a 5-frame cycle with a pause in the middle, the properties file might look like this:

tile.0=0
tile.1=1
tile.2=2
duration.2=5
tile.3=1
tile.4=0

The animation happens in this order:

  1. Frame 0: Display animation tile 0 for 1 tick (default duration).

  2. Frame 1: Display animation tile 1 for 1 tick (default duration).

  3. Frame 2: Display animation tile 2 for 5 ticks (duration=5).

  4. Frame 3: Display animation tile 1 for 1 tick (default duration).

  5. Frame 4: Display animation tile 0 for 1 tick (default duration).

  6. Go back to frame 0.

Total: 5 frames over 9 ticks.

JSON schema

Note

Although this page is .properties based, it can be mapped to JSON.

{
	"$schema": "http://json-schema.org/draft/2020-12/schema",
	"$id": "https://gitlab.com/whoatemybutter/optifinedocs/-/blob/master/schemas/custom_animations.schema.json",
	"title": "Custom Animations",
	"description": "Custom Animations allows all textures to be animated, like GUIs and entities.",
	"type": "object",
	"properties": {
		"from": {
			"$ref": "common.schema.json#/$defs/resource",
			"description": "Path to source texture of the animation to display."
		},
		"to": {
			"$ref": "common.schema.json#/$defs/resource",
			"description": "Path to destination texture to replace and animate."
		},
		"x": {
			"type": "integer",
			"minimum": 0,
			"description": "X coordinate of the top-left corner of the destination texture to animate to."
		},
		"y": {
			"type": "integer",
			"minimum": 0,
			"description": "Y coordinate of the top-left corner of the destination texture to animate to."
		},
		"w": {
			"type": "integer",
			"minimum": 0,
			"description": "Width of an individual animation frame."
		},
		"h": {
			"type": "integer",
			"minimum": 0,
			"description": "Height of an individual animation frame."
		},
		"duration": {
			"type": "integer",
			"minimum": 0,
			"description": "Duration of each individual frame, in ticks."
		},
		"interpolate": {
			"type": "boolean",
			"description": "Whether to unterpolate between each animated frame."
		},
		"skip": {
			"type": "integer",
			"minimum": 0,
			"description": "What frame number to skip/ignore during animation."
		}
	},
	"patternProperties": {
		"^tile\\.\\d+$": {
			"type": "integer",
			"minimum": 0,
			"description": "What frame number to display at the n-th tick."
		},
		"^duration\\.\\d+$": {
			"type": "integer",
			"minimum": 0,
			"description": "Duration in ticks to display the tile for."
		}
	},
	"additionalProperties": false,
	"required": [
		"from",
		"to",
		"x",
		"y",
		"w",
		"h"
	]
}

Assumes the latest OptiFine version.
Updated to commit dc7b4aca.

Last update: 2024 March 13