Examples.md - gawrmonster/CustomHitboxLib GitHub Wiki
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,
"positioner": {
"type": "rotating",
"offset": [0, 0, 0]
},
"collision": true,
"pushable": true
}
]
}
Rotating Parts (Body Yaw)
Parts that follow the entity's body rotation. Useful for limbs, wings, or armor that should swing when the entity turns.
File: data/mymod/custom_parts/spider_legs.json
{
"id": "minecraft:spider",
"parts": [
{
"name": "left_leg_front",
"width": 0.3,
"height": 0.3,
"positioner": {
"type": "rotating",
"offset": [1.0, 0.5, 0.5]
}
},
{
"name": "right_leg_front",
"width": 0.3,
"height": 0.3,
"positioner": {
"type": "rotating",
"offset": [-1.0, 0.5, 0.5]
}
}
]
}
Rotating Parts (Head Yaw)
Parts that follow the entity's head rotation. Useful for accessories that should track where the entity is looking.
File: data/mymod/custom_parts/head_accessory.json
{
"id": "minecraft:zombie",
"parts": [
{
"name": "head_lantern",
"width": 0.3,
"height": 0.3,
"positioner": {
"type": "rotating_head",
"offset": [0.4, 0.2, 0.0]
}
}
]
}
Pose-Specific Parts (Datapack)
Define different parts for different entity poses. Parts automatically switch when the entity changes pose.
File: data/mymod/custom_parts/player_armor.json
[
{
"id": "minecraft:player",
"pose": "standing",
"parts": [
{
"name": "turtle_shell",
"width": 1.5,
"height": 1.5,
"offset": [0, 0, 0],
"pickable": true,
"pushable": false,
"collision": true,
"suffocate": false
}
]
},
{
"id": "minecraft:player",
"pose": "crouching",
"parts": [
{
"name": "turtle_shell",
"width": 1.5,
"height": 0.5,
"offset": [0, 0, 0],
"pickable": true,
"pushable": false,
"collision": true,
"suffocate": false
}
]
}
]
When the player stands up, the shell is 1.5 blocks tall. When crouching, it shrinks to 0.5 blocks tall. Missing pose variants automatically fall back to the "standing" definition.
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);
Built-in Rotating Positioner
A part that rotates with the entity using PartPositioners.rotating(). The offset is applied relative to yBodyRot, so the part swings with the body:
// 2 blocks behind the entity, rotates with body yaw
MultipartHelper.addPart(entity, "back_part", 2.0F, 2.0F,
PartPositioners.rotating(0, 0, -2), true, true, true, false);
Built-in Head-Rotating Positioner
A part that rotates with the entity's head using PartPositioners.rotatingHead(). The offset is applied relative to yHeadRot, so the part follows where the entity is looking:
// 0.4 blocks to the right of the head, rotates with head yaw
MultipartHelper.addPart(entity, "head_accessory", 0.3F, 0.3F,
PartPositioners.rotatingHead(0.4, 0.2, 0), true, false, false, false);
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 from all poses
mp.removeCustomPart("shield");
// Remove a part from a specific pose only
mp.removeCustomPart("turtle_shell", "crouching");
}
Pose-Specific Parts (Java API)
Add parts that only appear when the entity is in a specific pose:
if (entity instanceof ICustomMultipart mp) {
// Part only visible while standing
mp.addCustomPart("cape", PartDefinition.of("cape", 1.0F, 1.5F,
PartPositioners.atOffset(0, 1.0, 0.3), true, false, false, false), "standing");
// Part only visible while crouching
mp.addCustomPart("turtle_shell", PartDefinition.of("turtle_shell", 1.5F, 0.5F,
PartPositioners.atOffset(0, 0.5, 0), true, false, true, false), "crouching");
}
Parts automatically switch when the entity changes pose. Missing pose variants fall back to "standing".
Controlling Main Hitbox Behavior
if (entity instanceof ICustomMultipart mp) {
// Make main hitbox intangible but visible
mp.setMainHitboxCollision(false);
mp.setMainHitboxPushable(false);
mp.setMainHitboxPickable(true);
}