--- 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 instructions; private List sensors; private List 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 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 >}}