Create a Custom Entity

Similarly to custom items, we can also make custom entities with many similar mechanics to the vanilla entities in the game. These entities can be incredibly powerful allowing you to make your own animals which can be bred and tamed or an aggressive mob that attacks anything it sees.

Here we will make a ghost entity which will float, attack the player and drop our ectoplasm item on death.

Concept: Just like items, entities are made up of two parts:

  • The visuals (model, texture, animations, name, sounds).
  • The behaviors (movement, health, attacks, interactions).

Unlike items, entities typically require two main definition files: a server file (in the Behavior Pack) for behavior and a client file (in the Resource Pack) for visuals.

First, we will cover how to create an entity & define its behavior. Next, we will look at how to add the visuals.

Ghost entity view in Minecraft

Entity Behavior (Server File)

Like with items, we need a file to tell our entity how to behave, linking an identifier to components that define its actions and properties. This "server" entity file resides in the Behavior Pack (BP).

Create an entities folder inside your BP folder if it doesn't exist. Inside BP/entities/, create a new file. We'll call ours ghost.se.json.

The .se suffix stands for "server entity". While not required by the game, it's a recommended naming convention from the community Style Guide for clarity.

Here's the basic structure:

BP/entities/ghost.se.json
  {        "format_version": "1.21.0",        "minecraft:entity": {            "description": { ... },            "components": { ... }        }    }  

Similar to the item file, we have "format_version" and "minecraft:entity". The key information goes inside "minecraft:entity".

Entities have slightly more in their "description" block:

ghost.se.json / description
  "description": {        "identifier": "wiki:ghost",        "is_summonable": true,        "is_spawnable": true    }  
  • "identifier": Same purpose as items - uniquely identifies this entity (wiki:ghost).
  • "is_summonable": Allows the entity to be created using the /summon command.
  • "is_spawnable": Allows the entity to be spawned using a spawn egg or potentially through world generation (with spawn rules).

We recommend keeping both is_summonable and is_spawnable as true during development for easier testing.

Components

Entities have many more potential behaviors than items, so they use a wider variety of components. We'll group the components for our ghost into categories. For a deeper dive, see the Entity Components Guide.

Stat Components

These components define core attributes and properties common to most entities.

ghost.se.json / components (stats)
  "minecraft:type_family": {        "family": ["ghost", "monster"]    },    "minecraft:health": {        "value": 20,        "max": 20    },    "minecraft:attack": {        "damage": 3    },    "minecraft:movement": {        "value": 0.2    },    "minecraft:collision_box": {        "width": 0.8,        "height": 1.8    },    "minecraft:loot": {        "table": "loot_tables/entities/ghost.json"    },  
  • minecraft:type_family: Assigns tags for grouping (e.g., "monster", "undead", "ghost"). Useful for targeting commands or behaviors.
  • minecraft:health: Sets current and maximum health.
  • minecraft:attack: Defines base attack damage.
  • minecraft:movement: Sets base movement speed (blocks per second).
  • minecraft:collision_box: Defines the physical size for collisions.
  • minecraft:loot: Points to a loot table file (which we'll create later) defining drops on death.

Movement Components

These components define *how* and *where* the entity can move.

ghost.se.json / components (movement)
  "minecraft:physics": {},    "minecraft:jump.static": {},    "minecraft:movement.basic": {},    "minecraft:navigation.walk": {        "can_walk": true,        "avoid_sun": true,        "can_pass_doors": true,        "can_open_doors": true    }  
  • minecraft:physics: Applies basic physics like gravity and collisions. (Note: Cannot be easily modified by events/component groups).
  • minecraft:jump.static: Allows the entity to jump up single blocks.
  • minecraft:movement.basic: Enables standard ground walking. Other options include .fly, .swim, .hover. We use basic movement but will make it *look* like floating using the model/animations later.
  • minecraft:navigation.walk: Defines pathfinding capabilities for walking entities. The properties here allow it to pathfind on the ground, avoid sun, and interact with doors. Other navigation types exist for flying/swimming.

Behavior Components

These components define the entity's AI - *what* it decides to do and *when*.

We want our ghost to wander idly, look around, notice and target the player, and attack. We use these behavior components:

ghost.se.json / components (behaviors - simple)
  "minecraft:behavior.random_stroll": {...},    "minecraft:behavior.random_look_around": {...},    "minecraft:behavior.look_at_player": {...},        "minecraft:behavior.hurt_by_target": {...},    "minecraft:behavior.nearest_attackable_target": {...},        "minecraft:behavior.delayed_attack": {...}  
  • minecraft:behavior.random_stroll: Makes the entity wander randomly.
  • minecraft:behavior.random_look_around / minecraft:behavior.look_at_player: Adds idle looking behavior.
  • minecraft:behavior.hurt_by_target: Makes the entity target whatever attacked it.
  • minecraft:behavior.nearest_attackable_target: Makes the entity proactively target specific nearby entities (like players).
  • minecraft:behavior.delayed_attack: Defines a melee attack with a wind-up/delay.

Each behavior has settings to fine-tune its actions, including priority:

ghost.se.json / components (behaviors - detailed)
  "minecraft:behavior.random_stroll": {        "priority": 6,        "speed_multiplier": 1    },    "minecraft:behavior.random_look_around": {        "priority": 7    },    "minecraft:behavior.look_at_player": {        "priority": 7,        "look_distance": 6,        "probability": 0.02    },    "minecraft:behavior.hurt_by_target": {        "priority": 1    },    "minecraft:behavior.nearest_attackable_target": {        "priority": 2,        "within_radius": 25,        "reselect_targets": true,        "entity_types": [            {                "filters": {                    "any_of": [                        {                            "test": "is_family",                            "subject": "other",                            "value": "player"                        }                    ]                },                "max_dist": 35            }        ]    },    "minecraft:behavior.delayed_attack": {        "priority": 0,        "attack_once": false,        "track_target": true,        "require_complete_path": false,        "random_stop_interval": 0,        "reach_multiplier": 1.5,        "speed_multiplier": 1,        "attack_duration": 0.75,        "hit_delay_pct": 0.5    }  
Priority

The "priority" field (lower number = higher priority) is crucial. When an entity decides what to do, it checks behaviors from lowest priority number upwards and performs the *first* one whose conditions are met.

Priority Matters! If a low-priority behavior (like wandering) has its conditions met and is checked before a high-priority behavior (like attacking), the entity might never attack! Ensure critical actions (attacking, fleeing) have lower priority numbers than idle actions (wandering, looking around).

Full Entity Server File

Combining all these components gives us our complete behavior definition file.

Show Full ghost.se.json
BP/entities/ghost.se.json
  {        "format_version": "1.21.0",        "minecraft:entity": {            "description": {                "identifier": "wiki:ghost",                "is_summonable": true,                "is_spawnable": true            },            "components": {                "minecraft:type_family": {                    "family": ["ghost", "monster"]                },                "minecraft:health": {                    "value": 20,                    "max": 20                },                "minecraft:attack": {                    "damage": 3                },                "minecraft:movement": {                    "value": 0.2                },                "minecraft:collision_box": {                    "width": 0.8,                    "height": 1.8                },                "minecraft:loot": {                    "table": "loot_tables/entities/ghost.json"                },                "minecraft:physics": {},                "minecraft:jump.static": {},                "minecraft:movement.basic": {},                "minecraft:navigation.walk": {                    "can_walk": true,                    "avoid_sun": true,                    "can_pass_doors": true,                    "can_open_doors": true                },                "minecraft:behavior.random_stroll": {                    "priority": 6,                    "speed_multiplier": 1                },                "minecraft:behavior.random_look_around": {                    "priority": 7                },                "minecraft:behavior.look_at_player": {                    "priority": 7,                    "look_distance": 6,                    "probability": 0.02                },                "minecraft:behavior.hurt_by_target": {                    "priority": 1                },                "minecraft:behavior.nearest_attackable_target": {                    "priority": 2,                    "within_radius": 25,                    "reselect_targets": true,                    "entity_types": [                        {                            "filters": {                                "any_of": [                                    {                                        "test": "is_family",                                        "subject": "other",                                        "value": "player"                                    }                                ]                            },                            "max_dist": 35                        }                    ]                },                "minecraft:behavior.delayed_attack": {                    "priority": 0,                    "attack_once": false,                    "track_target": true,                    "require_complete_path": false,                    "random_stop_interval": 0,                    "reach_multiplier": 1.5,                    "speed_multiplier": 1,                    "attack_duration": 0.75,                    "hit_delay_pct": 0.5                }            }        }    }  

Advanced States & Events: More complex entities use events and component groups to change behavior dynamically (e.g., a wolf switching from wild to tamed state). We're keeping it simple for now.

Test Behavior: If you load the world now and /summon wiki:ghost, you should see a shadow on the ground. The entity exists and *should* behave as defined (wander, target, attack you), but it's invisible because we haven't defined its visuals yet.

Next, we'll create the client-side resources to make our ghost visible.


Entity Resource (Client File)

Applying visuals to an entity is more involved than for items. We need to define its shape (model/geometry), skin (texture), and how it moves (animations). These are all linked together in the entity's client file within the Resource Pack (RP).

Create an entity folder inside your RP folder if it doesn't exist. Inside RP/entity/, create a file named ghost.ce.json (.ce for client entity).

Blockbench: Creating models, textures, and animations is typically done using a dedicated 3D editor like Blockbench, which can export the necessary .json and .png files. We'll assume you have these files for the tutorial, but the next guide section will cover using Blockbench.

Model (Geometry)

The entity's shape or "geometry" defines the cubes ("bones") that make up its visual form. This is stored in a .geo.json file.

Place your geometry file (e.g., ghost.geo.json) inside RP/models/entity/. Create these folders if needed.

Show Example ghost.geo.json
RP/models/entity/ghost.geo.json
  {        "format_version": "1.12.0",        "minecraft:geometry": [            {                "description": {                    "identifier": "geometry.ghost",                    "texture_width": 64,                    "texture_height": 64,                    "visible_bounds_width": 3,                    "visible_bounds_height": 3.5,                    "visible_bounds_offset": [0, 1.25, 0]                },                "bones": [                    { "name": "root", "pivot": [0, 3, 0] },                    {                        "name": "body",                        "parent": "root",                        "pivot": [0, 4.625, 0],                        "cubes": [                            {                                "origin": [-4, 3, -4],                                "size": [8, 13, 8],                                "uv": [0, 20]                            }                        ]                    },                    {                        "name": "leftArm",                        "parent": "body",                        "pivot": [4.6, 15.5, 0.5],                        "cubes": [                            {                                "origin": [4.1, 7, -1],                                "size": [3, 9, 3],                                "uv": [32, 32]                            }                        ]                    },                    {                        "name": "rightArm",                        "parent": "body",                        "pivot": [-4.5, 15.5, 0.5],                        "cubes": [                            {                                "origin": [-7.1, 7, -1],                                "size": [3, 9, 3],                                "uv": [32, 20]                            }                        ]                    },                    {                        "name": "head",                        "parent": "body",                        "pivot": [0, 16, 0],                        "cubes": [                            {                                "origin": [-5, 16, -5],                                "size": [10, 10, 10],                                "uv": [0, 0]                            }                        ]                    }                ]            }        ]    }  

The key piece of information we need from this file for later is the geometry's identifier, found under description.identifier (e.g., geometry.ghost).

Texture

The texture is a .png image file that wraps around the model, giving it color and detail.

Ghost Texture

Place your texture file (e.g., ghost.png) inside RP/textures/entity/.

Download Example Texture

Unlike items, we don't use item_texture.json for entity textures. Instead, we'll define a shortname reference directly in the entity's client file later.

Animations

Animations define how the entity's bones (cubes) move over time (e.g., walking, attacking). These are stored in .a.json files (or .animation.json).

Place your animation file(s) (e.g., ghost.a.json) inside RP/animations/.

Show Example ghost.a.json (Multiple Animations)
RP/animations/ghost.a.json
  {        "format_version": "1.8.0",        "animations": {            "animation.ghost.idle": {                "loop": true,                "animation_length": 3,                "bones": {                    "body": {                        "rotation": { "0.0": [10, 0, 0], "3.0": [10, 0, 0] },                        "position": {                            "0.0": [0, 0, 0],                            "1.5": [0, 1, 0],                            "3.0": [0, 0, 0]                        }                    },                    "leftArm": {                        "rotation": {                            "0.0": [-10, 0, 0],                            "1.5": [-5, 0, 0],                            "3.0": [-10, 0, 0]                        }                    },                    "rightArm": {                        "rotation": {                            "0.0": [-10, 0, 0],                            "1.5": [-5, 0, 0],                            "3.0": [-10, 0, 0]                        }                    },                    "head": {                        "rotation": {                            "0.0": [-7.5, 0, 0],                            "1.5": [-2.5, 0, 0],                            "3.0": [-7.5, 0, 0]                        }                    }                }            },            "animation.ghost.attack": {                "animation_length": 0.75,                "bones": {                    "body": {                        "rotation": {                            "0.0": [10, 0, 0],                            "0.2917": [10, 15, 0],                            "0.5": [22.5, -12.5, 0],                            "0.75": [10, 0, 0]                        },                        "position": {                            "0.0": [0, 0, 0],                            "0.2917": [0, 0, 3],                            "0.5": [0, 0, -3],                            "0.75": [0, 0, 0]                        }                    },                    "leftArm": {                        "rotation": { "0.0": [-10, 0, 0], "0.75": [-10, 0, 0] }                    },                    "rightArm": {                        "rotation": {                            "0.0": [-10, 0, 0],                            "0.2083": [-10, 0, 0],                            "0.2917": [-10, 62.5, 117.5],                            "0.5": [-80, -17.5, 22.5],                            "0.75": [-10, 0, 0]                        }                    },                    "head": {                        "rotation": { "0.0": [-7.5, 0, 0], "0.75": [-7.5, 0, 0] }                    }                }            },            "animation.ghost.move": {                "loop": true,                "animation_length": 1,                "bones": {                    "body": {                        "rotation": {                            "0.0": [15, 0, 0],                            "0.25": [15, -2.5, 0],                            "0.5": [15, 0, 0],                            "0.75": [15, 2.5, 0],                            "1.0": [15, 0, 0]                        },                        "position": [0, 0, 0]                    },                    "leftArm": {                        "rotation": {                            "0.0": [15, 0, 0],                            "0.5": [20, 0, 0],                            "1.0": [15, 0, 0]                        }                    },                    "rightArm": {                        "rotation": {                            "0.0": [15, 0, 0],                            "0.5": [20, 0, 0],                            "1.0": [15, 0, 0]                        }                    },                    "head": {                        "rotation": {                            "0.0": [-12.5, 0, 0],                            "0.5": [-15, 0, 0],                            "1.0": [-12.5, 0, 0]                        }                    }                }            }        }    }  

An animation file can contain multiple animations. We need the identifier for each animation (e.g., animation.ghost.idle, animation.ghost.attack, animation.ghost.move) to reference later.

While you *can* have multiple animation files per entity, it's often cleaner to group all animations for one entity into a single file (like ghost.a.json) for easier management.

Animation Controller

An animation controller (.ac.json or .animation_controller.json) determines *when* specific animations should play based on the entity's state or actions. It uses states, transitions, and queries.

Place your animation controller file(s) (e.g., ghost.ac.json) inside RP/animation_controllers/.

Show Example ghost.ac.json (Walk & Attack Controllers)
RP/animation_controllers/ghost.ac.json
  {        "format_version": "1.12.0",        "animation_controllers": {            "controller.animation.ghost.attack": {                "states": {                    "default": {                        "transitions": [                            {                                "attacking": "q.is_delayed_attacking"                            }                        ]                    },                    "attacking": {                        "blend_transition": 0.2,                        "animations": ["attack"],                        "transitions": [                            {                                "default": "!q.is_delayed_attacking"                            }                        ]                    }                }            },            "controller.animation.ghost.walk": {                "initial_state": "standing",                "states": {                    "standing": {                        "blend_transition": 0.2,                        "animations": ["idle"],                        "transitions": [                            {                                "moving": "q.modified_move_speed > 0.1"                            }                        ]                    },                    "moving": {                        "blend_transition": 0.2,                        "animations": ["move"],                        "transitions": [                            {                                "standing": "q.modified_move_speed < 0.1"                            }                        ]                    }                }            }        }    }  
  • States: Define periods of behavior (e.g., "standing", "moving", "attacking").
  • Transitions: Define conditions (using Molang Queries like q.is_delayed_attacking or q.modified_move_speed > 0.1) to move between states.
  • Animations: Specify which animation shortnames (defined later in the client entity file) play during each state.
  • initial_state: Specifies the starting state.
  • blend_transition: Smoothly blends between animations when changing states.

We need the identifier for each controller (e.g., controller.animation.ghost.attack, controller.animation.ghost.walk) for the client entity file.

Learn more about Animation Controllers here.

Entity Client File (ghost.ce.json)

Now we assemble references to all these visual resources in our RP/entity/ghost.ce.json file.

Start with the basic structure and identifier:

RP/entity/ghost.ce.json
  {        "format_version": "1.10.0",        "minecraft:client_entity": {            "description": {                "identifier": "wiki:ghost"            }        }    }  

Inside the "description" block, we define shortnames for materials, textures, and geometry:

ghost.ce.json / description (resources)
  {        "format_version": "1.10.0",        "minecraft:client_entity": {            "description": {                "identifier": "wiki:ghost",                "materials": {                    "default": "entity_alphatest"                },                "textures": {                    "default": "textures/entity/ghost"                },                "geometry": {                    "default": "geometry.ghost"                }            }        }    }  
  • "materials": Defines rendering materials. "default": "entity_alphatest" uses a built-in material suitable for textures with transparency. Custom materials are advanced. Learn more here.
  • "textures": Maps a shortname ("default") to the texture path (relative to RP, no extension).
  • "geometry": Maps a shortname ("default") to the geometry identifier (from the .geo.json file).

Render Controller

A render controller tells the game *which* geometry, materials, and textures (using their shortnames) to actually draw. These are defined in .rc.json files (or .render_controller.json) in RP/render_controllers/.

Show Example ghost.rc.json
RP/render_controllers/ghost.rc.json
  {        "format_version": "1.10.0",        "render_controllers": {            "controller.render.ghost": {                "geometry": "geometry.default",                "materials": [                    {                        "*": "material.default"                    }                ],                "textures": ["texture.default"]            }        }    }  

This simple controller (identifier: controller.render.ghost) tells the game to use the resources assigned to the "default" shortnames we defined above. More complex controllers can swap textures or show/hide parts of the model. Learn more here.

If you keep shortnames like "default" consistent across entities with similar rendering needs, you can often reuse the same render controller file.

Add a reference to this render controller in your ghost.ce.json description:

ghost.ce.json / description (add render_controllers)
  "render_controllers": ["controller.render.ghost"]  

At this point, your entity should be visible in-game!

Show ghost.ce.json (so far)
RP/entity/ghost.ce.json
  {        "format_version": "1.10.0",        "minecraft:client_entity": {            "description": {                "identifier": "wiki:ghost",                "materials": {                    "default": "entity_alphatest"                },                "textures": {                    "default": "textures/entity/ghost"                },                "geometry": {                    "default": "geometry.ghost"                },                "render_controllers": ["controller.render.ghost"]            }        }    }  

Scripts (for Animations)

To make the animations play, we first define shortnames for them and their controllers within the ghost.ce.json description:

ghost.ce.json / description (add animations)
  "animations": {        "walk_controller": "controller.animation.ghost.walk",        "attack_controller": "controller.animation.ghost.attack",        "attack": "animation.ghost.attack",        "idle": "animation.ghost.idle",        "move": "animation.ghost.move"    }  

Note how the values match the identifiers from the .a.json and .ac.json files. The keys ("walk_controller", "attack", etc.) are the shortnames we use elsewhere (like in the animation controllers).

Then, we use the "scripts" block to tell the entity *when* to run the animation controllers:

ghost.ce.json / description (add scripts)
  "scripts": {        "animate": [            "walk_controller",            "attack_controller"        ]    }  

The "animate" script runs every game tick, executing the listed animation controllers (which then decide which specific animation plays based on their internal states and transitions).

Test Animations! Reload the world. Your ghost should now idle, move, and attack with animations!

Spawn Egg

Finally, we can define how the entity's spawn egg looks in the Creative inventory. Add the "spawn_egg" key to the ghost.ce.json description:

ghost.ce.json / description (add spawn_egg)
  "spawn_egg": {        "overlay_color": "#bdd1d1",        "base_color": "#9fb3b3"    }  

This generates a standard two-tone egg using the provided hex color codes.

Alternatively, if you want a completely custom spawn egg texture (like vanilla ones), you can define it like an item texture in item_texture.json and reference its shortname here:

ghost.ce.json / description (spawn_egg texture)
  "spawn_egg": {        "texture": "texture_shortname"    }  

With that, the client entity file is complete!

Show Full ghost.ce.json
RP/entity/ghost.ce.json
  {        "format_version": "1.10.0",        "minecraft:client_entity": {            "description": {                "identifier": "wiki:ghost",                "materials": {                    "default": "entity_alphatest"                },                "textures": {                    "default": "textures/entity/ghost"                },                "geometry": {                    "default": "geometry.ghost"                },                "scripts": {                    "animate": ["walk_controller", "attack_controller"]                },                "animations": {                    "walk_controller": "controller.animation.ghost.walk",                    "attack_controller": "controller.animation.ghost.attack",                    "attack": "animation.ghost.attack",                    "idle": "animation.ghost.idle",                    "move": "animation.ghost.move"                },                "spawn_egg": {                    "overlay_color": "#bdd1d1",                    "base_color": "#9fb3b3"                },                "render_controllers": ["controller.render.ghost"]            }        }    }  

Entity Name

The final step is giving our entity and its spawn egg proper display names. Add these lines to **both** RP/texts/en_US.lang and BP/texts/en_US.lang:

RP/texts/en_US.lang & BP/texts/en_US.lang (additions)
  entity.wiki:ghost.name=Ghost    item.spawn_egg.entity.wiki:ghost.name=Ghost Spawn Egg  

Make sure the keys match the entity identifier (entity.wiki:ghost.name) and the spawn egg item name (item.spawn_egg.entity.wiki:ghost.name).


Overview

Done! Your entity should now show up in Minecraft, complete with all behaviors and visuals, including animations! You should be able to summon your entity using /summon wiki:ghost or by finding the "Ghost Spawn Egg" in the creative menu.

Your final folder structure should look something like this:

Project File Structure Update

  • RP/
  • animations/ (New)
  • ghost.a.json (New)
  • animation_controllers/ (New)
  • ghost.ac.json (New)
  • entity/ (New)
  • ghost.ce.json (New)
  • models/ (New)
  • entity/ (New)
  • ghost.geo.json (New)
  • render_controllers/ (New)
  • ghost.rc.json (New)
  • textures/
  • entity/ (New)
  • ghost.png (New)
  • items/
  • ectoplasm.png
  • item_texture.json
  • texts/
  • en_US.lang (Edited)
  • ... (manifest.json, pack_icon.png etc.)
  • BP/
  • entities/ (New)
  • ghost.se.json (New)
  • items/
  • ectoplasm.json
  • texts/
  • en_US.lang (Edited)
  • ... (manifest.json, pack_icon.png etc.)

Full Entity Code Files:

Full ghost.se.json (Behavior)
BP/entities/ghost.se.json
  {        "format_version": "1.21.0",        "minecraft:entity": {            "description": {                "identifier": "wiki:ghost",                "is_summonable": true,                "is_spawnable": true            },            "components": {                "minecraft:type_family": {                    "family": ["ghost", "monster"]                },                "minecraft:health": {                    "value": 20,                    "max": 20                },                "minecraft:attack": {                    "damage": 3                },                "minecraft:movement": {                    "value": 0.2                },                "minecraft:collision_box": {                    "width": 0.8,                    "height": 1.8                },                "minecraft:loot": {                    "table": "loot_tables/entities/ghost.json"                },                "minecraft:physics": {},                "minecraft:jump.static": {},                "minecraft:movement.basic": {},                "minecraft:navigation.walk": {                    "can_walk": true,                    "avoid_sun": true,                    "can_pass_doors": true,                    "can_open_doors": true                },                "minecraft:behavior.random_stroll": {                    "priority": 6,                    "speed_multiplier": 1                },                "minecraft:behavior.random_look_around": {                    "priority": 7                },                "minecraft:behavior.look_at_player": {                    "priority": 7,                    "look_distance": 6,                    "probability": 0.02                },                "minecraft:behavior.hurt_by_target": {                    "priority": 1                },                "minecraft:behavior.nearest_attackable_target": {                    "priority": 2,                    "within_radius": 25,                    "reselect_targets": true,                    "entity_types": [                        {                            "filters": {                                "any_of": [                                    {                                        "test": "is_family",                                        "subject": "other",                                        "value": "player"                                    }                                ]                            },                            "max_dist": 35                        }                    ]                },                "minecraft:behavior.delayed_attack": {                    "priority": 0,                    "attack_once": false,                    "track_target": true,                    "require_complete_path": false,                    "random_stop_interval": 0,                    "reach_multiplier": 1.5,                    "speed_multiplier": 1,                    "attack_duration": 0.75,                    "hit_delay_pct": 0.5                }            }        }    }  
Full ghost.ce.json (Client)
RP/entity/ghost.ce.json
  {        "format_version": "1.10.0",        "minecraft:client_entity": {            "description": {                "identifier": "wiki:ghost",                "materials": {                    "default": "entity_alphatest"                },                "textures": {                    "default": "textures/entity/ghost"                },                "geometry": {                    "default": "geometry.ghost"                },                "scripts": {                    "animate": ["walk_controller", "attack_controller"]                },                "animations": {                    "walk_controller": "controller.animation.ghost.walk",                    "attack_controller": "controller.animation.ghost.attack",                    "attack": "animation.ghost.attack",                    "idle": "animation.ghost.idle",                    "move": "animation.ghost.move"                },                "spawn_egg": {                    "overlay_color": "#bdd1d1",                    "base_color": "#9fb3b3"                },                "render_controllers": ["controller.render.ghost"]            }        }    }  
Full ghost.geo.json (Model)
RP/models/entity/ghost.geo.json
  {        "format_version": "1.12.0",        "minecraft:geometry": [            {                "description": {                    "identifier": "geometry.ghost",                    "texture_width": 64,                    "texture_height": 64,                    "visible_bounds_width": 3,                    "visible_bounds_height": 3.5,                    "visible_bounds_offset": [0, 1.25, 0]                },                "bones": [                    { "name": "root", "pivot": [0, 3, 0] },                    {                        "name": "body",                        "parent": "root",                        "pivot": [0, 4.625, 0],                        "cubes": [                            {                                "origin": [-4, 3, -4],                                "size": [8, 13, 8],                                "uv": [0, 20]                            }                        ]                    },                    {                        "name": "leftArm",                        "parent": "body",                        "pivot": [4.6, 15.5, 0.5],                        "cubes": [                            {                                "origin": [4.1, 7, -1],                                "size": [3, 9, 3],                                "uv": [32, 32]                            }                        ]                    },                    {                        "name": "rightArm",                        "parent": "body",                        "pivot": [-4.5, 15.5, 0.5],                        "cubes": [                            {                                "origin": [-7.1, 7, -1],                                "size": [3, 9, 3],                                "uv": [32, 20]                            }                        ]                    },                    {                        "name": "head",                        "parent": "body",                        "pivot": [0, 16, 0],                        "cubes": [                            {                                "origin": [-5, 16, -5],                                "size": [10, 10, 10],                                "uv": [0, 0]                            }                        ]                    }                ]            }        ]    }  
Full ghost.a.json (Animations)
RP/animations/ghost.a.json
  {        "format_version": "1.8.0",        "animations": {            "animation.ghost.idle": {                "loop": true,                "animation_length": 3,                "bones": {                    "body": {                        "rotation": { "0.0": [10, 0, 0], "3.0": [10, 0, 0] },                        "position": {                            "0.0": [0, 0, 0],                            "1.5": [0, 1, 0],                            "3.0": [0, 0, 0]                        }                    },                    "leftArm": {                        "rotation": {                            "0.0": [-10, 0, 0],                            "1.5": [-5, 0, 0],                            "3.0": [-10, 0, 0]                        }                    },                    "rightArm": {                        "rotation": {                            "0.0": [-10, 0, 0],                            "1.5": [-5, 0, 0],                            "3.0": [-10, 0, 0]                        }                    },                    "head": {                        "rotation": {                            "0.0": [-7.5, 0, 0],                            "1.5": [-2.5, 0, 0],                            "3.0": [-7.5, 0, 0]                        }                    }                }            },            "animation.ghost.attack": {                "animation_length": 0.75,                "bones": {                    "body": {                        "rotation": {                            "0.0": [10, 0, 0],                            "0.2917": [10, 15, 0],                            "0.5": [22.5, -12.5, 0],                            "0.75": [10, 0, 0]                        },                        "position": {                            "0.0": [0, 0, 0],                            "0.2917": [0, 0, 3],                            "0.5": [0, 0, -3],                            "0.75": [0, 0, 0]                        }                    },                    "leftArm": {                        "rotation": { "0.0": [-10, 0, 0], "0.75": [-10, 0, 0] }                    },                    "rightArm": {                        "rotation": {                            "0.0": [-10, 0, 0],                            "0.2083": [-10, 0, 0],                            "0.2917": [-10, 62.5, 117.5],                            "0.5": [-80, -17.5, 22.5],                            "0.75": [-10, 0, 0]                        }                    },                    "head": {                        "rotation": { "0.0": [-7.5, 0, 0], "0.75": [-7.5, 0, 0] }                    }                }            },            "animation.ghost.move": {                "loop": true,                "animation_length": 1,                "bones": {                    "body": {                        "rotation": {                            "0.0": [15, 0, 0],                            "0.25": [15, -2.5, 0],                            "0.5": [15, 0, 0],                            "0.75": [15, 2.5, 0],                            "1.0": [15, 0, 0]                        },                        "position": [0, 0, 0]                    },                    "leftArm": {                        "rotation": {                            "0.0": [15, 0, 0],                            "0.5": [20, 0, 0],                            "1.0": [15, 0, 0]                        }                    },                    "rightArm": {                        "rotation": {                            "0.0": [15, 0, 0],                            "0.5": [20, 0, 0],                            "1.0": [15, 0, 0]                        }                    },                    "head": {                        "rotation": {                            "0.0": [-12.5, 0, 0],                            "0.5": [-15, 0, 0],                            "1.0": [-12.5, 0, 0]                        }                    }                }            }        }    }  
Full ghost.ac.json (Animation Controllers)
RP/animation_controllers/ghost.ac.json
  {        "format_version": "1.12.0",        "animation_controllers": {            "controller.animation.ghost.attack": {                "states": {                    "default": {                        "transitions": [                            {                                "attacking": "q.is_delayed_attacking"                            }                        ]                    },                    "attacking": {                        "blend_transition": 0.2,                        "animations": ["attack"],                        "transitions": [                            {                                "default": "!q.is_delayed_attacking"                            }                        ]                    }                }            },            "controller.animation.ghost.walk": {                "initial_state": "standing",                "states": {                    "standing": {                        "blend_transition": 0.2,                        "animations": ["idle"],                        "transitions": [                            {                                "moving": "q.modified_move_speed > 0.1"                            }                        ]                    },                    "moving": {                        "blend_transition": 0.2,                        "animations": ["move"],                        "transitions": [                            {                                "standing": "q.modified_move_speed < 0.1"                            }                        ]                    }                }            }        }    }  
Full ghost.rc.json (Render Controller)
RP/render_controllers/ghost.rc.json
  {        "format_version": "1.10.0",        "render_controllers": {            "controller.render.ghost": {                "geometry": "geometry.default",                "materials": [                    {                        "*": "material.default"                    }                ],                "textures": ["texture.default"]            }        }    }  

If you encounter issues, review the Troubleshooting page or compare your files with the example entity files.


Your Progress So Far

  • Setup your pack structure
  • Create a custom item (Ectoplasm)
  • Create a custom entity (Ghost)
  • Format behavior (.se.json) and resource (.ce.json) files for an entity
  • Define entity components for stats, movement, and AI
  • Link entity model, texture, animations, and controllers
  • Set an entity's display name and spawn egg
  • Create the entity's loot, spawn rules, and a custom recipe

Next Steps

Your ghost entity now exists and looks the part! Next, we'll define how it interacts with the world by creating loot tables (what it drops), spawn rules (where it appears), and maybe even a custom recipe involving its drops.

Next: Blockbench Guide