Skip to content

ECS Architecture ​

The Hytale server uses an Entity Component System (ECS) architecture. Understanding this is fundamental to working with the API.

Core Concepts ​

Entities ​

Entities are unique identifiers (references) for game objects. An entity by itself has no data - it's just an ID.

java
Ref<EntityStore> ref;  // Reference to an entity

Components ​

Components are pure data containers attached to entities. Examples:

  • Player - Player-specific data
  • TransformComponent - Position and rotation
  • EntityStatMap - Health, stamina, etc.
  • DeathComponent - Added when entity dies
java
// Get a component from an entity
Player player = (Player) commandBuffer.getComponent(ref, Player.getComponentType());
TransformComponent transform = (TransformComponent) commandBuffer.getComponent(ref, TransformComponent.getComponentType());

Systems ​

Systems contain the logic. They operate on entities that have specific components. Systems don't store state - they process components.

java
public class MySystem extends EntityTickingSystem {
    @Override
    public Query getQuery() {
        return Player.getComponentType();  // Only run on entities with Player component
    }

    @Override
    public void tick(float dt, int index, ArchetypeChunk chunk, Store store, CommandBuffer buffer) {
        // Logic here runs every tick for matching entities
    }
}

Queries ​

Queries define which entities a system operates on:

java
// Single component
Query query = Player.getComponentType();

// Multiple required components (AND)
Query query = Query.and(Player.getComponentType(), TransformComponent.getComponentType());

// Exclude components (NOT)
Query query = Query.and(Player.getComponentType(), Query.not(DeathComponent.getComponentType()));

Store and CommandBuffer ​

  • Store - Read-only access to the current state
  • CommandBuffer - Queues modifications to be applied safely
java
// Reading (use Store or CommandBuffer)
Player player = (Player) store.getComponent(ref, Player.getComponentType());

// Writing (use CommandBuffer)
commandBuffer.putComponent(ref, SomeComponent.getComponentType(), newComponent);
commandBuffer.removeComponent(ref, SomeComponent.getComponentType());

ArchetypeChunk ​

In tick systems, entities are processed in batches called chunks for performance:

java
public void tick(float dt, int index, ArchetypeChunk chunk, Store store, CommandBuffer buffer) {
    // Get component for this specific entity in the chunk
    Player player = (Player) chunk.getComponent(index, Player.getComponentType());

    // Get the entity reference
    Ref<EntityStore> ref = chunk.getReferenceTo(index);
}

See Also ​

Unofficial documentation · Any questions? Found a mistake? Have something you want documented? Join the Discord server at the top and let us know in #hytale!