Files
Documentation/content/world/entities/flocking-behavior.en.md
2026-01-20 20:33:59 +01:00

5.9 KiB

title, type, weight
title type weight
Flocking Behavior docs 10

The flock system enables NPCs to form and behave as coordinated groups.

Package: com.hypixel.hytale.server.flock

Overview

Flocks are entity-based groups that allow NPCs to:

  • Move and act as a coordinated unit
  • Share damage information across members
  • Spawn in configurable group sizes
  • Have designated leaders

Architecture

Flock System
├── Components
│   ├── Flock - Group entity component
│   ├── FlockMembership - Member reference
│   └── PersistentFlockData - Saved flock data
├── Assets
│   ├── FlockAsset - Flock configuration
│   ├── RangeSizeFlockAsset - Range-based size
│   └── WeightedSizeFlockAsset - Weighted size
├── Systems
│   ├── FlockSystems - Core flock logic
│   ├── FlockMembershipSystems - Member management
│   └── FlockDeathSystems - Death handling
└── NPC Components
    ├── BodyMotionFlock - Movement behavior
    ├── ActionFlockJoin/Leave - Join/leave actions
    └── SensorFlockLeader - Leader detection

Flock Component

The flock entity holds shared group state:

public class Flock implements Component<EntityStore> {
    // Shared damage data for combat coordination
    private DamageData currentDamageData;
    private DamageData nextDamageData;

    // Leader-specific damage data
    private DamageData currentLeaderDamageData;
    private DamageData nextLeaderDamageData;

    // Persistent group configuration
    private PersistentFlockData flockData;

    // Removal status
    public enum FlockRemovedStatus {
        NOT_REMOVED,
        DISSOLVED,
        UNLOADED
    }
}

FlockMembership Component

Each NPC member has a membership component:

public class FlockMembership implements Component<EntityStore> {
    // Reference to the flock entity
    private Ref<EntityStore> flockRef;
}

Creating Flocks

Spawn with Flock

// Spawn an NPC with its flock
Ref<EntityStore> flockRef = FlockPlugin.trySpawnFlock(
    npcRef,           // Initial NPC reference
    npc,              // NPC component
    store,            // Entity store
    roleIndex,        // NPC role index
    position,         // Spawn position
    rotation,         // Spawn rotation
    flockDefinition,  // FlockAsset config (determines size)
    postSpawnCallback // Called for each spawned member
);

Create Empty Flock

// Create flock entity for manual member management
Ref<EntityStore> flockRef = FlockPlugin.createFlock(store, role);

// Or with explicit configuration
Ref<EntityStore> flockRef = FlockPlugin.createFlock(
    store,
    flockAsset,       // FlockAsset configuration
    allowedRoles      // Roles that can join
);

Join Existing Flock

// Add NPC to existing flock
FlockMembershipSystems.join(npcRef, flockRef, store);

Flock Assets

FlockAsset

Base configuration for flocks:

public class FlockAsset {
    // Asset identifier
    private String id;

    // Pick group size for spawning
    public abstract int pickFlockSize();
}

RangeSizeFlockAsset

Flock with random size in range:

{
  "Type": "RangeSize",
  "Id": "wolf_pack",
  "MinSize": 3,
  "MaxSize": 8
}

WeightedSizeFlockAsset

Flock with weighted random size:

{
  "Type": "WeightedSize",
  "Id": "deer_herd",
  "Sizes": [
    { "Size": 2, "Weight": 1 },
    { "Size": 4, "Weight": 2 },
    { "Size": 6, "Weight": 1 }
  ]
}

NPC Core Components

BodyMotionFlock

Controls flocking movement behavior:

{
  "Type": "Flock",
  "SeparationWeight": 1.5,
  "AlignmentWeight": 1.0,
  "CohesionWeight": 1.0
}

ActionFlockJoin

Join a flock:

{
  "Type": "JoinFlock",
  "FlockId": "wolf_pack"
}

ActionFlockLeave

Leave current flock:

{
  "Type": "LeaveFlock"
}

SensorFlockLeader

Detect flock leader:

{
  "Type": "FlockLeader",
  "Output": "leader_ref"
}

EntityFilterFlock

Filter entities by flock membership:

{
  "Type": "Flock",
  "IncludeSelf": false,
  "OnlyMembers": true
}

Damage Sharing

Flocks share combat information:

// Get damage data for the flock
Flock flock = store.getComponent(flockRef, Flock.getComponentType());
DamageData damageData = flock.getDamageData();

// Track kills for the flock
flock.onTargetKilled(componentAccessor, targetRef);

Double Buffering

Damage data uses double buffering to avoid race conditions:

// Called each tick
flock.swapDamageDataBuffers();
// currentDamageData contains last tick's data
// nextDamageData accumulates current tick's data

Conditions

FlockSizeCondition

Check flock size in decision making:

{
  "Type": "FlockSize",
  "Min": 2,
  "Max": 10
}

Plugin Access

FlockPlugin flockPlugin = FlockPlugin.get();

// Component types
ComponentType<EntityStore, Flock> flockType =
    flockPlugin.getFlockComponentType();
ComponentType<EntityStore, FlockMembership> membershipType =
    flockPlugin.getFlockMembershipComponentType();
ComponentType<EntityStore, PersistentFlockData> dataType =
    flockPlugin.getPersistentFlockDataComponentType();

Utility Methods

// Check if entity is in a flock
boolean isMember = FlockPlugin.isFlockMember(npcRef, store);

// Get flock reference from entity
Ref<EntityStore> flockRef = FlockPlugin.getFlockReference(npcRef, store);

// Get flock component from entity
Flock flock = FlockPlugin.getFlock(store, npcRef);

Flock Spawning Behavior

When spawning a flock:

  1. Initial NPC is created
  2. Flock entity is created with membership
  3. Additional members spawn at same location
  4. Members spread with slight random offset
  5. Each member joins the flock
// Members spawn with random offset
memberTransform.getPosition().assign(
    x + RandomExtra.randomRange(-0.5, 0.5),
    offsetY,
    z + RandomExtra.randomRange(-0.5, 0.5)
);