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

303 lines
5.9 KiB
Markdown

---
title: Flocking Behavior
type: docs
weight: 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:
```java
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:
```java
public class FlockMembership implements Component<EntityStore> {
// Reference to the flock entity
private Ref<EntityStore> flockRef;
}
```
## Creating Flocks
### Spawn with Flock
```java
// 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
```java
// 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
```java
// Add NPC to existing flock
FlockMembershipSystems.join(npcRef, flockRef, store);
```
## Flock Assets
### FlockAsset
Base configuration for flocks:
```java
public class FlockAsset {
// Asset identifier
private String id;
// Pick group size for spawning
public abstract int pickFlockSize();
}
```
### RangeSizeFlockAsset
Flock with random size in range:
```json
{
"Type": "RangeSize",
"Id": "wolf_pack",
"MinSize": 3,
"MaxSize": 8
}
```
### WeightedSizeFlockAsset
Flock with weighted random size:
```json
{
"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:
```json
{
"Type": "Flock",
"SeparationWeight": 1.5,
"AlignmentWeight": 1.0,
"CohesionWeight": 1.0
}
```
### ActionFlockJoin
Join a flock:
```json
{
"Type": "JoinFlock",
"FlockId": "wolf_pack"
}
```
### ActionFlockLeave
Leave current flock:
```json
{
"Type": "LeaveFlock"
}
```
### SensorFlockLeader
Detect flock leader:
```json
{
"Type": "FlockLeader",
"Output": "leader_ref"
}
```
### EntityFilterFlock
Filter entities by flock membership:
```json
{
"Type": "Flock",
"IncludeSelf": false,
"OnlyMembers": true
}
```
## Damage Sharing
Flocks share combat information:
```java
// 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:
```java
// 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:
```json
{
"Type": "FlockSize",
"Min": 2,
"Max": 10
}
```
## Plugin Access
```java
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
```java
// 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
```java
// Members spawn with random offset
memberTransform.getPosition().assign(
x + RandomExtra.randomRange(-0.5, 0.5),
offsetY,
z + RandomExtra.randomRange(-0.5, 0.5)
);
```