Skip to content

Creating Cursor Textures

Requirements:

  • Minimum Size: 8x8
  • Maximum Size: 128x128
  • Must be divisible by: 8
  • Must be square
  • File name must correspond to a cursor key.
  • Format: .png

Recommendations:

  • Use 2n size when applying 1x scale or some other custom scale.
  • Use 16x16 with 1:1 pixel density for optimal results with auto scale (may vary across platforms).

Example

Creating a 32x32 texture for the Default cursor which has the default key:

demo-filename

demo-texture

Animated Textures

  1. Choose a single frame size (must be within spec) and create the first sprite used as fallback.

    In this example, I chose to animate the Default cursor with a size of 32x32:
    demo-texture

  2. Add frames by stacking them vertically (top to bottom).

    • All frames must be the same size.
    • The total image height must be divisible by the chosen frame size.
    • Frames are indexed from top to bottom, starting at 0.

    Here, a second frame was added, making the total height 64 pixels:
    demo-animation-texture

  3. Register the texture as animated by creating a <key>.png.mcmeta file within the same directory. This is where you can specify animation data.

    demo-animation-filename

    default.png.mcmeta: demo-animation-data

Animation Data

The existence of the <key>.png.mcmeta file tells Minecraft Cursor that <key>.png is an animated texture. It also specifies the animation data.

It is in JSON format and can be opened with any text editor, preferably code editors like Notepad++ to aid with formatting.

Key Type Default Description
mode optional String loop

Determines the animation mode.

Animation Modes
Name Description
loop Repeats in a continuous loop. The default mode.
loop_reverse Repeats in a continuous loop but in reverse.
forwards Plays the animation and stops at the last frame.
reverse Plays the animation in reverse and stops at the first frame.
oscillate Loops back and forth continuously.
random Randomly selects frames in a loop. Does not repeat the same frame twice.
random_cycle Randomly selects frames in a loop, cycling through all frames before repeating.
frametime optional int 1 The amount of ticks per frame. Minimum value: 1.
frames optional Array null

Determines the order and/or time of the frames to be played.

  • If this is not specified, frames will be auto-generated from top to bottom with the given frametime.
  • Array elements can either be an int or a Frame object.
int
Specifies the index of the frame according to the sprite sheet.
Frame
Key Type Description
index required int Specifies the index of the frame according to the sprite sheet.
time required int The frametime of the frame. Minimum value: 1.

Examples

<key>.png.mcmeta
json
{
  "mode": "loop",
  "frametime": 4,
  "frames": [
    3,
    { "index": 1, "time": 6 },
    0,
    5,
    { "index": 2, "time": 3 }
  ]
}
  • Animation loops continuously.
  • Default frame duration is 4 ticks.
  • Frames played in this order: 3 → 1 → 0 → 5 → 2.
  • Frame 1 plays for 6 ticks (overridden).
  • Frame 2 plays for 3 ticks (overridden).
  • All other frames play for 4 ticks (default).

<key>.png.mcmeta
json
{
  "frametime": 2
}
  • Frames are played in order from top to bottom.
  • Each frame lasts two ticks.
  • Animation loops by default.

Limitations

  • To maximize mod compatibility, interpolation is not feasible as the cursors are not being custom rendered. Minecraft Cursor simply changes the look of the native cursor, with each frame essentially being its own cursor.

    The animation may pause or slow down when the game does.

Practical Examples

For more examples, you can take a look at the built-in textures of Minecraft Cursor in the source files.

Released under the CC0-1.0 License.