For Developers
Custom Features
Custom Entities

When using custom entities, players will need a resource pack containing all important texture, geometry, and entity files. Find out more about resource packs on wiki.bedrock.dev

Custom Entities

On PNX, you can create your own entities. Make sure your resource pack contains all the important texture, geometry, and entity files. For this example, we will use the PNX Example resource pack.

Register a Custom Entity

It is recommended to register your entity while the plugin is loaded but not enabled yet. You can achieve this in the onLoad function.

// Imports
import cn.nukkit.registry.EntityRegistry;
import cn.nukkit.registry.RegisterException;
import cn.nukkit.registry.Registries;
 
@Override
public void onLoad() {
    try {
        // Register the custom entity using the entity class
        Registries.ENTITY.registerCustomEntity(this, MyPig.class);
        // After registration, we rebuild the NBT tag to include our new entity.
        Registries.ENTITY.rebuildTag();
    } catch (RegisterException e) {
        throw new RuntimeException(e);
    }
}

Defining Your Entity

As we learned above in Register a Custom Entity, every custom entity needs to have a corresponding class, which roughly looks like this:

// Imports
import cn.nukkit.entity.Entity;
import cn.nukkit.entity.custom.CustomEntity;
import cn.nukkit.level.format.IChunk;
import cn.nukkit.nbt.tag.CompoundTag;
import org.jetbrains.annotations.NotNull;
 
 
public class MyPig extends Entity implements CustomEntity {
    public MyPig(IChunk chunk, CompoundTag nbt) { super(chunk, nbt); }
 
    public static final String IDENTIFIER = "powernukkitx:boar";
    @Override public @NotNull String getIdentifier() { return IDENTIFIER; }
 
    // Define your entity's components here
    public static CustomEntityDefinition definition() {
        return CustomEntityDefinition.simpleBuilder(IDENTIFIER)
            .eid(IDENTIFIER)
            .hasSpawnEgg(true) // If true, a spawn egg of this entity will be generated and can be found in the creative inventory
            .isSummonable(false) // If false, you cannot spawn this entity by commands
            .originalName("Boar") // A display name for the entity
            .maxHealth(220) // Define the max health
            .attack(0) // If the mob can attack you can define here its melee power
            .movement(0.1f, 7.0f) // Default movement speed
            .typeFamily("mob", "pig", "mypig") // Type family of the mob, useful for filterings on API and commands
            .collisionBox(0.8f, 0.6f) // Collision box of the entity, where you can hit/interact with it
            .knockbackResistance(0.6f) // The entity resistance against physical attacks
            .maxAutoStep(1.0625f, 1.0625f, 0.5625f) // You can define the max auto-step of the entity, making it move over blocks without need to jump
            .isPersistent(true) // If set true, the entity never despawns from distance
            .build();
    }
}

You can also implement additional features like MarkVariant and Variant (e.g., multiple textures/geometries) by adding EntityMarkVariant, EntityVariant after CustomEntity.

Spawning Your Entity

After Registering and Defining our entity, you will be able to spawn the entity by some methods:

  • Summon command (if isSummonable(true) is used)
  • Spawn egg (if hasSpawnEgg(true) is used), available in Creative
  • API: create an instance of your entity class (e.g., MyPig) and call a spawn method such as spawnToAll() or spawnTo(player)

Example: spawn your entity with API:

@Override
public boolean execute(CommandSender sender, String commandLabel, String[] args) {
    if (sender.isPlayer()) {
        Player player = sender.asPlayer();
 
        // Creating a new instance of our MyPig class and providing the required variables IChunk chunk and CompoundTag nbt to the Entity constructor.
        MyPig boar = new MyPig(player.getChunk(), Entity.getDefaultNBT(player));
 
        // Spawn it for everyone on the server:
        boar.spawnToAll();
 
        // Or, alternatively, spawn it only for the command sender:
        // boar.spawnTo(player);
 
        return true;
    } else {
        return false;
    }
}

Need Help?

If you need help, check out our Example plugin or join our Discord server and ask for help.