Skip to content

OrangeUtan/mcanitexgen

Repository files navigation

Code style: black

Animated-texture generator for Minecraft

Anitexgen is a generator for ".mcmeta" files that Minecraft uses to animate textures.

It allows you to write texture animations in Python instead of json. Using a proper programming language enables you to create much more complex animations, like this model that uses 3 animated textures to create a moving dog.

Installation

pip install mcanitexgen

Usage

Generate .mcmeta files for all animations in an animation file

$ mcanitexgen generate <animation_file>
    -o, --out       The output directory of the generated files
    -m, --minify    Minify generated files
    -i, --indent    Indentation used when generating files
    --dry           Dry run. Don't generate any files

Create gifs for all animations in an animation file

$ mcanitexgen gif <animation_file>
    -o, --out       The output directory of the generated files

Getting started

Create a simple animation

We are going to create this blinking Steve:

First we have to create the different states of the animation. I created a simple steve.png file:

Top to Bottom: Looking normal, blinking, wink with right eye, wink with left eye.
Now we can create the animation file steve.animation .py that uses these states to create an animation:

from mcanitexgen.animation import animation, TextureAnimation, State, Sequence

@animation("steve.png")
class Steve(TextureAnimation):
  NORMAL = State(0)  # Look normal
  BLINK = State(1)
  WINK_RIGHT = State(2)  # Wink with right eye
  WINK_LEFT = State(3)  # Wink with left eye

  # Look normal and blink shortly
  look_and_blink = Sequence(NORMAL(duration=60), BLINK(duration=2))

  # The main Sequence used to create the animation
  main = Sequence(
    3 * look_and_blink,  # Play "look_and_blink" Sequence 3 times
    NORMAL(duration=60),
    WINK_LEFT(duration=30),
    look_and_blink,
    NORMAL(duration=60),
    WINK_RIGHT(duration=30),
  )

Files overview:

resourcepack
  ⠇
  textures
    └╴ item
       ├╴steve.png
       └╴steve.animation.py

Passing the animation file to Anitexgen will create a steve.png.mcmeta file:

$ mcanitexgen generate steve.animation.py
steve.png.mcmeta
{
  "animation": {
      "interpolate": false,
      "frametime": 1,
      "frames": [
        {"index": 0, "time": 60},
        {"index": 1, "time": 2},
        {"index": 0, "time": 60},
        {"index": 1, "time": 2},
        {"index": 0, "time": 60},
        {"index": 1, "time": 2},
        {"index": 0, "time": 60},
        {"index": 3, "time": 30},
        {"index": 0, "time": 60},
        {"index": 1, "time": 2},
        {"index": 0, "time": 60},
        {"index": 2, "time": 30}
      ]
  }
}
resourcepack
  ⠇
  textures
    └╴ item
       ├╴ steve.png
       ├╴ steve.animation.py
       └╴ steve.png.mcmeta

Beet integration

Mcanitexgen can be used as a beet plugin. Here is an example beet project using mcanitexgen:

beet.json
resourcepack
  └╴assets
    └╴minecraft
      └╴textures
        └╴item
          ├╴stone_sword.png
          └╴swords.animation.py

swords.animation.py

from mcanitexgen.animation import animation, TextureAnimation, State, Sequence

@animation("minecraft:item/stone_sword.png")
class StoneSword(TextureAnimation):
  IDLE1 = State(0)
  IDLE2 = State(1)
  IDLE3 = State(2)

  idle = Sequence(
    IDLE1(weight=1),
    IDLE2(weight=1),
    IDLE3(weight=1)
  )

  main = Sequence(
    idle(duration=100)
  )

beet.json

{
  "output": "build",
  "resource_pack": {
    "load": ["resourcepack"]
  },
  "pipeline": [
      "mcanitexgen.integration.beet"
  ],
  "meta": {
      "mcanitexgen": {
        "load": ["resourcepack/**/*.animation.py"]
      }
  }
}

Running beet build generates the .mcmeta file:

beet.json
resourcepack
  └╴...
build
  └╴assets
    └╴minecraft
      └╴textures
        └╴item
          ├╴stone_sword.png
          └╴stone_sword.png.mcmeta

Contributing

Contributions are welcome. Make sure to first open an issue discussing the problem or the new feature before creating a pull request. The project uses poetry. Setup dev environment with invoke:

$ invoke install

Run tests:

$ invoke test

The project follows black codestyle. Import statements are sorted with isort. Code formatting and type checking is enforced using pre-commit