7 min

Entities

Working with entities, living entities, and spawning in Hytale.

Entity Hierarchy

Hytale uses a component-based entity system. The core hierarchy is:

1Entity (abstract)
2├── LivingEntity (abstract)
3│ └── Player
4└── BlockEntity

NPCs and mobs implement INonPlayerCharacter interface on top of LivingEntity.

Entity Class

The base Entity class provides core functionality for all entities.

1// Core Entity methods
2public abstract class Entity {
3 // Identity
4 public UUID getUuid();
5 public int getNetworkId();
6 public String getLegacyDisplayName();
7
8 // World
9 public World getWorld();
10 public void loadIntoWorld(World world);
11 public void unloadFromWorld();
12 public boolean wasRemoved();
13
14 // Transform
15 public TransformComponent getTransformComponent();
16 public void setTransformComponent(TransformComponent transform);
17 public void moveTo(Ref ref, double x, double y, double z,
18 ComponentAccessor accessor);
19
20 // Lifecycle
21 public boolean remove(); // Remove from world
22 public void markNeedsSave();
23
24 // Reference system
25 public Ref getReference();
26 public void setReference(Ref ref);
27
28 // Collision
29 public boolean isCollidable();
30 public boolean isHiddenFromLivingEntity(...);
31}

LivingEntity Class

LivingEntity extends Entity with inventory, stats, and other living creature features.

1public abstract class LivingEntity extends Entity {
2 // Inventory
3 public Inventory getInventory();
4 public Inventory setInventory(Inventory inventory);
5 public Inventory setInventory(Inventory inventory, boolean notify);
6
7 // Stats
8 public StatModifiersManager getStatModifiersManager();
9
10 // Fall damage
11 public double getCurrentFallDistance();
12 public void setCurrentFallDistance(double distance);
13
14 // Item durability
15 public boolean canDecreaseItemStackDurability(...);
16 public ItemStackSlotTransaction decreaseItemStackDurability(...);
17 public ItemStackSlotTransaction updateItemStackDurability(...);
18
19 // Equipment
20 public void invalidateEquipmentNetwork();
21 public boolean consumeEquipmentNetworkOutdated();
22
23 // Movement (inherited from Entity)
24 public void moveTo(...);
25}

Player Class

The Player class extends LivingEntity and implementsCommandSender and PermissionHolder.

1public class Player extends LivingEntity
2 implements CommandSender, PermissionHolder {
3
4 // Connection
5 public PacketHandler getPlayerConnection();
6
7 // Managers
8 public WindowManager getWindowManager();
9 public PageManager getPageManager();
10 public HudManager getHudManager();
11 public HotbarManager getHotbarManager();
12 public WorldMapTracker getWorldMapTracker();
13
14 // Messaging
15 public void sendMessage(Message message);
16
17 // Permissions
18 public boolean hasPermission(String permission);
19 public boolean hasPermission(String permission, boolean defaultValue);
20
21 // View
22 public int getViewRadius();
23 public int getClientViewRadius();
24 public void setClientViewRadius(int radius);
25
26 // Spawn
27 public boolean isFirstSpawn();
28 public void setFirstSpawn(boolean first);
29 public boolean hasSpawnProtection();
30 public long getSinceLastSpawnNanos();
31
32 // Reference
33 public PlayerRef getPlayerRef();
34
35 // Config data
36 public PlayerConfigData getPlayerConfigData();
37 public CompletableFuture saveConfig(World world, Holder holder);
38}

Spawning Entities

Use World.spawnEntity() to spawn entities at a position.

1// Spawning an entity
2World world = player.getWorld();
3Vector3d position = new Vector3d(100, 64, 100);
4Vector3f rotation = new Vector3f(0, 0, 0); // yaw, pitch, roll
5
6world.execute(() -> {
7 // spawnEntity returns the spawned entity
8 MyEntity entity = world.spawnEntity(
9 new MyEntity(world), // Entity instance
10 position, // Spawn position
11 rotation // Initial rotation
12 );
13});

addEntity vs spawnEntity

methoduse case
spawnEntity(entity, pos, rot)Normal spawning - fires spawn events
addEntity(entity, pos, rot, reason)Low-level add with custom AddReason
1// Using addEntity with AddReason
2world.addEntity(
3 entity,
4 position,
5 rotation,
6 AddReason.SPAWN // or LOAD, etc.
7);

INonPlayerCharacter Interface

NPCs and mobs implement this interface for type identification:

1public interface INonPlayerCharacter {
2 String getNPCTypeId(); // e.g. "trork_warrior", "Chicken"
3 int getNPCTypeIndex(); // Internal type index
4}

Spawning NPCs

Use NPCPlugin.get().spawnNPC() to spawn NPCs programmatically. This is the correct way to spawn mobs and creatures from plugins.

Basic NPC Spawning

1import com.hypixel.hytale.server.npc.NPCPlugin;
2import com.hypixel.hytale.server.core.universe.world.npc.INonPlayerCharacter;
3import com.hypixel.hytale.server.core.universe.world.storage.EntityStore;
4import com.hypixel.hytale.component.Ref;
5import com.hypixel.hytale.component.Store;
6import com.hypixel.hytale.math.vector.Vector3d;
7import com.hypixel.hytale.math.vector.Vector3f;
8import it.unimi.dsi.fastutil.Pair;
9
10// Get the world's entity store
11World world = player.getWorld();
12
13world.execute(() -> {
14 NPCPlugin npcPlugin = NPCPlugin.get();
15 Store store = world.getEntityStore().getStore();
16
17 // Spawn position and rotation
18 Vector3d position = new Vector3d(100, 64, 100);
19 Vector3f rotation = new Vector3f(0, 0, 0); // yaw, pitch, roll
20
21 // spawnNPC returns a Pair
22 Pair, INonPlayerCharacter> result = npcPlugin.spawnNPC(
23 store, // Entity store
24 "Chicken", // NPC type ID (from assets)
25 null, // Variant (null for default)
26 position, // Spawn position
27 rotation // Initial rotation
28 );
29
30 if (result != null) {
31 Ref entityRef = result.first();
32 INonPlayerCharacter npc = result.second();
33
34 // NPC is now spawned and active
35 String typeId = npc.getNPCTypeId(); // "Chicken"
36 }
37});

NPCPlugin.spawnNPC() Signature

1public Pair, INonPlayerCharacter> spawnNPC(
2 Store store, // From world.getEntityStore().getStore()
3 String npcTypeId, // NPC type identifier (e.g., "Chicken", "trork_warrior")
4 String variant, // Variant name or null for default
5 Vector3d position, // World position
6 Vector3f rotation // Rotation (yaw, pitch, roll in radians)
7)

Return Value

parttypedescription
result.first()Ref<EntityStore>Reference for component access
result.second()INonPlayerCharacterThe spawned NPC entity
npc type ids
NPC type IDs come from asset definitions. Common examples include "Chicken", "Kweebec", "trork_warrior". Check your asset files for available types.

Freezing NPCs

Use the Frozen component to prevent an NPC from moving, attacking, or performing AI behaviors. This is essential for camera anchors, decorative NPCs, or cutscene actors.

Adding the Frozen Component

1import com.hypixel.hytale.server.core.entity.Frozen;
2
3// After spawning the NPC...
4Pair, INonPlayerCharacter> result = npcPlugin.spawnNPC(...);
5
6if (result != null) {
7 Ref entityRef = result.first();
8
9 // Add the Frozen component to stop all NPC behavior
10 store.addComponent(entityRef, Frozen.getComponentType(), Frozen.get());
11
12 // The NPC is now completely frozen:
13 // - No movement
14 // - No AI behaviors
15 // - No animations (idle state)
16}

Frozen Component API

1// Frozen is a singleton component
2public class Frozen {
3 public static ComponentType getComponentType();
4 public static Frozen get(); // Returns the singleton instance
5}
use case: camera anchors
When using NPCs as camera attachment points (see Camera docs), always addFrozen to prevent the NPC from walking away or triggering AI.

Getting Network ID

The network ID is required for camera attachment and other network operations. Cast INonPlayerCharacter to NPCEntity to access it.

1import com.hypixel.hytale.server.npc.entities.NPCEntity;
2
3// After spawning...
4INonPlayerCharacter npc = result.second();
5
6// Cast to NPCEntity to get network ID
7if (npc instanceof NPCEntity) {
8 NPCEntity entity = (NPCEntity) npc;
9 int networkId = entity.getNetworkId();
10
11 // Use networkId for camera attachment:
12 // settings.attachedToEntityId = networkId;
13}
deprecation note
getNetworkId() may be marked as deprecated but still works correctly. It's required for camera attachment via ServerCameraSettings.attachedToEntityId.

Removing NPCs

Use the remove() method on NPCEntity to despawn.

1// Store the NPC reference
2private INonPlayerCharacter spawnedNpc;
3
4// Later, when you want to remove it...
5if (spawnedNpc != null && spawnedNpc instanceof NPCEntity) {
6 NPCEntity entity = (NPCEntity) spawnedNpc;
7
8 world.execute(() -> {
9 if (!entity.wasRemoved()) {
10 entity.remove();
11 }
12 });
13}

Complete NPC Example

NPCSpawnExample.javajava
1import com.hypixel.hytale.server.core.plugin.JavaPlugin;
2import com.hypixel.hytale.server.core.universe.world.World;
3import com.hypixel.hytale.server.core.universe.PlayerRef;
4import com.hypixel.hytale.server.core.universe.world.npc.INonPlayerCharacter;
5import com.hypixel.hytale.server.core.universe.world.storage.EntityStore;
6import com.hypixel.hytale.server.npc.NPCPlugin;
7import com.hypixel.hytale.server.npc.entities.NPCEntity;
8import com.hypixel.hytale.server.core.entity.Frozen;
9import com.hypixel.hytale.component.Ref;
10import com.hypixel.hytale.component.Store;
11import com.hypixel.hytale.math.vector.Vector3d;
12import com.hypixel.hytale.math.vector.Vector3f;
13import com.hypixel.hytale.math.vector.Transform;
14import it.unimi.dsi.fastutil.Pair;
15
16public class NPCSpawnExample extends JavaPlugin {
17
18 private INonPlayerCharacter spawnedNpc;
19 private Ref npcRef;
20
21 public void spawnFrozenNPC(PlayerRef player, World world) {
22 // Calculate spawn position in front of player
23 Transform transform = player.getTransform();
24 Vector3d playerPos = transform.getPosition();
25 float yaw = transform.getRotation().getYaw();
26
27 double spawnX = playerPos.getX() - Math.sin(yaw) * 3;
28 double spawnZ = playerPos.getZ() - Math.cos(yaw) * 3;
29
30 Vector3d spawnPos = new Vector3d(spawnX, playerPos.getY(), spawnZ);
31 Vector3f spawnRot = new Vector3f(0, yaw + (float)Math.PI, 0); // Face player
32
33 world.execute(() -> {
34 NPCPlugin npcPlugin = NPCPlugin.get();
35 Store store = world.getEntityStore().getStore();
36
37 Pair, INonPlayerCharacter> result = npcPlugin.spawnNPC(
38 store, "Chicken", null, spawnPos, spawnRot
39 );
40
41 if (result != null) {
42 npcRef = result.first();
43 spawnedNpc = result.second();
44
45 // Freeze the NPC
46 store.addComponent(npcRef, Frozen.getComponentType(), Frozen.get());
47
48 // Get network ID for camera attachment
49 int networkId = ((NPCEntity) spawnedNpc).getNetworkId();
50 getLogger().info("Spawned frozen NPC with network ID: " + networkId);
51 }
52 });
53 }
54
55 public void removeNPC(World world) {
56 if (spawnedNpc != null && spawnedNpc instanceof NPCEntity) {
57 NPCEntity entity = (NPCEntity) spawnedNpc;
58 world.execute(() -> {
59 if (!entity.wasRemoved()) {
60 entity.remove();
61 }
62 });
63 spawnedNpc = null;
64 npcRef = null;
65 }
66 }
67}

Getting Entities

1World world = player.getWorld();
2
3// Get all players in world
4List<Player> players = world.getPlayers();
5int playerCount = world.getPlayerCount();
6
7// Get entity by UUID
8Entity entity = world.getEntity(someUUID);
9
10// Get entity reference by UUID
11Ref ref = world.getEntityRef(someUUID);
12
13// Get player refs
14Collection playerRefs = world.getPlayerRefs();

Removing Entities

1// Remove an entity from the world
2world.execute(() -> {
3 boolean wasRemoved = entity.remove();
4
5 // Check if already removed
6 if (entity.wasRemoved()) {
7 // Entity is gone
8 }
9});
entityremoveevent
When entities are removed, EntityRemoveEvent fires. There is no direct EntityDeathEvent - useEntityRemoveEvent and check the removal reason.

Entity Components

Entities use the component system for data storage. Common components:

componentpurpose
TransformComponentPosition, rotation, scale
MovementStatesComponentWalking, sprinting, jumping states
EffectControllerComponentActive effects (buffs/debuffs)
UUIDComponentUnique identifier storage
1// Access transform component
2TransformComponent transform = entity.getTransformComponent();
3
4// Using the reference system for components
5Ref ref = entity.getReference();
6EntityStore store = ref.getStore();
7
8// Get component through accessor
9ComponentAccessor accessor = world.getEntityStore();
10// ... use accessor to read/write components

Quick Reference

EntityExample.javajava
1public class EntityExample extends JavaPlugin {
2
3 @Override
4 protected void start() {
5 getEventRegistry().register(
6 PlayerConnectEvent.class,
7 this::onPlayerConnect
8 );
9 }
10
11 private void onPlayerConnect(PlayerConnectEvent event) {
12 Player player = event.getPlayer();
13 World world = player.getWorld();
14
15 // Log player info
16 UUID uuid = player.getUuid();
17 int networkId = player.getNetworkId();
18 getLogger().info("Player " + uuid + " connected (network: " + networkId + ")");
19
20 // Access inventory
21 Inventory inventory = player.getInventory();
22
23 // Check permissions
24 if (player.hasPermission("example.vip")) {
25 // VIP handling
26 }
27
28 // Get position via transform
29 world.execute(() -> {
30 TransformComponent transform = player.getTransformComponent();
31 // transform.pos contains position
32 });
33 }
34}