Skip to content

Interaction System

The interaction system handles all player interactions with blocks, entities, and items through a chain-based execution model with server-client synchronization.

The interaction system is the framework that powers all player actions in Hytale - from swinging a sword to placing blocks to drinking potions. When a player presses a button, the system:

  1. Resolves which interaction to run based on held item, target, and input type
  2. Executes a chain of operations (animations, hit detection, damage, effects)
  3. Synchronizes state between client and server for smooth gameplay
flowchart LR
    subgraph Input["Player Input"]
        MouseClick
        KeyPress
    end

    subgraph Manager["InteractionManager"]
        Resolve["Resolves Root<br/>Interaction"]
    end

    subgraph Chain["InteractionChain"]
        Track["Tracks State<br/>Per-Entity"]
    end

    subgraph Ops["Operations"]
        PlaceBlock
        DamageEntity
        ApplyEffect
        More["..."]
    end

    Input --> Manager
    Manager --> Chain
    Chain --> Ops
  1. Input Detection - Player clicks or presses an action key
  2. Root Resolution - System finds the RootInteraction for the held item and interaction type
  3. Chain Creation - An InteractionChain is created to track execution state
  4. Operation Execution - Operations in the chain execute sequentially (or in parallel for forks)
  5. Client-Server Sync - Results are synchronized between client and server
  6. Completion - Chain completes, cooldowns are applied
PackagePurpose
com.hypixel.hytale.server.core.modules.interactionMain module, InteractionModule plugin
com.hypixel.hytale.server.core.entityInteractionManager, InteractionChain, InteractionContext
com.hypixel.hytale.server.core.modules.interaction.interaction.configInteraction base classes and configs
com.hypixel.hytale.server.core.modules.interaction.interaction.operationOperation interface and builders
com.hypixel.hytale.protocolInteractionType enum, sync data, packets

Every interaction follows a consistent lifecycle managed by the framework:

When an interaction begins:

  • InteractionChain is created with initial state
  • InteractionContext is populated with held item, target info, metadata
  • firstRun = true flag is set for the first tick

Each frame while the interaction runs:

  • tick() (final) handles framework validation and state management
  • tick0() (abstract) is called for your custom logic
  • simulateTick0() runs on client for prediction
  • InteractionState is updated (NotFinished, Finished, Failed, Skip, ItemChanged)

When the interaction completes:

  • Cooldowns are applied via CooldownHandler
  • Next operations in the chain execute
  • Forked chains continue independently
  • Completion callbacks fire

Per-entity component managing all interaction chains for that entity:

public class InteractionManager implements Component<EntityStore> {
// Max interaction reach distance
public static final double MAX_REACH = 8.0;
// Start an interaction chain
public boolean tryStartChain(
Ref<EntityStore> ref,
CommandBuffer<EntityStore> commandBuffer,
InteractionType type,
InteractionContext context,
RootInteraction rootInteraction
);
// Process mouse/keyboard input
public void doMouseInteraction(
Ref<EntityStore> ref,
MouseInteraction mouseInteraction,
ComponentAccessor<EntityStore> componentAccessor,
CommandBuffer<EntityStore> commandBuffer
);
// Tick all active chains
public void tick();
}

Represents the execution state of a running interaction:

public class InteractionChain {
public InteractionState getServerState();
public InteractionState getClientState();
public InteractionType getType();
public RootInteraction getRootInteraction();
public InteractionContext getContext();
public int getOperationCounter();
// Fork a new chain from this one
public InteractionChain fork(
InteractionContext forkedContext,
RootInteraction forkedRootInteraction
);
}

Execution context passed to all operations:

public class InteractionContext {
public Ref<EntityStore> getEntity();
public Ref<EntityStore> getOwningEntity();
public ItemStack getHeldItem();
public byte getHeldItemSlot();
public DynamicMetaStore<InteractionContext> getMetaStore();
public DynamicMetaStore<Interaction> getInstanceStore();
public InteractionChain getChain();
public InteractionSyncData getState();
@Nullable
public InteractionSyncData getClientState();
public InteractionChain fork(
InteractionContext context,
RootInteraction rootInteraction,
boolean predicted
);
public void jump(Label label);
public Label getLabel(int index);
}

Here’s how interactions flow for a simple sword swing:

1. Item Definition references a RootInteraction:

{
"Interactions": {
"Primary": "Root_Weapon_Sword_Primary"
}
}

2. RootInteraction defines the entry point:

{
"RequireNewClick": true,
"Cooldown": { "Cooldown": 0.25 },
"Interactions": ["Weapon_Sword_Swing"]
}

3. Interaction Chain executes operations:

Weapon_Sword_Swing (Simple - animation)
Weapon_Sword_Selector (Selector - hit detection)
Weapon_Sword_Damage (DamageEntity - apply damage)

Beginners: Start with Asset-Based Interactions to create custom weapon attacks and abilities using JSON files.

Intermediate: Learn Control Flow Patterns for combos, charging, and parallel effects.

Advanced: Dive into Java Operations for completely custom interaction types.