Skip to content

Examples.md

gawrmonster edited this page Jul 22, 2026 · 1 revision

Examples

Datapack Examples

Zombie with Wings

Adds two wing parts that extend outward from the zombie's body.

File: data/mymod/custom_parts/zombie_wings.json

{
  "id": "minecraft:zombie",
  "main_hitbox_pickable": true,
  "main_hitbox_pushable": true,
  "main_hitbox_collision": true,
  "parts": [
    {
      "name": "left_wing",
      "width": 1.5,
      "height": 0.5,
      "offset": [1.0, 1.0, -0.2],
      "pickable": true,
      "pushable": false,
      "collision": false,
      "suffocate": false
    },
    {
      "name": "right_wing",
      "width": 1.5,
      "height": 0.5,
      "offset": [-1.0, 1.50, -0.2],
      "pickable": true,
      "pushable": false,
      "collision": false,
      "suffocate": false
    }
  ]
}

Skeleton with Shield

Adds a shield part in front of the skeleton that blocks player movement.

File: data/mymod/custom_parts/skeleton_shield.json

{
  "id": "minecraft:skeleton",
  "main_hitbox_collision": true,
  "parts": [
    {
      "name": "shield",
      "width": 1.0,
      "height": 1.8,
      "offset": [0, 0, -0.5],
      "pickable": true,
      "pushable": true,
      "collision": true,
      "suffocate": false
    }
  ]
}

Multiple Entities in One File

Use an array to define parts for multiple entity types.

File: data/mymod/custom_parts/multi_entity.json

[
  {
    "id": "minecraft:zombie",
    "parts": [
      { "name": "left_wing", "width": 1.5, "height": 0.5, "offset": [1.0, 1.0, 0] }
    ]
  },
  {
    "id": "minecraft:skeleton",
    "parts": [
      { "name": "shield", "width": 1.0, "height": 1.8, "offset": [0, 0, -0.5], "collision": true }
    ]
  },
  {
    "id": "minecraft:creeper",
    "parts": [
      { "name": "antenna", "width": 0.3, "height": 0.5, "offset": [0, 2.0, 0] }
    ]
  }
]

NBT-Based Selector

Only apply parts when the entity has specific NBT data.

File: data/mymod/custom_parts/heavy_zombie.json

{
  "selector": {
    "id": "minecraft:zombie",
    "nbt": "Health:20.0"
  },
  "parts": [
    {
      "name": "heavy_armor",
      "width": 1.2,
      "height": 2.2,
      "offset": [0, 0, 0],
      "collision": true,
      "pushable": true
    }
  ]
}

Java API Examples

Adding Parts on Entity Spawn

Listen for entity join and add parts:

@SubscribeEvent
public void onEntityJoin(EntityJoinLevelEvent event) {
    Entity entity = event.getEntity();
    if (entity instanceof Zombie zombie && zombie instanceof ICustomMultipart mp && !mp.hasCustomParts()) {
        MultipartHelper.addPart(zombie, "left_wing", 1.5F, 0.5F,
            PartPositioners.atOffset(1.0, 1.0, -0.2), true, false, false, false);
        MultipartHelper.addPart(zombie, "right_wing", 1.5F, 0.5F,
            PartPositioners.atOffset(-1.0, 1.0, -0.2), true, false, false, false);
    }
}

Custom Positioner (Facing Direction)

A part that always appears 0.5 blocks in front of the entity's eyes:

PartPositioner facePositioner = (entity, partialTick) -> {
    float yaw = entity.getYRot();
    float yawRad = (float) Math.toRadians(yaw);
    double forwardX = -Mth.sin(yawRad);
    double forwardZ = Mth.cos(yawRad);
    double dist = 0.5D;
    return new Vec3(
        entity.getX() + forwardX * dist,
        entity.getY() + entity.getEyeHeight(),
        entity.getZ() + forwardZ * dist
    );
};

MultipartHelper.addPart(entity, "face", 0.3F, 0.3F, facePositioner);

Custom Positioner (Orbiting Part)

A part that orbits around the entity's head:

PartPositioner orbitPositioner = (entity, partialTick) -> {
    float time = (float)(System.currentTimeMillis() % 4000L) / 4000.0F * 360.0F;
    double radians = Math.toRadians(time);
    return new Vec3(
        entity.getX() + Math.cos(radians) * 1.5,
        entity.getY() + entity.getEyeHeight() + 0.5,
        entity.getZ() + Math.sin(radians) * 1.5
    );
};

MultipartHelper.addPart(entity, "orbit", 0.2F, 0.2F, orbitPositioner);

Disabling Main Hitbox

Use custom parts as the only collision for an entity:

if (entity instanceof ICustomMultipart mp) {
    MultipartHelper.addPart(entity, "body", 0.6F, 1.8F,
        PartPositioners.atOffset(0, 0, 0), true, true, true, false);
    mp.setMainHitboxCollision(false);
    mp.setMainHitboxPickable(false);
}

Dynamic Part Management

Add and remove parts at runtime:

if (entity instanceof ICustomMultipart mp) {
    // Add a part
    mp.addCustomPart("shield", PartDefinition.of("shield", 1.0F, 1.8F,
        PartPositioners.atOffset(0, 0, -0.5), true, true, true));

    // Check if entity has parts
    if (mp.hasCustomParts()) {
        PartEntity<?>[] parts = mp.getCustomParts();
        // ...
    }

    // Remove a part
    mp.removeCustomPart("shield");
}

Controlling Main Hitbox Behavior

if (entity instanceof ICustomMultipart mp) {
    // Make main hitbox intangible but visible
    mp.setMainHitboxCollision(false);
    mp.setMainHitboxPushable(false);
    mp.setMainHitboxPickable(true);
}