|
| 1 | +--- |
| 2 | +title: Creating Your First Entity |
| 3 | +description: Learn how to register a simple entity and how to give it goals, render, model, and animate it. |
| 4 | +authors: |
| 5 | + - cassiancc |
| 6 | + - Earthcomputer |
| 7 | + - JaaiDead |
| 8 | +--- |
| 9 | + |
| 10 | +Entities are dynamic, interactive objects in the game that are not part of the terrain (like blocks). Entities can move around and interact with the world in various ways. A few examples include: |
| 11 | + |
| 12 | +- `Villager`, `Pig`, and `Goat` are all examples of a `Mob`, the most common type of entity - something alive. |
| 13 | +- `Zombie` and `Skeleton` are examples of a `Monster`, a variant of an `Entity` that is hostile to the `Player`. |
| 14 | +- `Minecart` and `Boat` are examples of a `VehicleEntity`, which has special logic for accepting player input. |
| 15 | + |
| 16 | +This tutorial will walk you through the process of creating a custom _Mini Golem_. This entity will have fun animations. It will be a `PathfinderMob`, which is the class used by most mobs with pathfinding, such as `Zombie` and `Villager`. |
| 17 | + |
| 18 | +## Preparing Your First Entity {#preparing-your-first-entity} |
| 19 | + |
| 20 | +The first step in creating a custom entity is defining its class and registering it with the game. |
| 21 | + |
| 22 | +We'll create the class `MiniGolemEntity` for our entity, and start by giving it attributes. [Attributes](attributes) decide various things including the maximum health, movement speed, and tempt range of the entity. |
| 23 | + |
| 24 | +@[code transcludeWith=:::registerclass](@/reference/latest/src/main/java/com/example/docs/entity/MiniGolemEntity.java) |
| 25 | + |
| 26 | +To register your entity, it's recommended to create a separate class, `ModEntityTypes`, where you register any and all entity types, set their sizes, and register their attributes. |
| 27 | + |
| 28 | +@[code transcludeWith=:::types](@/reference/latest/src/main/java/com/example/docs/entity/ModEntityTypes.java) |
| 29 | + |
| 30 | +## Adding Goals {#adding-goals} |
| 31 | + |
| 32 | +Goals are the system that handle an entity's objective/aim, providing them with a defined set of behavior. Goals have a certain priority: goals with a lower value for the priority are prioritized over goals with a higher value for the priority. |
| 33 | + |
| 34 | +To add goals to the entity, you need to create a `registerGoals` method in your entity's class that defines the goals for the entity. |
| 35 | + |
| 36 | +@[code transcludeWith=:::goals](@/reference/latest/src/main/java/com/example/docs/entity/MiniGolemEntity.java) |
| 37 | + |
| 38 | +::: info |
| 39 | + |
| 40 | +1. `TemptGoal` - The entity is attracted towards a player holding an item. |
| 41 | +2. `RandomStrollGoal` - Walks/wanders around the world. |
| 42 | +3. `LookAtPlayerGoal` - Despite the name, this accepts any entity. Used here to look at the `Cow` entity. |
| 43 | +4. `RandomLookAroundGoal` - To look in random directions. |
| 44 | + |
| 45 | +::: |
| 46 | + |
| 47 | +## Creating Rendering {#creating-rendering} |
| 48 | + |
| 49 | +Rendering refers to the process of converting game data such as blocks, entities, and environments into visual representations displayed on the player's screen. This involves determining how objects are illuminated, shaded, and textured. |
| 50 | + |
| 51 | +::: info |
| 52 | + |
| 53 | +Entity rendering is always handled on the client side. The server manages the entity's logic and behavior, while the client is responsible for displaying the entity's model, texture, and animations. |
| 54 | + |
| 55 | +::: |
| 56 | + |
| 57 | +Rendering has multiple steps involving their own classes, but we'll start with the `EntityRenderState` class. |
| 58 | + |
| 59 | +@[code transcludeWith=:::entitystate](@/reference/latest/src/client/java/com/example/docs/entity/state/MiniGolemEntityRenderState.java) |
| 60 | + |
| 61 | +Data stored on the render state is used to determine how the entity is visually represented, including animation states such as movement and idle behaviors. |
| 62 | + |
| 63 | +### Setting up the Model {#setting-up-model} |
| 64 | + |
| 65 | +The `MiniGolemEntityModel` class defines how your entity looks by describing its shape and parts. Models are generally created in third-party tools like [Blockbench](https://web.blockbench.net), rather than being written by hand. Nonetheless, this tutorial will go through a manual example to show you how it works. |
| 66 | + |
| 67 | +::: warning |
| 68 | + |
| 69 | +Blockbench supports multiple [mappings](../migrating-mappings/#mappings) (such as Mojang Mappings, Yarn, and others). Ensure you select the correct mapping that matches your development environment - this tutorial uses Mojang Mappings. |
| 70 | + |
| 71 | +Mismatched mappings can cause errors when integrating Blockbench generated code. |
| 72 | + |
| 73 | +::: |
| 74 | + |
| 75 | +@[code transcludeWith=:::model1](@/reference/latest/src/client/java/com/example/docs/entity/model/MiniGolemEntityModel.java) |
| 76 | + |
| 77 | +The `MiniGolemEntityModel` class defines the visual model for a Mini Golem entity. It extends `EntityModel`, specifying how the entity's body parts (body, head, left leg, and right leg) are named. |
| 78 | + |
| 79 | +@[code transcludeWith=:::model_texture_data](@/reference/latest/src/client/java/com/example/docs/entity/model/MiniGolemEntityModel.java) |
| 80 | + |
| 81 | +This method defines the Mini Golem's 3D model by creating its body, head, and legs as cuboids, setting their positions and texture mappings, and returning a `LayerDefinition` for rendering. |
| 82 | + |
| 83 | +Each part is added with an offset point which is the origin for all of the transformations applied to that part. All other coordinates in the model part are measured relative to this offset point. |
| 84 | + |
| 85 | +::: warning |
| 86 | + |
| 87 | +Higher Y values in the model correspond to the **bottom** of the entity. This is the reverse compared to in-game coordinates. |
| 88 | + |
| 89 | +::: |
| 90 | + |
| 91 | +We'll now need to create a `ModEntityModelLayers` class in the client package. This entity only has a single texture layer, but other entities may use multiple - think of the secondary skin layer on entities like the `Player` or a `Spider`'s eyes. |
| 92 | + |
| 93 | +@[code transcludeWith=:::model_layer](@/reference/latest/src/client/java/com/example/docs/entity/model/ModEntityModelLayers.java) |
| 94 | + |
| 95 | +This class must then be initialized in the mod's client initializer. |
| 96 | + |
| 97 | +@[code transcludeWith=::register_client](@/reference/latest/src/client/java/com/example/docs/entity/ExampleModCustomEntityClient.java) |
| 98 | + |
| 99 | +### Setting up the Texture {#setting-up-texture} |
| 100 | + |
| 101 | +::: tip |
| 102 | + |
| 103 | +The size of the texture should match the values in the `LayerDefinition.create(modelData, 64, 32)`: 64 pixels wide and 32 pixels tall. If you need a differently-sized texture, then don't forget to change the size in `LayerDefinition.create` to match. |
| 104 | + |
| 105 | +::: |
| 106 | + |
| 107 | +Each model part / box is expecting a net on the texture in a particular location. By default, it's expecting it at `0, 0` (the top left), but this can be changed by calling the `texOffs` function in `CubeListBuilder`. |
| 108 | + |
| 109 | +For example purposes, you can use this texture for `assets/example-mod/textures/entity/mini_golem.png` |
| 110 | + |
| 111 | +<DownloadEntry visualURL="/assets/develop/entity/mini_golem.png" downloadURL="/assets/develop/entity/mini_golem_small.png">Texture</DownloadEntry> |
| 112 | + |
| 113 | +### Creating the Renderer {#creating-the-renderer} |
| 114 | + |
| 115 | +A entity's renderer enables you to view your entity in-game. We'll create a new class, `MiniGolemEntityRenderer`, which will tell Minecraft what texture, model, and entity render state to use for this entity. |
| 116 | + |
| 117 | +@[code transcludeWith=:::renderer](@/reference/latest/src/client/java/com/example/docs/entity/renderer/MiniGolemEntityRenderer.java) |
| 118 | + |
| 119 | +This is also where the shadow radius is set, for this entity that will be `0.375f`. |
| 120 | + |
| 121 | +### Adding Walking Animations {#walking-animations} |
| 122 | + |
| 123 | +The following code can be added to the `MiniGolemEntityModel` class to give the entity a walking animation. |
| 124 | + |
| 125 | +@[code transcludeWith=:::model_animation](@/reference/latest/src/client/java/com/example/docs/entity/model/MiniGolemEntityModel.java) |
| 126 | + |
| 127 | +To start, apply the yaw and pitch to the head model part. |
| 128 | + |
| 129 | +Then, we apply the walking animation to the leg model parts. We use the `cos` function to create the general leg swing effect and then transform the cosine wave to get the correct swing speed and amplitude. |
| 130 | + |
| 131 | +- The `0.2` constant in the formula controls the frequency of the cosine wave (how fast the legs are swinging). Higher values result in a higher frequency. |
| 132 | +- The `1.4` constant in the formula controls the amplitude of the cosine wave (how far the legs swing). Higher values result in a higher amplitude. |
| 133 | +- The `limbSwingAmplitude` variable also affects the amplitude in the same way as the `1.4` constant. This variable changes based on the velocity of the entity, so that the legs swing more when the entity is moving faster and swing less or not at all when the entity is moving slower or not moving. |
| 134 | +- The `Mth.PI` constant for the left leg translates the cosine wave a half phase so that the left leg is swinging the opposite direction to the right leg. |
| 135 | + |
| 136 | +You can plot those on a graph to see what they look like: |
| 137 | + |
| 138 | +{.dark-only} |
| 139 | +{.light-only} |
| 140 | + |
| 141 | +The "red" curve is for the left leg, and the "black" one is for the right. The horizontal x-axis represents time, and the y-axis indicates the angle of the leg limbs. |
| 142 | + |
| 143 | +Feel free to [play around with the constants on Desmos](https://www.desmos.com/calculator/9r6lh5knfu) to see how they affect the curve. |
| 144 | + |
| 145 | +Looking into the game, you now have all you need to spawn the entity with `/summon example-mod:mini_golem`! |
| 146 | + |
| 147 | + |
| 148 | + |
| 149 | +## Adding Data To An Entity {#adding-data-to-an-entity} |
| 150 | + |
| 151 | +To store data on an entity, the normal way is to simply add a field in entity class. |
| 152 | + |
| 153 | +Sometimes you need data from the server-side entity to be synced with the client-side entity. See the [Networking Page](../networking) for more info on the client-server architecture. To do this we can use _synched data_ \[sic] by defining an `EntityDataAccessor` for it. |
| 154 | + |
| 155 | +In our case we want our entity to dance every so often, so we need to create a dancing state that is synchronized between the clients so that it can be animated later. However, the dancing cooldown need not be synced with the client because the animation is triggered by the server. |
| 156 | + |
| 157 | +@[code transcludeWith=:::datatracker](@/reference/latest/src/main/java/com/example/docs/entity/MiniGolemEntity.java) |
| 158 | + |
| 159 | +As you can see we added a tick method to control the dancing state. |
| 160 | + |
| 161 | +## Storing Data to NBT {#storing-data-to-nbt} |
| 162 | + |
| 163 | +For persistent data that can be saved after the game is closed, we will override the `addAdditionalSaveData` and `readAdditionalSaveData` methods in `MiniGolemEntity`. We can use this to store the amount of time remaining in the dancing animation. |
| 164 | + |
| 165 | +@[code transcludeWith=:::savedata](@/reference/latest/src/main/java/com/example/docs/entity/MiniGolemEntity.java) |
| 166 | + |
| 167 | +Now, whenever the entity is loaded, it will restore the state that it was left in. |
| 168 | + |
| 169 | +## Adding an Animation {#adding-an-animation} |
| 170 | + |
| 171 | +The first step to adding an animation to the entity is adding the animation state in the entity class. We'll create an animation state that will be used to make the entity dance. |
| 172 | + |
| 173 | +@[code transcludeWith=:::dancing_animation](@/reference/latest/src/main/java/com/example/docs/entity/MiniGolemEntity.java) |
| 174 | + |
| 175 | +We have overridden the `onSyncedDataUpdated` method. This gets called whenever synched data is updated both the server and the client. The if-statement checks whether the synched data that was updated is the dancing synched data. |
| 176 | + |
| 177 | +Now, we'll move on to animation itself. We will create the `MiniGolemAnimations` class, and add an `AnimationDefinition` to define how the animation will be applied to the entity. |
| 178 | + |
| 179 | +@[code transcludeWith=:::dancing_animation](@/reference/latest/src/client/java/com/example/docs/entity/animation/MiniGolemAnimations.java) |
| 180 | + |
| 181 | +There's a lot going on here, notice the following key points: |
| 182 | + |
| 183 | +- `withLength(1)` makes the animation last 1 second. |
| 184 | +- `looping()` makes the animation loop repeatedly. |
| 185 | +- Then follows a series of `addAnimation` calls which adds individual animations targeting individual model parts. Here, we have different animations targeting the head, left leg, and right leg. |
| 186 | + - Each animation targets a specific property of that model part, in our case we are changing the rotation of the model part in each case. |
| 187 | + - An animation is made up of a list of keyframes. When the time (number of seconds elapsed) of the animation is equal to one of these keyframes, then the value of the property we targeted will be equal to the value we specified for that keyframe (in our case the rotation). |
| 188 | + - When the time is between our keyframes, then the value will be interpolated (blended) between the two neighboring keyframes. |
| 189 | + - We have used linear interpolation, which is the simplest and changes the value (in our case rotation of the model part) at a constant rate from one keyframe to the next. Vanilla also provides Catmull-Rom spline interpolation, which produces a smoother transition between keyframes. |
| 190 | + - Modders can also create custom interpolation types. |
| 191 | + |
| 192 | +Finally, let's hook up the animation to the model: |
| 193 | + |
| 194 | +@[code transcludeWith=:::dancing_animation](@/reference/latest/src/client/java/com/example/docs/entity/model/MiniGolemEntityModel.java) |
| 195 | + |
| 196 | +When the animation is playing we apply the animation, otherwise we use the old leg animation code. |
| 197 | + |
| 198 | +## Adding the Spawn Egg {#adding-spawn-egg} |
| 199 | + |
| 200 | +To add a spawn egg for the Mini Golem entity, refer to the full article on [Creating a Spawn Egg](../items/spawn-egg). |
0 commit comments