Skip to main content

Entity API

Paper provides comprehensive APIs for entity management, customization, and AI control.

Entity Basics

Spawning Entities

import org.bukkit.entity.*;

// Spawn basic entity
Entity entity = world.spawnEntity(location, EntityType.ZOMBIE);

// Spawn with type casting
Zombie zombie = (Zombie) world.spawnEntity(location, EntityType.ZOMBIE);

// Or use typed method
Zombie zombie = world.spawn(location, Zombie.class);

// Configure before spawning
Zombie customZombie = world.spawn(location, Zombie.class, zombie -> {
    zombie.setBaby(true);
    zombie.setCustomName("Baby Zombie");
    zombie.setCustomNameVisible(true);
    zombie.getAttribute(Attribute.GENERIC_MAX_HEALTH).setBaseValue(40.0);
    zombie.setHealth(40.0);
});

Entity Properties

// Basic properties
EntityType type = entity.getType();
UUID uuid = entity.getUniqueId();
Location location = entity.getLocation();
World world = entity.getWorld();

// Custom name
entity.customName(Component.text("Custom Name"));
entity.setCustomNameVisible(true);

// Invulnerability
entity.setInvulnerable(true);

// Gravity
entity.setGravity(false);

// Silent (no sound effects)
entity.setSilent(true);

// Glowing
entity.setGlowing(true);

Entity Movement

// Teleport
entity.teleport(location);

// Velocity
Vector velocity = new Vector(0, 1, 0); // Upward
entity.setVelocity(velocity);

// Passengers
entity.addPassenger(player);
entity.removePassenger(player);
List<Entity> passengers = entity.getPassengers();

// Vehicle
Entity vehicle = entity.getVehicle();
entity.leaveVehicle();

Living Entities

Health and Attributes

if (entity instanceof LivingEntity living) {
    // Health
    double health = living.getHealth();
    double maxHealth = living.getAttribute(Attribute.GENERIC_MAX_HEALTH).getValue();
    living.setHealth(20.0);
    
    // Attributes
    AttributeInstance speed = living.getAttribute(Attribute.GENERIC_MOVEMENT_SPEED);
    speed.setBaseValue(0.3); // Faster
    
    AttributeInstance knockback = living.getAttribute(Attribute.GENERIC_KNOCKBACK_RESISTANCE);
    knockback.setBaseValue(1.0); // Immune to knockback
    
    // Air (drowning)
    int air = living.getRemainingAir();
    int maxAir = living.getMaximumAir();
    living.setRemainingAir(maxAir);
    
    // No AI
    living.setAI(false);
    
    // Remove when far
    living.setRemoveWhenFarAway(true);
}

Potion Effects

import org.bukkit.potion.PotionEffect;
import org.bukkit.potion.PotionEffectType;

if (entity instanceof LivingEntity living) {
    // Add potion effect
    PotionEffect effect = new PotionEffect(
        PotionEffectType.SPEED,
        200,  // Duration in ticks (10 seconds)
        1,    // Amplifier (level 2)
        false, // Ambient
        true,  // Show particles
        true   // Show icon
    );
    living.addPotionEffect(effect);
    
    // Check for effect
    if (living.hasPotionEffect(PotionEffectType.POISON)) {
        living.removePotionEffect(PotionEffectType.POISON);
    }
    
    // Get all effects
    Collection<PotionEffect> effects = living.getActivePotionEffects();
    
    // Clear all effects
    for (PotionEffect e : effects) {
        living.removePotionEffect(e.getType());
    }
}

Equipment

if (entity instanceof LivingEntity living) {
    EntityEquipment equipment = living.getEquipment();
    
    if (equipment != null) {
        // Set equipment
        equipment.setHelmet(new ItemStack(Material.DIAMOND_HELMET));
        equipment.setChestplate(new ItemStack(Material.DIAMOND_CHESTPLATE));
        equipment.setLeggings(new ItemStack(Material.DIAMOND_LEGGINGS));
        equipment.setBoots(new ItemStack(Material.DIAMOND_BOOTS));
        equipment.setItemInMainHand(new ItemStack(Material.DIAMOND_SWORD));
        equipment.setItemInOffHand(new ItemStack(Material.SHIELD));
        
        // Drop chances (0.0 = never, 1.0 = always)
        equipment.setHelmetDropChance(0.0f);
        equipment.setChestplateDropChance(0.0f);
        equipment.setLeggingsDropChance(0.0f);
        equipment.setBootsDropChance(0.0f);
        equipment.setItemInMainHandDropChance(0.0f);
        equipment.setItemInOffHandDropChance(0.0f);
    }
}

Mob AI

Paper AI API

Paper provides enhanced AI control:
import com.destroystokyo.paper.entity.ai.*;
import org.bukkit.entity.Mob;

if (entity instanceof Mob mob) {
    // Disable all AI
    mob.setAware(false);
    
    // Get AI goals
    Set<Goal<?>> targetGoals = mob.getGoals(GoalType.TARGET);
    Set<Goal<?>> normalGoals = mob.getGoals(GoalType.NORMAL);
    
    // Remove specific goal
    for (Goal<?> goal : normalGoals) {
        GoalKey<?> key = goal.getKey();
        if (key.getNamespacedKey().getKey().contains("panic")) {
            mob.removeGoal(key);
        }
    }
    
    // Get all goals
    Collection<Goal<?>> allGoals = mob.getAllGoals();
}

Targeting

if (entity instanceof Mob mob) {
    // Set target
    mob.setTarget(player);
    
    // Get target
    LivingEntity target = mob.getTarget();
    
    // Clear target
    mob.setTarget(null);
}

Specific Entity Types

Zombies

Zombie zombie = world.spawn(location, Zombie.class);

// Baby zombie
zombie.setBaby(true);
boolean isBaby = zombie.isBaby();

// Age (for baby entities)
zombie.setAge(-24000); // Baby for longer

// Convert to drowned
zombie.setConversionTime(100); // Ticks until conversion

Creepers

Creeper creeper = world.spawn(location, Creeper.class);

// Charged creeper
creeper.setPowered(true);

// Explosion radius
creeper.setExplosionRadius(5);

// Max fuse ticks
creeper.setMaxFuseTicks(30);

// Ignite
creeper.ignite();

Villagers

Villager villager = world.spawn(location, Villager.class);

// Profession
villager.setProfession(Villager.Profession.LIBRARIAN);
Villager.Profession profession = villager.getProfession();

// Level
villager.setVillagerLevel(5);

// Experience
villager.setVillagerExperience(100);

// Trades
List<MerchantRecipe> recipes = villager.getRecipes();
MerchantRecipe recipe = new MerchantRecipe(
    new ItemStack(Material.DIAMOND),
    1,  // Max uses
    5,  // XP reward
    0.2f // Price multiplier
);
recipe.addIngredient(new ItemStack(Material.EMERALD, 64));
recipes.add(recipe);
villager.setRecipes(recipes);

Armor Stands

ArmorStand stand = world.spawn(location, ArmorStand.class);

// Visibility
stand.setVisible(false);
stand.setMarker(true); // Small hitbox, no collision

// Arms
stand.setArms(true);

// Base plate
stand.setBasePlate(false);

// Gravity
stand.setGravity(false);

// Pose
EulerAngle angle = new EulerAngle(Math.toRadians(45), 0, 0);
stand.setHeadPose(angle);
stand.setBodyPose(angle);
stand.setLeftArmPose(angle);
stand.setRightArmPose(angle);
stand.setLeftLegPose(angle);
stand.setRightLegPose(angle);

// Equipment
EntityEquipment equipment = stand.getEquipment();
equipment.setHelmet(new ItemStack(Material.PLAYER_HEAD));

Item Frames

ItemFrame frame = world.spawn(location, ItemFrame.class);

// Item
frame.setItem(new ItemStack(Material.DIAMOND_SWORD));

// Rotation
frame.setRotation(Rotation.CLOCKWISE);

// Fixed (cannot be removed)
frame.setFixed(true);

// Visible
frame.setVisible(false);

Minecarts

Minecart minecart = world.spawn(location, Minecart.class);

// Speed
Vector velocity = new Vector(1, 0, 0);
minecart.setVelocity(velocity);

// Max speed
minecart.setMaxSpeed(0.4);

// Slow when empty
minecart.setSlowWhenEmpty(true);

// Derail
minecart.setDerailedVelocityMod(new Vector(0.5, 0.5, 0.5));

Entity Metadata

Store custom data on entities:
import org.bukkit.persistence.PersistentDataContainer;
import org.bukkit.persistence.PersistentDataType;

// Get persistent data container
PersistentDataContainer data = entity.getPersistentDataContainer();

// Store data
NamespacedKey key = new NamespacedKey(plugin, "custom_data");
data.set(key, PersistentDataType.STRING, "value");

// Retrieve data
String value = data.get(key, PersistentDataType.STRING);

// Check if has data
if (data.has(key, PersistentDataType.STRING)) {
    // Has data
}

// Remove data
data.remove(key);

Entity Tracking

Control which players can see entities:
import io.papermc.paper.entity.TeleportFlag;

// Get tracking players
Set<Player> tracking = entity.getTrackedPlayers();

// Check if player can see entity
boolean canSee = player.canSee(entity);

// Hide entity from player
player.hideEntity(plugin, entity);

// Show entity to player
player.showEntity(plugin, entity);

Entity Removal

// Remove entity
entity.remove();

// Check if removed
boolean isDead = entity.isDead();

// Get all entities
Collection<Entity> entities = world.getEntities();

// Get entities by type
Collection<Zombie> zombies = world.getEntitiesByClass(Zombie.class);

// Get nearby entities
Collection<Entity> nearby = world.getNearbyEntities(location, 10, 10, 10);

Best Practices

Use world.spawn(location, Class, Consumer) to configure entities atomically before they’re spawned.
Always check if an entity is a specific type before casting: if (entity instanceof Zombie zombie)
Entities with setAI(false) or setAware(false) won’t move or react to players.

Next Steps

Events API

Handle entity events

World API

World and environment control