Skip to content

NPC Groups

NPC groups define collections of NPCs that share common behaviors and attitudes. Groups are used for AI targeting, faction relationships, and behavior rules.

Group definitions are stored in Assets/Server/NPC/Groups/:

  • DirectoryAssets/Server/NPC/Groups/
    • Prey.json
    • Predators.json
    • PredatorsBig.json
    • Livestock.json
    • Critters.json
    • Birds.json
    • Aquatic.json
    • Vermin.json
    • Undead.json
    • Void.json
    • Player.json
    • Self.json
    • DirectoryCreature/
      • DirectoryLivestock/
      • DirectoryMammal/
      • DirectoryMythic/
      • DirectoryVermin/
    • DirectoryIntelligent/
      • DirectoryAggressive/
        • DirectoryGoblin/
        • DirectoryOutlander/
        • Scarak.json
        • DirectoryTrork/
      • DirectoryNeutral/
    • DirectoryLivingWorld/
      • Aggressive.json
      • Neutral.json
      • Passive.json
    • DirectoryUndead/

Groups can include or exclude individual roles and other groups. Under the hood, NPCGroup implements a TagSet with four fields:

FieldTypeDescription
IncludeRolesstring[]Individual NPC role IDs to include (supports wildcards)
ExcludeRolesstring[]Individual NPC role IDs to exclude (supports wildcards)
IncludeGroupsstring[]Other NPC groups to include
ExcludeGroupsstring[]Other NPC groups to exclude
Prey.json
{
"IncludeRoles": [
"Chicken",
"Chicken_Chick",
"Chicken_Desert",
"Turkey",
"Rabbit",
"Bunny",
"Mouse",
"Penguin",
"Flamingo"
]
}
Livestock.json
{
"IncludeGroups": [
"Bison",
"Chicken",
"Cow",
"Pig",
"Sheep",
"Mouflon",
"Turkey",
"Chicken_Desert",
"Goat",
"Rabbit",
"Camel",
"Deer"
]
}

Use * to match role name patterns:

Predators.json
{
"IncludeRoles": [
"Fox*",
"Hyena*",
"Fen_Stalker",
"Spark*",
"Toad*"
]
}

This matches Fox, Fox_Arctic, Fox_Desert, etc.

Example combined group
{
"IncludeRoles": [
"SpecificNPC_A",
"SpecificNPC_B"
],
"ExcludeRoles": [
"SpecificNPC_C"
],
"IncludeGroups": [
"ExistingGroup_A",
"ExistingGroup_B"
],
"ExcludeGroups": [
"ExistingGroup_C"
]
}

Animals that flee from predators:

GroupMembers
PreyChickens, Turkey, Rabbits, Mice, Penguins, Flamingos, young livestock
PreyBigLarger prey animals

Hostile hunting NPCs:

GroupMembers
PredatorsFox*, Hyena*, Fen_Stalker, Spark*, Toad*
PredatorsBigBear*, Wolf*, Yeti, Emberwulf, Leopard_Snow, Tiger_Sabertooth, Crocodile, Raptor_Cave, Rex_Cave

Domesticated animals:

Livestock.json
{
"IncludeGroups": [
"Bison", "Chicken", "Cow", "Pig", "Sheep",
"Mouflon", "Turkey", "Chicken_Desert", "Goat",
"Rabbit", "Camel", "Deer"
]
}
GroupDescription
CrittersSmall wildlife (squirrels, birds)
BirdsFlying bird NPCs
AquaticWater-dwelling creatures
VerminPest creatures

Located in Intelligent/Aggressive/:

GroupMembers
GoblinGoblin faction members
TrorkTrork faction members
OutlanderOutlander faction members
ScarakScarak hive creatures
GroupDescription
UndeadAll undead NPCs
SkeletonSkeleton variants
ZombieZombie variants
GroupPurpose
PlayerPlayer entities
SelfSelf-reference for targeting
VoidVoid realm creatures
Capture_CrateNPCs that can be captured

High-level behavioral groupings:

LivingWorld/Aggressive.json
{
"IncludeGroups": [
"Trork",
"Goblin",
"Skeleton",
"Void",
"Zombie",
"Vermin",
"Predators",
"PredatorsBig"
]
}
GroupDescriptionBehavior
LivingWorld/AggressiveHostile to playersAttack on sight
LivingWorld/NeutralDefensive NPCsAttack if provoked
LivingWorld/PassiveNon-hostile NPCsFlee or ignore

Roles don’t directly reference groups for “target” or “flee” lists. Instead, targeting works through two mechanisms: attitude groups and entity filters.

Each role can set an AttitudeGroup, a DefaultPlayerAttitude, and a DefaultNPCAttitude. The attitude system resolves how an NPC feels about a target using a layered priority chain:

  1. Override attitudes (highest priority) — temporary per-entity overrides set by ActionOverrideAttitude, with a duration
  2. AttitudeGroup map — looks up the target’s role in the NPC’s assigned attitude group
  3. Default attitudes (fallback) — DefaultPlayerAttitude for players, DefaultNPCAttitude for other NPCs
Role attitude configuration
{
"DefaultPlayerAttitude": "HOSTILE",
"DefaultNPCAttitude": "NEUTRAL",
"AttitudeGroup": "Trork_Attitudes"
}

The Attitude enum has five values:

AttitudeDescription
IGNOREIgnoring the target
HOSTILEHostile towards the target
NEUTRALNeutral towards the target
FRIENDLYFriendly towards the target
REVEREDReveres the target

Attitude groups are separate assets that map attitudes to NPC groups. They define which groups an NPC considers hostile, friendly, etc.

Trork_Attitudes.json
{
"Groups": {
"HOSTILE": ["Player", "Goblin", "Livestock"],
"FRIENDLY": ["Trork"],
"IGNORE": ["Self"],
"NEUTRAL": ["Undead"]
}
}

When resolving a target’s attitude, the system looks up the target’s role index in the attitude map. If the target’s role belongs to a group listed under HOSTILE, the NPC treats them as hostile.

Behavior instructions can also use entity filters to target by group membership or attitude directly:

Filter by attitude
{
"Type": "Attitude",
"Attitudes": ["HOSTILE"]
}
Filter by NPC group
{
"Type": "NPCGroup",
"IncludeGroups": ["Player", "Livestock"],
"ExcludeGroups": ["Self"]
}

These filters are used inside sensors and instructions to decide which entities an NPC should pay attention to.

Groups can be nested for organization. The IncludeGroups field pulls in all members of referenced groups, creating a hierarchy:

graph TD
    A["LivingWorld/Aggressive"] --> B["Trork"]
    A --> C["Goblin"]
    A --> D["Skeleton"]
    A --> E["Void"]
    A --> F["Zombie"]
    A --> G["Vermin"]
    A --> H["Predators"]
    A --> I["PredatorsBig"]
    H --> J["Fox*"]
    H --> K["Hyena*"]
    H --> L["Toad*"]
    I --> M["Bear*"]
    I --> N["Wolf*"]
    I --> O["Yeti"]
MyPlugin_CustomEnemies.json
{
"IncludeRoles": [
"MyPlugin_Enemy_A",
"MyPlugin_Enemy_B",
"MyPlugin_Boss"
]
}
MyPlugin_AllHostile.json
{
"IncludeRoles": [
"MyPlugin_CustomEnemy"
],
"IncludeGroups": [
"Undead",
"Trork"
]
}
MyPlugin_AllVariants.json
{
"IncludeRoles": [
"MyPlugin_Creature*"
]
}

This matches MyPlugin_Creature, MyPlugin_Creature_Rare, MyPlugin_Creature_Boss, etc.

  1. Use wildcards sparingly - Explicit lists are more maintainable
  2. Nest groups logically - Create hierarchies for complex factions
  3. Consider symmetry - If A is hostile to B, B should be hostile to A
  4. Use standard groups - Reference existing groups like Player rather than duplicating
  5. Prefix custom groups - Use plugin prefix to avoid conflicts