Hytale-documentation.github.io

Interaction System

The Interaction System in Hytale is a powerful, data-driven framework for defining player actions and their effects. Interactions are defined in JSON and handle everything from breaking blocks to using items and triggering abilities.

Architecture Overview

graph TD
    A[Player Action] -->|Client Sends| B[Interaction Packet]
    B -->|Network| C[Server Processes]
    C --> D{Interaction Type?}
    D -->|Block| E[BlockConditionInteraction]
    D -->|Item Use| F[RootInteraction]
    D -->|Entity| G[DamageEntityInteraction]
    E --> H[Execute Interaction Chain]
    F --> H
    G --> H
    H --> I[Apply Effects]
    I --> J[Sync to Clients]

Core Concepts

Interaction Types

The InteractionType enum defines when an interaction can be triggered:

Type Trigger Example Use Case
PRIMARY Left-click / Main action Mining blocks, melee attacks
SECONDARY Right-click / Secondary action Place blocks, use items
TERTIARY Special action button Ability activation
HOLD Continuous hold Charging bows, eating food
RELEASE Button release Fire charged projectile

Interaction Chain

Interactions in Hytale use a chain pattern where multiple actions can be sequenced:

graph LR
    A[Primary Interaction] --> B[Condition Check]
    B -->|Pass| C[Apply Effect]
    C --> D[Chained Interaction]
    D --> E[Next Action]
    B -->|Fail| F[Cancel Chain]

Interaction Components

An interaction definition consists of:

  1. Trigger: InteractionType (PRIMARY, SECONDARY, etc.)
  2. Conditions: Requirements to execute (permissions, state, resources)
  3. Effects: What happens when executed
  4. Chaining: Follow-up interactions
  5. Cooldowns: Prevent spam
  6. Sync: Network synchronization settings

Key Classes

Interaction Base Classes

Specific Interaction Types

From the 71 interaction-related classes found:

Block Interactions

Combat Interactions

Item Interactions

Effect Interactions

State Management

Advanced Patterns

Interaction Configuration

Root Interaction Settings

From RootInteractionSettings and InteractionConfiguration:

{
  "type": "SECONDARY",
  "cooldown": {
    "duration": 1.5,
    "resetOnCancel": true
  },
  "conditions": [
    {
      "type": "MemoriesCondition",
      "requiredLevel": 5
    }
  ],
  "effects": [
    {
      "type": "ApplyEffect",
      "effect": "hytale:speed_boost",
      "duration": 10.0
    }
  ],
  "chainData": {
    "next": "hytale:follow_up_interaction"
  }
}

Interaction Priorities

From InteractionPriority:

When multiple interactions are valid, priority determines execution order:

Interaction Conditions

Interactions can have multiple condition types:

Resource Conditions

State Conditions

Environmental Conditions

Interaction Effects

From InteractionEffects:

Effects are what actually happen when an interaction executes:

Entity Effects

// Apply a status effect to the player
{
  "type": "ApplyEffect",
  "target": "SELF",
  "effect": "hytale:regeneration",
  "duration": 30.0,
  "amplifier": 1
}

World Effects

// Change a block in the world
{
  "type": "ChangeBlock",
  "position": "TARGET",
  "newBlock": "hytale:torch_on",
  "playSound": true
}

Inventory Effects

// Consume an item from inventory
{
  "type": "ModifyInventory",
  "operation": "REMOVE",
  "item": "hytale:apple",
  "amount": 1,
  "slot": "ACTIVE"
}

Interaction Targets

From InteractionTarget:

Interactions can target different entities:

Cooldown System

From InteractionCooldown and IncrementCooldownInteraction:

stateDiagram-v2
    [*] --> Ready
    Ready --> Active: Interaction Triggered
    Active --> Cooldown: Execute Action
    Cooldown --> Ready: Duration Expires
    Cooldown --> Ready: ResetCooldown Called
    Cooldown --> Cooldown: IncrementCooldown

Cooldown Management

// Example: Set a custom cooldown
{
  "type": "IncrementCooldown",
  "cooldownId": "my_plugin:special_ability",
  "duration": 5.0
}

// Reset a cooldown early
{
  "type": "ResetCooldown",
  "cooldownId": "my_plugin:special_ability"
}

Interaction Chaining

From InteractionChainData and ChainingInteraction:

Sequential Chains

Execute interactions one after another:

{
  "interaction": "first_action",
  "chainData": {
    "next": "second_action",
    "delay": 0.5
  }
}

Conditional Chains

From ChainFlagInteraction:

Branch based on success/failure:

{
  "interaction": "try_action",
  "chainData": {
    "onSuccess": "success_action",
    "onFailure": "failure_action"
  }
}

Parallel Execution

From ParallelInteraction:

Run multiple interactions simultaneously:

{
  "type": "ParallelInteraction",
  "interactions": [
    "play_sound",
    "apply_effect",
    "spawn_particles"
  ]
}

Camera Interactions

From CameraInteraction and InteractionCamera:

Interactions can control the camera:

{
  "type": "CameraInteraction",
  "settings": {
    "shake": {
      "intensity": 0.5,
      "duration": 0.3
    }
  }
}

Builder Tool Interactions

From BuilderToolInteraction:

Special interaction type for creative building tools:

These are handled by dedicated builder packets (400+ packet IDs).

Registering Custom Interactions (Plugin API)

Listening to Interactions

@Override
public void setup() {
    // Listen to any interaction event
    getEventRegistry().register(PlayerInteractEvent.class, event -> {
        Player player = event.getPlayer();
        InteractionType type = event.getInteractionType();
        
        if (type == InteractionType.SECONDARY) {
            // Player right-clicked
            ItemStack item = player.getActiveItem();
            
            if (item.getId().equals("my_mod:special_item")) {
                event.setCancelled(true); // Cancel default interaction
                
                // Custom logic here
                player.sendMessage("Special item activated!");
            }
        }
    });
}

Defining Data-Driven Interactions

Interactions are primarily defined in JSON within item/entity definitions:

{
  "id": "my_mod:magic_wand",
  "interactions": {
    "SECONDARY": {
      "type": "RootInteraction",
      "settings": {
        "cooldown": { "duration": 2.0 },
        "conditions": [
          {
            "type": "CooldownCondition",
            "cooldownId": "my_mod:magic_wand"
          }
        ],
        "effects": [
          {
            "type": "ProjectileInteraction",
            "projectile": "my_mod:magic_bolt",
            "speed": 30.0
          },
          {
            "type": "IncrementCooldown",
            "cooldownId": "my_mod:magic_wand",
            "duration": 2.0
          }
        ]
      }
    }
  }
}

Interaction State Management

From InteractionState and InteractionSyncData:

The server tracks interaction states:

State Synchronization

Interaction states must be synced to clients for UI feedback:

AOE (Area of Effect) Interactions

From AOECircleSelector and AOECylinderSelector:

Interactions can affect multiple targets:

{
  "type": "DamageEntity",
  "aoeType": "CIRCLE",
  "radius": 5.0,
  "maxTargets": 10,
  "filters": {
    "excludeSelf": true,
    "targetType": "ENEMY"
  }
}

First Click vs Continuous

From FirstClickInteraction:

Distinguish between:

{
  "type": "FirstClick",
  "initialDelay": 0.0,
  "repeatDelay": 0.5, // 0.5s between subsequent triggers
  "interaction": "attack_action"
}

Network Synchronization

Client → Server

When a player performs an interaction, the client sends:

Server → Client

The server broadcasts interaction results:

Best Practices

Performance

// ❌ Bad: Heavy logic in interaction handler
event.getInteraction().execute(() -> {
    // Complex pathfinding, database queries, etc.
});

// ✅ Good: Offload to async task
event.getInteraction().execute(() -> {
    scheduler.runAsync(() -> {
        // Heavy computation
    });
});

Validation

Always validate interactions server-side:

public boolean validateInteraction(Player player, Interaction interaction) {
    // Check permissions
    if (!player.hasPermission(interaction.getRequiredPermission())) {
        return false;
    }
    
    // Check cooldowns
    if (player.isOnCooldown(interaction.getCooldownId())) {
        return false;
    }
    
    // Check resources (mana, stamina, etc.)
    if (!player.hasResources(interaction.getResourceCost())) {
        return false;
    }
    
    return true;
}

Modularity

Break complex interactions into reusable chains:

{
  "base_attack": {
    "effects": [
      { "type": "DamageEntity", "amount": 10 },
      { "type": "ApplyForce", "magnitude": 5.0 }
    ]
  },
  "critical_attack": {
    "chainData": {
      "bases": ["base_attack"],
      "additionalEffects": [
        { "type": "PlaySound", "sound": "critical_hit" }
      ]
    }
  }
}

Integration with Other Systems

Movement System

Interactions can modify movement:

{
  "type": "ApplyForceInteraction",
  "direction": "FORWARD",
  "magnitude": 20.0,
  "movementType": "INSTANT"
}

ECS Integration

Interactions trigger EntityEventSystem updates:

Permissions

Interactions respect the permission system:

interaction.setRequiredPermission("my_plugin.ability.fireball");

Troubleshooting

Interaction Not Triggering

Interaction Spam

Effects Not Syncing

Advanced Patterns

State Machine Interactions

Create complex state-based systems:

stateDiagram-v2
    [*] --> Idle
    Idle --> Charging: Hold Button
    Charging --> Charged: Full Charge
    Charged --> Release: Release Button
    Release --> Cooldown: Fire Projectile
    Cooldown --> Idle: Cooldown Expires
    Charging --> Idle: Release Early

Combo Systems

Chain interactions based on timing:

// Detect rapid sequential interactions
if (timeSinceLastInteraction <  0.5) {
    comboCounter++;
    if (comboCounter == 3) {
        executeComboFinisher();
    }
}

Context-Sensitive Interactions

Change interaction behavior based on context:

if (player.isSneaking()) {
    // Execute alternate interaction
} else {
    // Execute default interaction
}