Making Entities

From Forge Community Wiki
Revision as of 21:49, 6 October 2022 by ChampionAsh5357 (talk | contribs) (Correct mistakes in entity attributes)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)

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 LivingEntitys 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());
}


Most mobs use this static method attribute builder, so if you are subclassing a different entity class (e.g., 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.