Entity System
Hytale uses an Entity Component System (ECS) architecture. Entities are lightweight identifiers; all data lives in components attached to them.
See also: Entity Events for entity lifecycle events, ECS Events for component-level events
Entity References (Ref<EntityStore>)
Section titled “Entity References (Ref<EntityStore>)”The primary way to reference entities. A Ref is a lightweight handle that points to an entity in a Store.
Ref<EntityStore> ref = ...;
// check validity before useif (ref.isValid()) { TransformComponent transform = store.getComponent(ref, TransformComponent.getComponentType()); Vector3d position = transform.getPosition();}Key methods:
isValid()- Returnstrueif the entity still existsgetStore()- Returns theStorethis ref belongs togetIndex()- Internal index (avoid direct use)
Refs become invalid when the entity is removed. Always check isValid() before accessing components.
Persistent References (PersistentRef)
Section titled “Persistent References (PersistentRef)”For references that survive entity unload/reload cycles, use PersistentRef. It stores the entity’s UUID and lazily resolves the Ref when needed.
PersistentRef persistentRef = new PersistentRef();persistentRef.setEntity(ref, componentAccessor);
// later, even after reload:Ref<EntityStore> resolved = persistentRef.getEntity(componentAccessor);if (resolved != null && resolved.isValid()) { // use the entity}Holders (Holder<EntityStore>)
Section titled “Holders (Holder<EntityStore>)”A Holder is a temporary container for an entity’s components, used during spawning and serialization. Think of it as a blueprint for an entity before it’s added to the world.
Holder<EntityStore> holder = EntityStore.REGISTRY.newHolder();holder.addComponent(TransformComponent.getComponentType(), new TransformComponent(position, rotation));holder.addComponent(ModelComponent.getComponentType(), modelComponent);// ... add more components
Ref<EntityStore> ref = store.addEntity(holder, AddReason.SPAWN);See Spawning for the full spawning workflow.
EntityStore
Section titled “EntityStore”Each World has an EntityStore that manages all entities in that world.
World world = ...;EntityStore entityStore = world.getEntityStore();Store<EntityStore> store = entityStore.getStore();See Queries for finding entities by UUID, network ID, or iteration.
Thread Safety
Section titled “Thread Safety”Entity operations must happen on the world’s tick thread. Use world.execute() for cross-thread access:
world.execute(() -> { if (ref.isValid()) { // safe to access entity here TransformComponent t = store.getComponent(ref, TransformComponent.getComponentType()); }});See Threading for more on Hytale’s threading model.