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

218 lines
4.8 KiB
Markdown

---
title: NPC Basics
type: docs
weight: 1
---
This guide covers the fundamentals of creating and configuring NPCs in Hytale.
**Package:** `com.hypixel.hytale.server.npc`
## NPCEntity Class
`NPCEntity` is the base class for all non-player characters. It extends the entity hierarchy and provides NPC-specific functionality.
```java
public class NPCEntity extends LivingEntity {
// Core NPC functionality
private Blackboard blackboard;
private Role role;
private DecisionMaker decisionMaker;
private MotionController motionController;
}
```
### Creating an NPC
NPCs are typically created through the asset system or spawned programmatically:
```java
// Spawn NPC from asset
NPCEntity npc = world.spawnNPC("villager", position);
// Configure NPC after spawn
npc.setRole(customRole);
npc.getBlackboard().setHomePosition(position);
```
## NPC Assets
NPC definitions are configured through YAML asset files:
```yaml
# npc/villager.yaml
Type: NPC
Id: villager
DisplayName: "Villager"
Model: models/characters/villager
Role: roles/villager_role
Stats:
Health: 100
Speed: 3.0
Components:
- Type: NPCBrain
- Type: Interactable
- Type: DialogueCapable
```
### Asset Structure
| Property | Type | Description |
|----------|------|-------------|
| `Type` | String | Must be "NPC" |
| `Id` | String | Unique identifier |
| `DisplayName` | String | Display name |
| `Model` | String | Model asset reference |
| `Role` | String | Default role reference |
| `Stats` | Object | Base statistics |
| `Components` | Array | Component configurations |
## NPC Roles
Roles define the behavioral template for an NPC. They specify what instructions, sensors, and actions the NPC can use.
```yaml
# roles/villager_role.yaml
Type: Role
Id: villager_role
Instructions:
- Wander
- ReactToThreats
- Interact
Sensors:
- Type: VisualSensor
Range: 15.0
- Type: AudioSensor
Range: 10.0
Actions:
- Walk
- Run
- Talk
- Trade
```
### Role Components
```java
public class Role {
private List<Instruction> instructions;
private List<Sensor> sensors;
private List<Action> availableActions;
// Get active instruction
public Instruction getCurrentInstruction();
// Check if action is available
public boolean hasAction(String actionId);
}
```
## NPC Systems
The NPC module registers several ECS systems for processing NPC behavior:
| System | Description |
|--------|-------------|
| `NPCBrainSystem` | Processes AI decisions |
| `NPCMovementSystem` | Handles movement updates |
| `NPCSensorSystem` | Processes sensor inputs |
| `NPCAnimationSystem` | Updates animations |
| `NPCInteractionSystem` | Handles interactions |
### System Registration
```java
public class NPCPlugin extends JavaPlugin {
@Override
public void start() {
// Systems are auto-registered by NPCPlugin
// Custom systems can be added:
getEntityStoreRegistry().registerSystem(
new CustomNPCSystem()
);
}
}
```
## NPC Utilities
The `util/` package provides helper classes:
### NPCUtils
```java
// Find nearest NPC
NPCEntity nearest = NPCUtils.findNearest(position, world, 50.0);
// Get all NPCs in area
List<NPCEntity> npcsInArea = NPCUtils.getNPCsInRadius(
position, world, 25.0
);
// Check line of sight
boolean canSee = NPCUtils.hasLineOfSight(npc, target);
```
### NPCSpawner
```java
// Spawn with configuration
NPCEntity npc = NPCSpawner.spawn(
world,
"villager",
position,
config -> {
config.setRole("merchant");
config.setFaction("town");
}
);
```
## Common Patterns
### Setting Up an NPC Shop
```java
NPCEntity merchant = world.spawnNPC("merchant", shopPosition);
merchant.getBlackboard().set("shop_inventory", inventory);
merchant.getBlackboard().set("is_merchant", true);
merchant.setRole(merchantRole);
```
### Creating a Guard NPC
```java
NPCEntity guard = world.spawnNPC("guard", guardPosition);
Blackboard bb = guard.getBlackboard();
bb.setPatrolPath(patrolWaypoints);
bb.setHostileToFactions(List.of("bandits", "monsters"));
guard.setRole(guardRole);
```
### NPC with Custom Behavior
```java
NPCEntity custom = world.spawnNPC("custom_npc", position);
// Add custom component
custom.getEntityStore().addComponent(new CustomBehaviorComponent());
// Set custom decision maker
custom.setDecisionMaker(new CustomDecisionMaker());
```
## Best Practices
{{< callout type="info" >}}
**NPC Guidelines:**
- Always set a Role for NPCs to define their behavior
- Use the Blackboard for all NPC state storage
- Configure appropriate sensors for the NPC's awareness needs
- Use the asset system for NPC definitions when possible
- Consider performance with large numbers of NPCs
{{< /callout >}}
{{< callout type="warning" >}}
**Thread Safety:** NPC operations should be performed on the world's ticking thread. Use `world.isInThread()` to verify before making changes.
{{< /callout >}}