Init
This commit is contained in:
217
content/world/entities/npc/npc-basics.en.md
Normal file
217
content/world/entities/npc/npc-basics.en.md
Normal file
@@ -0,0 +1,217 @@
|
||||
---
|
||||
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 >}}
|
||||
Reference in New Issue
Block a user