Views
Actions
Difference between revisions of "Making Entities"
m (boop) |
(Correct mistakes in entity attributes) |
||
(3 intermediate revisions by one other user not shown) | |||
Line 69: | Line 69: | ||
To define custom behavior, methods must be overriden. Your IDE should have a feature to list all possible methods to override, although some common ones might be: <code>customServerAiStep</code> for server AI, <code>tick</code> for code to execute each tick on client/server, and <code>registerGoals</code> to setup AI goals. | To define custom behavior, methods must be overriden. Your IDE should have a feature to list all possible methods to override, although some common ones might be: <code>customServerAiStep</code> for server AI, <code>tick</code> for code to execute each tick on client/server, and <code>registerGoals</code> to setup AI goals. | ||
+ | |||
+ | == Entity Attributes == | ||
+ | All <code>LivingEntity</code>s must have an associated <code>AttributeSupplier</code>, which, as named, supplies the default settings for all the attributes an entity has. An <code>Attribute</code> represents a syncable piece of data representing a characteristic, quality, or feature of an entity. Vanilla and Forge both define attributes that an entity can use within <code>Attributes</code> and <code>ForgeMod</code>, respectively. | ||
+ | |||
+ | To attach an attribute to a new entity, you must create an event listener for the <code>EntityAttributeCreationEvent</code> on the '''mod''' event bus and call <code>#put</code>, providing the <code>EntityType<T></code> and the attribute supplier. | ||
+ | |||
+ | {{Tabs/Code Snippets | ||
+ | |java=// On the mod event bus | ||
+ | public void newEntityAttributes(EntityAttributeCreationEvent event) { | ||
+ | event.put(EXAMPLE_ENTITY_TYPE.get(), | ||
+ | AttributeSupplier.builder() | ||
+ | .add(Attributes.MAX_HEALTH) // Sets max health to default value 20 | ||
+ | .add(Attributes.KNOCKBACK_RESISTANCE, 4.0D) // Sets knockback resistance to 4 | ||
+ | // ... | ||
+ | ); | ||
+ | } | ||
+ | }} | ||
+ | |||
+ | You can similarly append new attributes or modify existing attributes for existing entities by listening to <code>EntityAttributeModificationEvent</code> on the '''mod''' event bus and call <code>#add</code>, supplying the <code>EntityType<T></code>, the <code>Attribute</code>, and optionally the value if you do not want the default. | ||
+ | |||
+ | {{Tabs/Code Snippets | ||
+ | |java=// On the mod event bus | ||
+ | public void existingEntityAttributes(EntityAttributeModificationEvent event) { | ||
+ | if (!event.has(EntityType.CREEPER, EXAMPLE_ATTRIBUTE.get())) { | ||
+ | event.add(EntityType.CREEPER, | ||
+ | EXAMPLE_ATTRIBUTE.get() // Applies new attribute to creeper | ||
+ | ); | ||
+ | } | ||
+ | } | ||
+ | }} | ||
+ | |||
+ | === Reusable Attribute Suppliers === | ||
+ | |||
+ | <code>LivingEntity</code> and its subclasses require specific attributes to be defined on the entity (<code>LivingEntity</code> requires max health, knockback resistance, movement speed, armor, armor toughness, swim speed, nametag distance, entity gravity, and step height addition). To make it such that subclasses can use the previously defined attribute suppliers while still being able to add or override the specified super value, a static method is used to hold the builder, which is then referenced in a later subclass. The resulting method can then be passed into the <code>EntityAttributeCreationEvent</code>. | ||
+ | |||
+ | {{Tabs/Code Snippets | ||
+ | |java= | ||
+ | // In your LivingEntity subclass | ||
+ | public static AttributeSupplier.Builder createExampleAttributes() { | ||
+ | return LivingEntity.createLivingAttributes().add(Attributes.KNOCKBACK_RESISTANCE, 4.0D); | ||
+ | } | ||
+ | |||
+ | // In some separate class on the mod event bus | ||
+ | public void newEntityAttributes(EntityAttributeCreationEvent event) { | ||
+ | event.put(EXAMPLE_ENTITY_TYPE.get(), ExampleEntity.createExampleAttributes().build()); | ||
+ | } | ||
+ | }} | ||
+ | |||
+ | {{Tip|Most mobs use this static method attribute builder, so if you are subclassing a different entity class (e.g., <code>Mob</code>), you should look in the superclasses for the associated static method to build the attributes from (e.g., <code>Mob#createMobAttributes</code>).}} | ||
== Natural Spawning == | == Natural Spawning == | ||
To make entities naturally spawn, they must be added to the spawn list for each biome that the entity should spawn in. This can be achieved with a [[Biome Modifiers#Add Spawns|<code>forge:add_spawns</code> biome modifier]]. | To make entities naturally spawn, they must be added to the spawn list for each biome that the entity should spawn in. This can be achieved with a [[Biome Modifiers#Add Spawns|<code>forge:add_spawns</code> biome modifier]]. |
Latest revision as of 21:49, 6 October 2022
This page is under construction.
This page is incomplete, and needs more work. Feel free to edit and improve this page!
Entities are core to the Minecraft world and make up all movable objects that do not fall under Blocks or Block Entities. Entities can tick and be controlled by AI or player input. This article serves as a guide for setting up a basic entity. It does not involve setting up the rendering for an entity, which is a required step to be able to see an entity in-game without crashing. See Entity Renderer for more information on entity rendering and setup.
Entity Type
Much of the identity of an entity is determined by its entity type. This contains information universal to an entity. An entity type must exist and be registered for the corresponding entity to be summonable.
Creating the Builder
The primary way to make an EntityType
is to create and configure an EntityType$Builder
. Creating an entity type builder is done using the static factory EntityType.Builder#of
. It requires two parameters: an EntityType.EntityFactory
and a MobCategory
.
The entity factory is usually an entity class with a constructor taking its own EntityType
and Level
of the form MyEntity::new
. This requires a class of the name MyEntity
to actually exist (see the entity class section for more info).
The mob category is an enum describing mostly spawning properties about a category of mobs. This includes:
- How many entities in a given mob category can spawn per chunk
- Whether the entity is friendly (and therefore will spawn in peaceful difficulty)
- Whether the entity is persistent (and therefore will save to disk and be reloaded)
- How many blocks away a player must be for an entity in a given mob category to despawn
Configuring the Builder
An entity type builder by itself is not very useful. It must be configured to match the desired properties of the entity. The possible properties that can be configured are listed below:
Method | Default Value | Description |
---|---|---|
sized |
0.6 meters wide by 1.8 meters tall (player dimensions) | Sets the default pose dimensions of the entity in order of square base width then height in meters/blocks. A value of 1.0 would be equivalent to the length of 1 full block. The base cannot be configured with a separate width and length. |
noSummon |
Can summon | Calling this prevents spawning the entity through /summon ; intended for internal entities that a user should not be able to create. This also prevents summoning through natural spawning in biomes, if it is configured.
|
noSave |
Can save | Calling this prevents the entity from ever saving to disk. Unloading a chunk with a noSave entity will effectively delete the entity.
|
fireImmune |
Vulnerable to fire | Calling this prevents the entity from taking any fire/lava damage. |
clientTrackingRange |
5 chunks | Sets the maximum range in chunks in which players should be sent update packet information about the entity. Sending update information about an entity to a player is known as the player tracking that entity. If the player is outside this chunk range, they will not know of the entity's existence. |
immuneTo |
Empty set of blocks | Effectively useless for modding purposes. |
canSpawnFarFromPlayer |
True for MobCategory.CREATURE and MobCategory.MISC , false otherwise. |
Calling this allows an entity to spawn outside of the despawn distance of its mob category. |
updateInterval |
3 ticks | How often, in ticks, update packets should be sent to all client players tracking this entity (see clientTrackingRange ). The update packets contain information like position, rotation, and velocity. They may be sent more quickly than this interval during specific actions.
|
setShouldReceiveVelocityUpdates |
true | Sets whether tracking client players should receive velocity information in update interval packets. If false, velocity information will not be sent to clients unless necessary. |
Building the Builder
After creating and configuring the entity type builder, it must be built. This requires the modid and name of the entity type. For an entity type with the name "example_monster" in the mod "examplemod", this would look like builder.build("examplemod:example_monster")
.
Tying It Together
Given the above information, a basic EntityType might look like the following:
EntityType.Builder.of(ExampleMonsterEntity::new, MobCategory.MONSTER) .sized(1.0F, 2.0F) .fireImmune() .updateInterval(1) .build("examplemod:example_monster")
To function, this example requires that an entity class of the name ExampleMonsterEntity
exist along with the entity type being registered.
Entity Class
Alongside an entity type, an entity requires a class outlining its behavior and any information that may change from one instance to another. All entities must extend from the base class Entity
. However, some entities should extend from specific subclasses instead. For a completely generic entity, use Entity
. For a living entity with health, potion effects, and an inventory, use LivingEntity
. For a living entity with movement AI and AI goals, use Mob
. There are also many other entity subclasses which can be found through your IDE and picked depending on the scenario.
Once picking a target superclass to extend, an entity class should be created and the constructor should be setup. It should look something like this:
public class ExampleMonsterEntity extends Mob { public ExampleMonsterEntity(EntityType<? extends Mob> entityType, Level level) { super(entityType, level); } }
To define custom behavior, methods must be overriden. Your IDE should have a feature to list all possible methods to override, although some common ones might be: customServerAiStep
for server AI, tick
for code to execute each tick on client/server, and registerGoals
to setup AI goals.
Entity Attributes
All LivingEntity
s must have an associated AttributeSupplier
, which, as named, supplies the default settings for all the attributes an entity has. An Attribute
represents a syncable piece of data representing a characteristic, quality, or feature of an entity. Vanilla and Forge both define attributes that an entity can use within Attributes
and ForgeMod
, respectively.
To attach an attribute to a new entity, you must create an event listener for the EntityAttributeCreationEvent
on the mod event bus and call #put
, providing the EntityType<T>
and the attribute supplier.
// On the mod event bus public void newEntityAttributes(EntityAttributeCreationEvent event) { event.put(EXAMPLE_ENTITY_TYPE.get(), AttributeSupplier.builder() .add(Attributes.MAX_HEALTH) // Sets max health to default value 20 .add(Attributes.KNOCKBACK_RESISTANCE, 4.0D) // Sets knockback resistance to 4 // ... ); }
You can similarly append new attributes or modify existing attributes for existing entities by listening to EntityAttributeModificationEvent
on the mod event bus and call #add
, supplying the EntityType<T>
, the Attribute
, and optionally the value if you do not want the default.
// On the mod event bus public void existingEntityAttributes(EntityAttributeModificationEvent event) { if (!event.has(EntityType.CREEPER, EXAMPLE_ATTRIBUTE.get())) { event.add(EntityType.CREEPER, EXAMPLE_ATTRIBUTE.get() // Applies new attribute to creeper ); } }
Reusable Attribute Suppliers
LivingEntity
and its subclasses require specific attributes to be defined on the entity (LivingEntity
requires max health, knockback resistance, movement speed, armor, armor toughness, swim speed, nametag distance, entity gravity, and step height addition). To make it such that subclasses can use the previously defined attribute suppliers while still being able to add or override the specified super value, a static method is used to hold the builder, which is then referenced in a later subclass. The resulting method can then be passed into the EntityAttributeCreationEvent
.
// In your LivingEntity subclass public static AttributeSupplier.Builder createExampleAttributes() { return LivingEntity.createLivingAttributes().add(Attributes.KNOCKBACK_RESISTANCE, 4.0D); } // In some separate class on the mod event bus public void newEntityAttributes(EntityAttributeCreationEvent event) { event.put(EXAMPLE_ENTITY_TYPE.get(), ExampleEntity.createExampleAttributes().build()); }
Mob
), you should look in the superclasses for the associated static method to build the attributes from (e.g., Mob#createMobAttributes
).Natural Spawning
To make entities naturally spawn, they must be added to the spawn list for each biome that the entity should spawn in. This can be achieved with a forge:add_spawns
biome modifier.