The NPC surface provides helpers for spawning NPC entities, querying their role and variant data, and asserting on despawn state. It builds on WorldTestContext and adds NPC-specific operations through NPCTestAdapter and NPCAssert.
NPCs are the living inhabitants of Hytale - Kweebecs, Trork Warriors, Outlander Hunters, and any custom roles your mod defines. Testing NPCs is about verifying that the right creatures spawn with the right properties and behave as expected.
NPC role names like Trork_Warrior and Kweebec_Sapling are examples from Hytale’s default content. Your mod’s NPCs will have their own role names. If a role name is not recognized, spawnEntity falls back to creating an empty entity with a TransformComponent. Use spawnNPC when you need to guarantee the NPC type is correct - it throws an error if the role is invalid.
spawnEntity vs spawnNPC
Understanding the difference between these two methods is important:
ctx.spawnEntity("Kweebec_Sapling", x, y, z) - Attempts to spawn via NPCPlugin first. If it fails, falls back to creating an empty entity with no components. The empty entity will have no health, no AI, and no model. This silent fallback can make tests pass when they should fail.
ctx.spawnNPC("Kweebec_Sapling", x, y, z) - Directly calls NPCPlugin to spawn a fully initialized NPC. If the role name is not recognized, it fails explicitly rather than silently creating an empty entity. This is the preferred method for NPC tests.
Always use spawnNPC when you need a real NPC with health, AI, and model components. Use spawnEntity only when you intentionally want the fallback behavior for generic entity testing.
Complete Example Suite
Adapter Methods
| Method | Parameters | Returns | Description |
|---|
spawnNPC | String role, double x, double y, double z | Object | Spawn a fully initialized NPC at the given position |
spawnNPC | String role, String variant, double x, double y, double z | Object | Spawn an NPC with a specific variant |
getNPCRole | Object store, Object ref | String | Get the role name of an NPC entity |
getNPCVariant | Object store, Object ref | String | Get the variant identifier of an NPC |
isDespawning | Object store, Object ref | boolean | Check if the NPC is currently despawning |
getRoleRegistry | none | Object | Get the NPC role registry for role lookups |
Assertion Methods
| Method | Parameters | Failure Message |
|---|
assertNPCEntity | Object store, Object ref | ”Expected entity to be an NPC” |
assertRoleName | Object store, Object ref, String expected | ”Expected NPC role [expected] but was [actual]“ |
assertRoleExists | String roleName | ”NPC role [roleName] not found in registry” |
assertNotDespawning | Object store, Object ref | ”Expected NPC to not be despawning” |
NPC Role Names
NPC role names in Hytale use PascalCase with underscores to separate words. Common built-in roles include:
Kweebec_Sapling - Friendly forest creature
Trork_Warrior - Hostile undead melee combatant
Outlander_Hunter - Ranged hostile NPC
Your mod can register custom roles that follow the same naming convention.
Call ctx.waitTicks(1) after spawning before asserting. The NPC needs one tick to initialize all its components (health, AI, model, role data). Asserting immediately after spawnNPC may find the entity in a partially initialized state.
Next Steps