Hytale Asset ReferenceUnofficial
Versions / 0.5.3 / NPC / Roles / _Core / Templates / Template_Livestock.json

Template_Livestock

Server/NPC/Roles/_Core/Templates/Template_Livestock.json, 79.9 KB

Fields

FieldType
Typestring
StartStatestring
Parametersobject
IsMemoryobject
MemoriesCategoryobject
MemoriesNameOverrideobject
DropListobject
FlockSpawnTypesobject
FlockSpawnTypesRandomboolean
DisableDamageGroupsarray[1]
Appearanceobject
DefaultPlayerAttitudeobject
DefaultNPCAttitudestring
AttitudeGroupobject
ApplySeparationboolean
SeparationDistanceobject
SeparationWeightnumber
SeparationDistanceTargetobject
SeparationNearRadiusTargetnumber
SeparationFarRadiusTargetnumber
BreathesInWaterobject
KnockbackScalenumber
DeathParticlesobject
DropDeathItemsInstantlyobject
DeathAnimationTimeobject
MotionControllerListarray[1]
StateTransitionsarray[5]
MaxHealthobject
InteractionVarsobject
Instructionsarray[6]
InteractionInstructionobject
NameTranslationKeyobject

Source

{
  "Type": "Abstract",
  "StartState": "Idle",
  "Parameters": {
    "Appearance": {
      "Value": "Deer_Stag",
      "Description": "The NPC's model."
    },
    "ParticleOffset": {
      "Value": [ 0, 1, 0 ],
      "Description": "The offset of any spawned particle systems."
    },
    "SeparationDistance": {
      "Value": 1,
      "Description": "The separation distance between this and other NPCs."
    },
    "WanderRadius": {
      "Value": 7,
      "Description": "The wander radius of the NPC."
    },
    "ViewRange": {
      "Value": 16,
      "Description": "The view distance of the NPC, in blocks."
    },
    "ViewSector": {
      "Value": 180,
      "Description": "The view sector of the NPC, in degrees."
    },
    "HearingRange": {
      "Value": 8,
      "Description": "The hearing distance of the NPC, in blocks."
    },
    "SmellingRange": {
      "Value": 4,
      "Description": "The smelling distance of the NPC, in blocks. Used to detect when an attractive item is being held nearby."
    },
    "AbsoluteDetectionRange": {
      "Value": 4,
      "Description": "The range at which a target is guaranteed to be detected, in blocks. If set to zero, absolute detection will be disabled. The interval [ AbsoluteDetectionRange, AlertedActionRange ] defines the distance range within which an NPC can be befriended."
    },
    "AlertedRange": {
      "Value": 18,
      "Description": "The range within which the target can be seen/sensed when the NPC is alerted to their presence, in blocks. Should be higher than sense ranges."
    },
    "AlertedActionRange": {
      "Value": 6,
      "Description": "The range at which an NPC will react to other NPCs and players, depending on the attitude towards them, in blocks. Should be higher than AbsoluteDetectionRange to make the NPC befriendable."
    },
    "DropList": {
      "Value": "Empty",
      "Description": "The NPC's drop list."
    },
    "FlockArray": {
      "Value": [ ],
      "TypeHint": "String",
      "Description": "The set of NPCs belonging to this flock type"
    },
    "ClimbHeight": {
      "Value": 1,
      "Description": "The maximum climb height, in blocks."
    },
    "AttitudeGroup": {
      "Value": "Prey",
      "Description": "The attitude group this NPC belongs to."
    },
    "PlayerDefaultAttitude": {
      "Value": "Revered",
      "Description": "The default attitude towards the player."
    },
    "AlertedTimeoutGiveUp": {
      "Value": [ 5, 12 ],
      "Description": "The timeout after which an alerted NPC will give up on the target, in seconds."
    },
    "GrazingBlockSet": {
      "Value": "Grass",
      "Description": "The type of block that this NPC will graze on top of."
    },
    "DayTimePeriod": {
      "Value": [ 6.01, 17.99 ],
      "Description": "The hour range considered to be daytime for this NPC (inclusive). Hours should be written with decimal fractions."
    },
    "DayTimeNapWeight": {
      "Value": 2,
      "Description": "The weight used to determine if the NPC should have a short nap during the day. Set to 0 to disable."
    },
    "DayTimeNapTimeRange": {
      "Value": [ 10, 12 ],
      "Description": "The duration range of daytime naps, in seconds."
    },
    "DayFlavorAnimation": {
      "Value": "",
      "Description": "The flavor animation to play during the day. Ignored if null or empty."
    },
    "AttractiveItemSet": {
      "Value": [ "Tool_Feedbag" ],
      "Description": "The list of items that are deemed attractive (there's a chance targets holding them will be followed)."
    },
    "FoodBlockSet": {
      "Value": "Livestock_Feeding",
      "Description": "The type of block that this NPC will occasionally seek out to munch on."
    },
    "WeightFollowItem": {
      "Value": 100,
      "Description": "The probability the NPC will follow an attractive item when held by a non-hostile target, in percent."
    },
    "FollowItemPreDelay": {
      "Value": [ 1, 2 ],
      "Description": "The time delay before an NPC starts following an item."
    },
    "FollowItemTimeoutEnabled": {
      "Value": false,
      "Description": "Whether the NPC will follow an attractive item with a timeout. If set to false, make sure FollowItemTimeout is properly configured."
    },
    "FollowItemTimeout": {
      "Value": [ 20, 40 ],
      "Description": "The duration of the follow item behaviour, after which the NPC will give up on the target. Requires FollowItemTimeoutEnabled to be set to true."
    },
    "FollowItemDistance": {
      "Value": [ 2, 2.5 ],
      "Description": "The minimum distance which the NPC will retain from a target holding an attractive item."
    },
    "GreetAnimation": {
      "Value": "Alerted",
      "Description": "The flavor animation to play when greeting another NPC or player. Ignored if null or empty."
    },
    "GreetStateTimeout": {
      "Value": [ 4, 10 ],
      "Description": "The timeout after which an alerted NPC will give up on the target, in seconds."
    },
    "GreetTimeout": {
      "Value": [ "PT2H", "PT12H" ],
      "Description": "The timeout between consecutive greetings."
    },
    "IgnoreAttitudeOverride": {
      "Value": 30,
      "Description": "The attitude override after an NPC gets angry at a player."
    },
    "EatTimeout": {
      "Value": [ "PT8H", "PT12H" ],
      "Description": "The timeout between consecutive meals."
    },
    "IsPettable": {
      "Value": true,
      "Description": "Whether players can pet the NPC."
    },
    "PetAnimation": {
      "Value": "Alerted",
      "Description": "The animation the NPC will play when petted."
    },
    "PetRequiredAttitudes": {
      "Value": [ "Friendly", "Revered" ],
      "Description": "The attitude groups of players that can pet the NPC."
    },
    "FeedRequiredAttitudes": {
      "Value": [ "Friendly", "Revered" ],
      "Description": "The attitude groups of players that can feed the NPC by hand."
    },
    "PetTimeout": {
      "Value": [ "PT15M", "PT15M" ],
      "Description": "The timeout between consecutive pets."
    },
    "IsHarvestable": {
      "Value": false,
      "Description": "Whether this NPC can be 'harvested'. This includes shearing, milking, etc."
    },
    "HarvestInteractionContext": {
      "Value": "",
      "Description": "The interaction context of the harvest tool. If empty, no tool is needed to harvest the NPC."
    },
    "HarvestInteractionRequiredItems": {
      "Value": [ ],
      "TypeHint": "String",
      "Description": "The collection of items that enable the harvest interaction."
    },
    "HarvestRequiredAttitudes": {
      "Value": [ "Friendly", "Revered", "Ignore" ],
      "Description": "The attitude groups of players that can harvest the NPC."
    },
    "HarvestDropList": {
      "Value": "",
      "Description": "The drop list that's executed when the NPC is harvested."
    },
    "HarvestParticles": {
      "Value": "Alerted",
      "Description": "The particle system that is spawned when the NPC is harvested."
    },
    "HarvestSound": {
      "Value": "SFX_Sheep_Sheared",
      "Description": "The sound that plays when NPC is harvested."
    },
    "HarvestTimeout": {
      "Value": [ "P1D", "P1D" ],
      "Description": "The minimum time between consecutive harvests. Expressed in the ISO-8601 time period notation, where both values of the array must have the same prefix (either 'PT' or 'P')."
    },
    "HarvestModelSlot": {
      "Value": "",
      "Description": "The model attachment slot where the 'harvested' state is displayed."
    },
    "HarvestModelAttachmentHarvestable": {
      "Value": "",
      "Description": "The attachment that should be rendered when the NPC can be harvested."
    },
    "HarvestModelAttachmentHarvested": {
      "Value": "",
      "Description": "The attachment that should be rendered when the NPC was harvested and is in timeout."
    },
    "HarvestAddItemBucket": {
      "Value": "",
      "Description": "Item to add when player holds Container_Bucket (e.g., milk bucket for milking)."
    },
    "HarvestAddItemDecoBucket": {
      "Value": "",
      "Description": "Item to add when player holds Deco_Bucket (e.g., milk bucket for milking)."
    },
    "ProduceItem": {
      "Value": "",
      "Description": "The item this NPC produces (poop, eggs, etc)."
    },
    "ProduceTimeout": {
      "Value": [ "PT6H", "PT36H" ],
      "Description": "The timeout between consecutive produces."
    },
    "DayFlavorAnimationLength": {
      "Value": [ 3, 5 ],
      "Description": "How long the daytime flavor animation will be played for, in seconds."
    },
    "AttackWhenStartled": {
      "Value": false,
      "Description": "Whether this NPC attacks when startled."
    },
    "Attack": {
      "Value": "",
      "Description": "The attack interaction this NPC will use."
    },
    "AttackRange": {
      "Value": 5,
      "Description": "The range at which the NPC can identify an attacker."
    },
    "MaxSpeed": {
      "Value": 4,
      "Description": "The maximum walking speed of the NPC."
    },
    "MaxHealth": {
      "Value": 100,
      "Description": "The maximum health of the NPC."
    },
    "MaxRotationSpeed": {
      "Value": 360,
      "Description": "The maximum rotation speed, in degrees per second."
    },
    "RunThreshold": {
      "Value": 0.5,
      "Description": "The speed ratio at which the NPC switches to run animation (e.g if MaxSpeed is 10, and RunThreshold is set to 0.55, the NPC will start running at speed 5.5)."
    },
    "DeathParticles": {
      "Value": "Effect_Death",
      "Description": "The particle system that spawns when the NPC's corpse disappears."
    },
    "DropDeathItemsInstantly": {
      "Value": false,
      "Description": "Whether the NPC's drop list should be executed when the NPC dies. If set to false, items drop when the corpse disappears."
    },
    "DeathAnimationTime": {
      "Value": 2,
      "Description": "The time it takes for this NPC's corpse to disappear."
    },
    "IsMemory": {
      "Value": false,
      "Description": "Whether the NPC is a memory."
    },
    "MemoriesCategory": {
      "Value": "Livestock",
      "Description": "The category of the memory."
    },
    "MemoriesNameOverride": {
      "Value": "",
      "Description": "If set, overrides the memory name."
    },
    "IsMountable": {
      "Value": false,
      "Description": "Whether this NPC can be mounted."
    },
    "MountAnchorX": {
      "Value": 0
    },
    "MountAnchorY": {
      "Value": 0
    },
    "MountAnchorZ": {
      "Value": 0
    },
    "MountMovementConfig": {
      "Value": "Mount"
    },
    "BreathesInWater": {
      "Value": false,
      "Description": "Whether this NPC can breathe underwater."
    },
    "NameTranslationKey": {
      "Value": "server.npcRoles.Template.name",
      "Description": "The translation key for the NPC name display"
    }
  },
  "IsMemory": { "Compute": "IsMemory" },
  "MemoriesCategory": { "Compute": "MemoriesCategory" },
  "MemoriesNameOverride": { "Compute": "MemoriesNameOverride" },
  "DropList": { "Compute": "DropList" },
  "FlockSpawnTypes": { "Compute": "FlockArray" },
  "FlockSpawnTypesRandom": true,
  "DisableDamageGroups": [ "Self" ],
  "Appearance": { "Compute": "Appearance" },
  "DefaultPlayerAttitude": { "Compute": "PlayerDefaultAttitude" },
  "DefaultNPCAttitude": "Ignore",
  "AttitudeGroup": { "Compute": "AttitudeGroup" },
  "ApplySeparation": true,
  "SeparationDistance": { "Compute": "SeparationDistance" },
  "SeparationWeight": 1,
  "SeparationDistanceTarget": { "Compute": "SeparationDistance" },
  "SeparationNearRadiusTarget": 2,
  "SeparationFarRadiusTarget": 7,
  "BreathesInWater": { "Compute": "BreathesInWater" },
  "KnockbackScale": 0.5,
  "DeathParticles": { "Compute": "DeathParticles" },
  "DropDeathItemsInstantly": { "Compute": "DropDeathItemsInstantly" },
  "DeathAnimationTime": { "Compute": "DeathAnimationTime" },
  "MotionControllerList": [
    {
      "Type": "Walk",
      "MaxWalkSpeed": { "Compute": "MaxSpeed" },
      "Gravity": 15,
      "MaxFallSpeed": 15,
      "JumpHeight": 0.1,
      "MaxRotationSpeed": { "Compute": "MaxRotationSpeed" },
      "Acceleration": 100,
      "RunThreshold": { "Compute": "RunThreshold" },
      "DescentAnimationType": "Fall",
      "DescentSteepness": 2.5,
      "DescentBlending": 1,
      "JumpDescentSteepness": 8,
      "MaxClimbHeight": { "Compute": "ClimbHeight" },
      "FenceBlockSet": "Fence"
    }
  ],
  "StateTransitions": [
    {
      "States": [
        {
          "From": [ "Idle" ],
          "To": [ "Sleep" ]
        }
      ],
      "Actions": {
        "Reference": "Component_ActionList_Sleep"
      }
    },
    {
      "States": [
        {
          "From": [ "Sleep" ],
          "To": [ "Alerted", "Flee", "Idle" ]
        }
      ],
      "Actions": {
        "Reference": "Component_ActionList_Wake"
      }
    },
    {
      "$Comment": "Always clear animation when moving from Alerted or Flee state.",
      "States": [
        {
          "To": [ ],
          "From": [ "Alerted", "Flee" ]
        }
      ],
      "Actions": [
        {
          "Type": "PlayAnimation",
          "Slot": "Status"
        },
        {
          "Type": "SetFlag",
          "Name": "AnimationBlock",
          "SetTo": false
        }
      ]
    },
    {
      "$Comment": "Always clear target and reset instructions when going back to idle.",
      "States": [
        {
          "To": [ "Idle" ],
          "From": [ ]
        }
      ],
      "Actions": [
        {
          "Type": "ReleaseTarget"
        },
        {
          "Type": "ResetInstructions"
        },
        {
          "Type": "PlayAnimation",
          "Slot": "Status"
        }
      ]
    },
    {
      "$Comment": "Clear idle anims",
      "States": [
        {
          "To": [ ],
          "From": [ "Idle" ]
        }
      ],
      "Actions": [
        {
          "Type": "PlayAnimation",
          "Slot": "Status"
        }
      ]
    }
  ],
  "MaxHealth": { "Compute": "MaxHealth" },
  "InteractionVars": {
    "Melee_Damage": {
      "Interactions": [
        {
          "$Comment": "Config for a successful melee hit, default values for Effects and HitShape are not overwritten here, see each NPC_ file",
          "Parent": "NPC_Attack_Melee_Damage",
          "DamageCalculator": {
            "Type": "Absolute",
            "BaseDamage": {
              "Physical": 5
            },
            "RandomPercentageModifier": 0.1
          }
        }
      ]
    }
  },
  "Instructions": [
    {
      "$Comment": "This is separate so it can run all the time regardless of the rest of the script",
      "Continue": true,
      "Instructions": [
        {
          "$Comment": "Update flock member leash positions to match the leader.",
          "Enabled": { "Compute": "!isEmptyStringArray(FlockArray)" },
          "Continue": true,
          "Sensor": {
            "Type": "And",
            "Sensors": [
              {
                "Type": "FlockLeader"
              },
              {
                "Type": "Self",
                "Filters": [
                  {
                    "Type": "Flock",
                    "FlockStatus": "Follower"
                  }
                ]
              }
            ]
          },
          "Actions": [
            {
              "Type": "Timeout",
              "Delay": [ 0.5, 2 ],
              "Action": {
                "Type": "SetLeashPosition",
                "ToTarget": true
              }
            }
          ]
        },
        {
          "$Comment": "Join eligible flocks if not a member of a flock.",
          "Enabled": { "Compute": "!isEmptyStringArray(FlockArray)" },
          "Sensor": {
            "Type": "Mob",
            "Range": 20,
            "ExcludeOwnType": false,
            "LockOnTarget": true,
            "Filters": [
              {
                "Type": "NPCGroup",
                "IncludeGroups": [ "Self" ]
              },
              {
                "Type": "Flock",
                "FlockStatus": "NotMember"
              }
            ]
          },
          "Actions": [
            {
              "Type": "JoinFlock"
            }
          ]
        }
      ]
    },
    {
      "Continue": true,
      "$Comment": "This is separate so it can run all the time regardless of the rest of the script, when in water go straight to panic to get out",
      "Instructions": [
        {
          "Sensor": {
            "Type": "And",
            "Sensors": [
              {
                "Type": "InWater"
              },
              {
                "Type": "Not",
                "Sensor": {
                  "Type": "State",
                  "State": "Panic"
                }
              }
            ]
          },
          "Actions": [
            {
              "Type": "State",
              "State": "Panic"
            }
          ]
        }
      ]
    },
    {
      "$Comment": "If there are configured attachments for the 'harvestable' state, apply them",
      "Enabled": { "Compute": "IsHarvestable" },
      "Continue": true,
      "Sensor": {
        "Type": "Alarm",
        "Name": "Harvest_Ready",
        "State": "Passed",
        "Clear": true
      },
      "Instructions": [
        {
          "Enabled": { "Compute": "!isEmpty(HarvestModelSlot)" },
          "Actions": [
            {
              "Type": "ModelAttachment",
              "Slot": { "Compute": "HarvestModelSlot" },
              "Attachment": { "Compute": "HarvestModelAttachmentHarvestable" }
            }
          ]
        }
      ]
    },
    {
      "Continue": true,
      "Instructions": [
        {
          "$Comment": "Clear the pet alarm when it finishes",
          "Enabled": { "Compute": "IsPettable" },
          "Continue": true,
          "Sensor": {
            "Type": "Alarm",
            "Name": "Pet_Ready",
            "State": "Passed",
            "Clear": true
          },
          "Actions": [
            {
              "Type": "Nothing"
            }
          ]
        },
        {
          "$Comment": "Clear the greet alarm when it finishes",
          "Continue": true,
          "Sensor": {
            "Type": "Alarm",
            "Name": "Greet_Ready",
            "State": "Passed",
            "Clear": true
          },
          "Actions": [
            {
              "Type": "Nothing"
            }
          ]
        },
        {
          "$Comment": "Clear the eat alarm when it finishes",
          "Continue": true,
          "Sensor": {
            "Type": "Alarm",
            "Name": "Eat_Ready",
            "State": "Passed",
            "Clear": true
          },
          "Actions": [
            {
              "Type": "Nothing"
            }
          ]
        },
        {
          "$Comment": "Clear the produce alarm when it finishes",
          "Continue": true,
          "Enabled": { "Compute": "!isEmpty(ProduceItem)" },
          "Sensor": {
            "Type": "Alarm",
            "Name": "Produce_Ready",
            "State": "Passed",
            "Clear": true
          },
          "Actions": [
            {
              "Type": "Nothing"
            }
          ]
        }
      ]
    },
    {
      "$Comment": "Initialize the produce alarm. This prevents NPCs from producing as soon as they spawn in",
      "Enabled": { "Compute": "!isEmpty(ProduceItem)" },
      "Sensor": {
        "Type": "Alarm",
        "Name": "Produce_Ready",
        "State": "Unset"
      },
      "Actions": [
        {
          "Type": "SetAlarm",
          "Name": "Produce_Ready",
          "DurationRange": { "Compute": "ProduceTimeout" }
        }
      ]
    },
    {
      "Instructions": [
        {
          "Sensor": {
            "Type": "State",
            "State": "Idle"
          },
          "Instructions": [
            {
              "$Comment": "Switch to flee state if any flock member engages a target TODO switch to attack if you are very close and can attack? otherwise flee.",
              "Enabled": { "Compute": "!isEmptyStringArray(FlockArray)" },
              "Sensor": {
                "Type": "Beacon",
                "Message": "Flock_Attack",
                "TargetSlot": "LockedTarget",
                "Range": { "Compute": "HearingRange" }
              },
              "Actions": [
                {
                  "Type": "State",
                  "State": "Alerted"
                }
              ]
            },
            {
              "Reference": "Component_Instruction_Damage_Check",
              "Modify": {
                "_ExportStates": [ "Flee.Switch", "Panic" ],
                "AlertedRange": { "Compute": "AlertedRange" }
              }
            },
            {
              "$Comment": "Check if there are any potential things that can alert the NPC",
              "Sensor": {
                "Reference": "Component_Sensor_Standard_Detection",
                "Modify": {
                  "ViewRange": { "Compute": "ViewRange" },
                  "ViewSector": { "Compute": "ViewSector" },
                  "HearingRange": { "Compute": "HearingRange" },
                  "AbsoluteDetectionRange": { "Compute": "AbsoluteDetectionRange" },
                  "Attitudes": [ "Hostile" ]
                }
              },
              "Actions": [
                {
                  "Type": "State",
                  "State": "Alerted"
                }
              ]
            },
            {
              "$Comment": "Produce an item",
              "Enabled": { "Compute": "!isEmpty(ProduceItem)" },
              "Sensor": {
                "Type": "Alarm",
                "Name": "Produce_Ready",
                "State": "Passed"
              },
              "Actions": [
                {
                  "Type": "DropItem",
                  "Item": { "Compute": "ProduceItem" },
                  "Distance": [ 0.8, 0.8 ],
                  "DropSector": [ 170, 190 ],
                  "Delay": [ 0, 0 ],
                  "ThrowSpeed": 14
                },
                {
                  "Type": "SetAlarm",
                  "Name": "Produce_Ready",
                  "DurationRange": { "Compute": "ProduceTimeout" }
                }
              ]
            },
            {
              "$Comment": "If the target is holding a liked item, follow it",
              "Enabled": { "Compute": "!isEmptyStringArray(AttractiveItemSet)" },
              "Continue": true,
              "Sensor": {
                "Type": "And",
                "Sensors": [
                  {
                    "Reference": "Component_Sensor_Standard_Detection",
                    "Modify": {
                      "ViewRange": { "Compute": "ViewRange" },
                      "ViewSector": { "Compute": "ViewSector" },
                      "HearingRange": { "Compute": "SmellingRange" },
                      "AbsoluteDetectionRange": { "Compute": "AbsoluteDetectionRange" },
                      "Attitudes": [ "Revered", "Friendly" ]
                    }
                  }
                ]
              },
              "Instructions": [
                {
                  "Sensor": {
                    "Type": "Target",
                    "Filters": [
                      {
                        "Type": "ItemInHand",
                        "Items": { "Compute": "AttractiveItemSet" }
                      },
                      {
                        "Type": "Attitude",
                        "Attitudes": [ "Revered", "Friendly" ]
                      }
                    ]
                  },
                  "Type": "Random",
                  "ExecuteFor": [ 15, 20 ],
                  "Instructions": [
                    {
                      "Weight": { "Compute": "WeightFollowItem" },
                      "Sensor": {
                        "Type": "Target"
                      },
                      "HeadMotion": {
                        "Type": "Watch"
                      },
                      "BodyMotion": {
                        "Type": "MatchLook"
                      },
                      "ActionsBlocking": true,
                      "Actions": [
                        {
                          "Type": "PlayAnimation",
                          "Slot": "Status",
                          "Animation": "Alerted"
                        },
                        {
                          "Type": "SpawnParticles",
                          "ParticleSystem": "Hearts_Subtle",
                          "Offset": { "Compute": "ParticleOffset" },
                          "TargetNodeName": "Head"
                        },
                        {
                          "Type": "Timeout",
                          "Delay": { "Compute": "FollowItemPreDelay" }
                        },
                        {
                          "Type": "State",
                          "State": "SeekFood"
                        }
                      ]
                    },
                    {
                      "Enabled": { "Compute": "WeightFollowItem < 100" },
                      "Weight": { "Compute": "100 - WeightFollowItem" },
                      "Sensor": {
                        "Type": "Target"
                      },
                      "ActionsBlocking": true,
                      "Actions": [
                        {
                          "Type": "Nothing"
                        }
                      ]
                    }
                  ]
                }
              ]
            },
            {
              "Sensor": {
                "Type": "State",
                "State": ".EatFromBlock"
              },
              "Instructions": [
                {
                  "Sensor": {
                    "Type": "Block",
                    "Range": 2,
                    "MaxHeight": 4,
                    "Blocks": { "Compute": "FoodBlockSet" },
                    "Random": true
                  },
                  "HeadMotion": {
                    "Type": "Aim"
                  },
                  "BodyMotion": {
                    "Type": "MatchLook"
                  },
                  "ActionsBlocking": true,
                  "Actions": [
                    {
                      "Type": "PlayAnimation",
                      "Slot": "Status",
                      "Animation": "Eat"
                    },
                    {
                      "Type": "Timeout",
                      "Delay": [ 4, 6 ]
                    },
                    {
                      "Type": "ResetBlockSensors"
                    },
                    {
                      "Type": "State",
                      "State": "SeekFood.Ate"
                    }
                  ]
                },
                {
                  "Sensor": {
                    "Type": "Block",
                    "Range": { "Compute": "ViewRange" },
                    "MaxHeight": 4,
                    "Blocks": { "Compute": "FoodBlockSet" },
                    "Random": true
                  },
                  "BodyMotion": {
                    "Type": "Seek",
                    "RelativeSpeed": 0.6,
                    "StopDistance": 0.5,
                    "RelaxedMoveConstraints": false
                  },
                  "HeadMotion": {
                    "Type": "Watch"
                  }
                },
                {
                  "Sensor": {
                    "Type": "Any"
                  },
                  "ActionsBlocking": true,
                  "Actions": [
                    {
                      "Type": "PlayAnimation",
                      "Slot": "Status"
                    },
                    {
                      "Type": "Timeout",
                      "Delay": [ 2, 4 ]
                    },
                    {
                      "Type": "ResetBlockSensors"
                    },
                    {
                      "Type": "State",
                      "State": ".Default"
                    }
                  ]
                }
              ]
            },
            {
              "$Comment": "Execute daytime idle behaviors.",
              "Type": "Random",
              "ExecuteFor": [ 20, 30 ],
              "Sensor": {
                "Type": "Time",
                "Period": { "Compute": "DayTimePeriod" },
                "CheckDay": true
              },
              "Instructions": [
                {
                  "Weight": 20,
                  "Instructions": [
                    {
                      "$Comment": "Check if there are any surrounding players to greet",
                      "Sensor": {
                        "Type": "And",
                        "Sensors": [
                          {
                            "Reference": "Component_Sensor_Standard_Detection",
                            "Modify": {
                              "ViewRange": { "Compute": "ViewRange" },
                              "ViewSector": { "Compute": "ViewSector" },
                              "HearingRange": { "Compute": "HearingRange" },
                              "AbsoluteDetectionRange": { "Compute": "AbsoluteDetectionRange" },
                              "Attitudes": [ "Revered", "Friendly" ]
                            }
                          },
                          {
                            "Type": "Alarm",
                            "Name": "Greet_Ready",
                            "State": "Unset"
                          }
                        ]
                      },
                      "Actions": [
                        {
                          "Type": "State",
                          "State": "Greet"
                        }
                      ]
                    },
                    {
                      "$Comment": "No nearby players to greet or greet alarm hasn't finished",
                      "Actions": [
                        {
                          "Type": "ResetInstructions"
                        },
                        {
                          "Type": "State",
                          "State": ".Default"
                        }
                      ]
                    }
                  ]
                },
                {
                  "$Comment": "Regular wander.",
                  "Weight": 20,
                  "Instructions": [
                    {
                      "Continue": true,
                      "Actions": [
                        {
                          "Type": "Crouch",
                          "Crouch": false
                        }
                      ]
                    },
                    {
                      "Reference": "Component_Instruction_Leash_To_Flock_Leader",
                      "Modify": {
                        "Enabled": { "Compute": "!isEmptyStringArray(FlockArray)" },
                        "WanderRadius": { "Compute": "WanderRadius" },
                        "RelativeSpeed": 0.3,
                        "StopDistance": 3
                      }
                    },
                    {
                      "BodyMotion": {
                        "Type": "Sequence",
                        "Looped": true,
                        "Motions": [
                          {
                            "Type": "Timer",
                            "Time": [ 1, 5 ],
                            "Motion": {
                              "Type": "WanderInCircle",
                              "Radius": { "Compute": "WanderRadius" },
                              "MaxHeadingChange": 60,
                              "RelativeSpeed": 0.18
                            }
                          },
                          {
                            "Type": "Timer",
                            "Time": [ 3, 8 ],
                            "Motion": {
                              "Type": "Nothing"
                            }
                          }
                        ]
                      }
                    }
                  ]
                },
                {
                  "$Comment": "TODO: grazing component seems to be borked",
                  "Weight": 10,
                  "Instructions": [
                    {
                      "Sensor": {
                        "Type": "Self",
                        "Filters": [
                          {
                            "Type": "StandingOnBlock",
                            "BlockSet": { "Compute": "GrazingBlockSet" }
                          }
                        ]
                      },
                      "ActionsBlocking": true,
                      "Actions": [
                        {
                          "Type": "PlayAnimation",
                          "Slot": "Status",
                          "Animation": "Eat"
                        },
                        {
                          "Type": "Timeout",
                          "Delay": [ 5, 6 ]
                        },
                        {
                          "Type": "PlayAnimation",
                          "Slot": "Status"
                        },
                        {
                          "Type": "ResetInstructions"
                        }
                      ]
                    },
                    {
                      "$Comment": "They are not standing on grazing block",
                      "Actions": [
                        {
                          "Type": "ResetInstructions"
                        },
                        {
                          "Type": "State",
                          "State": ".Default"
                        }
                      ]
                    }
                  ]
                },
                {
                  "Enabled": { "Compute": "!isEmpty(FoodBlockSet)" },
                  "Weight": 10,
                  "Instructions": [
                    {
                      "Sensor": {
                        "Type": "And",
                        "Sensors": [
                          {
                            "Type": "Alarm",
                            "Name": "Eat_Ready",
                            "State": "Unset"
                          },
                          {
                            "Type": "Block",
                            "Range": { "Compute": "ViewRange" },
                            "MaxHeight": 4,
                            "Blocks": { "Compute": "FoodBlockSet" },
                            "Random": true
                          }
                        ]
                      },
                      "Actions": [
                        {
                          "Type": "State",
                          "State": ".EatFromBlock"
                        }
                      ]
                    },
                    {
                      "$Comment": "No nearby blocks to eat from",
                      "Actions": [
                        {
                          "Type": "ResetInstructions"
                        },
                        {
                          "Type": "State",
                          "State": ".Default"
                        }
                      ]
                    }
                  ]
                },
                {
                  "$Comment": "Play a daytime flavor animation.",
                  "Enabled": { "Compute": "!isEmpty(DayFlavorAnimation)" },
                  "Weight": 3,
                  "Instructions": [
                    {
                      "ActionsBlocking": true,
                      "Actions": [
                        {
                          "Type": "PlayAnimation",
                          "Slot": "Status",
                          "Animation": { "Compute": "DayFlavorAnimation" }
                        },
                        {
                          "Type": "Timeout",
                          "Delay": { "Compute": "DayFlavorAnimationLength" }
                        },
                        {
                          "Type": "PlayAnimation",
                          "Slot": "Status"
                        },
                        {
                          "Type": "ResetInstructions"
                        }
                      ]
                    }
                  ]
                },
                {
                  "$Comment": "Nap.",
                  "Enabled": { "Compute": "DayTimeNapWeight > 0" },
                  "Weight": { "Compute": "DayTimeNapWeight" },
                  "Instructions": [
                    {
                      "Actions": [
                        {
                          "Type": "State",
                          "State": "Sleep.Nap"
                        }
                      ]
                    }
                  ]
                }
              ]
            },
            {
              "$Comment": "Sleep time.",
              "Actions": [
                {
                  "Type": "Timeout",
                  "Delay": [ 2, 4 ],
                  "Action": {
                    "Type": "Sequence",
                    "Actions": [
                      {
                        "Type": "State",
                        "State": "Sleep"
                      }
                    ]
                  }
                }
              ]
            }
          ]
        },
        {
          "Sensor": {
            "Type": "State",
            "State": "Sleep"
          },
          "Instructions": [
            {
              "$Comment": "Wake up if an enemy attacks a flock member.",
              "Enabled": { "Compute": "!isEmptyStringArray(FlockArray)" },
              "Sensor": {
                "Type": "Beacon",
                "Message": "Flock_Attack",
                "TargetSlot": "LockedTarget"
              },
              "Actions": [
                {
                  "Type": "State",
                  "State": "Alerted"
                }
              ]
            },
            {
              "$Comment": "Just a little nap.",
              "Enabled": { "Compute": "DayTimeNapWeight > 0" },
              "Sensor": {
                "Type": "State",
                "State": ".Nap"
              },
              "Instructions": [
                {
                  "$Comment": "Start the nap timer",
                  "Continue": true,
                  "Sensor": {
                    "Type": "Any",
                    "Once": true
                  },
                  "Actions": [
                    {
                      "Type": "TimerStart",
                      "Name": "NapTimer",
                      "StartValueRange": { "Compute": "DayTimeNapTimeRange" },
                      "RestartValueRange": { "Compute": "DayTimeNapTimeRange" }
                    },
                    {
                      "Type": "TimerRestart",
                      "Name": "NapTimer"
                    }
                  ]
                },
                {
                  "Reference": "Component_Instruction_Wild_Sleep_State",
                  "Modify": {
                    "_ExportStates": [ "Panic", "Panic", "Flee.Switch", "Idle" ],
                    "HearingRange": { "Compute": "HearingRange" },
                    "Attitudes": [ "Hostile", "Neutral" ],
                    "WakeupSensor": "Component_Sensor_Timed_Nap"
                  }
                }
              ]
            },
            {
              "$Comment": "Night-time sleep.",
              "Instructions": [
                {
                  "Reference": "Component_Instruction_Wild_Sleep_State",
                  "Modify": {
                    "_ExportStates": [ "Panic", "Panic", "Flee.Switch", "Idle" ],
                    "HearingRange": { "Compute": "HearingRange" },
                    "Attitudes": [ "Hostile", "Neutral" ],
                    "DayTimePeriod": { "Compute": "DayTimePeriod" }
                  }
                }
              ]
            }
          ]
        },
        {
          "$Comment": "Used when receiving something like a flock beacon that may potentially result in the NPC becoming alerted but could also be discarded with a random chance.",
          "Sensor": {
            "Type": "State",
            "State": "Alerted"
          },
          "Instructions": [
            {
              "$Comment": "Play the alerted animation when entering the state",
              "Continue": true,
              "Sensor": {
                "Type": "Any",
                "Once": true
              },
              "Actions": [
                {
                  "Type": "PlayAnimation",
                  "Slot": "Status",
                  "Animation": "Alerted"
                }
              ]
            },
            {
              "$Comment": "Starting a timer to get out of alerted state if nothing else got us out of there",
              "Sensor": {
                "Type": "Target"
              },
              "Continue": true,
              "ActionsBlocking": true,
              "Actions": [
                {
                  "Type": "Timeout",
                  "Delay": { "Compute": "AlertedTimeoutGiveUp" }
                },
                {
                  "Type": "State",
                  "State": "Idle"
                }
              ]
            },
            {
              "$Comment": "Check for damage",
              "Reference": "Component_Instruction_Damage_Check",
              "Modify": {
                "_ExportStates": [ "Flee.Switch", "Panic" ],
                "AlertedRange": { "Compute": "AlertedRange" }
              }
            },
            {
              "$Comment": "Watching a target always, if we have any",
              "Continue": true,
              "Sensor": {
                "Type": "Target",
                "Range": { "Compute": "AlertedRange" }
              },
              "HeadMotion": {
                "Type": "Watch"
              }
            },
            {
              "Sensor": {
                "$Comment": "If target is reasonably close, the NPC will flee",
                "Type": "Target",
                "Range": { "Compute": "AlertedActionRange" },
                "Filters": [
                  {
                    "Type": "LineOfSight"
                  }
                ]
              },
              "Actions": [
                {
                  "Type": "State",
                  "State": "Flee.Switch"
                }
              ]
            },
            {
              "$Comment": "No target, back to idle",
              "Sensor": {
                "Type": "Not",
                "Sensor": {
                  "Type": "Target"
                }
              },
              "Actions": [
                {
                  "Type": "Timeout",
                  "Delay": [ 2, 2 ],
                  "Action": {
                    "Type": "State",
                    "State": "Idle"
                  }
                }
              ]
            }
          ]
        },
        {
          "Sensor": {
            "Type": "State",
            "State": "Greet"
          },
          "Instructions": [
            {
              "$Comment": "Play the greet animation when entering the state",
              "Continue": true,
              "Sensor": {
                "Type": "Any",
                "Once": true
              },
              "Actions": [
                {
                  "Type": "PlayAnimation",
                  "Slot": "Status",
                  "Animation": { "Compute": "GreetAnimation" }
                }
              ]
            },
            {
              "$Comment": "Check for damage",
              "Reference": "Component_Instruction_Damage_Check",
              "Modify": {
                "_ExportStates": [ "Flee.Switch", "Panic" ],
                "AlertedRange": { "Compute": "AlertedRange" }
              }
            },
            {
              "$Comment": "Starting a timer to get out of greet state if nothing else got us out of there. TODO: expose the timer duration",
              "Continue": true,
              "Sensor": {
                "Type": "Target"
              },
              "ActionsBlocking": true,
              "Actions": [
                {
                  "Type": "Timeout",
                  "Delay": { "Compute": "GreetStateTimeout" }
                },
                {
                  "Type": "SetAlarm",
                  "Name": "Greet_Ready",
                  "DurationRange": { "Compute": "GreetTimeout" }
                },
                {
                  "Type": "State",
                  "State": "Idle"
                }
              ]
            },
            {
              "$Comment": "Watching a target always, if we have any",
              "Continue": true,
              "Sensor": {
                "Type": "Target",
                "Range": { "Compute": "AlertedRange" }
              },
              "HeadMotion": {
                "Type": "Watch"
              }
            },
            {
              "Enabled": { "Compute": "!isEmptyStringArray(AttractiveItemSet)" },
              "$Comment": "If the target is holding a liked item, follow it",
              "Sensor": {
                "Type": "And",
                "Sensors": [
                  {
                    "Type": "Target",
                    "Range": { "Compute": "ViewRange" },
                    "Filters": [
                      {
                        "Type": "ItemInHand",
                        "Items": { "Compute": "AttractiveItemSet" }
                      },
                      {
                        "Type": "Attitude",
                        "Attitudes": [ "Revered", "Friendly" ]
                      }
                    ]
                  }
                ]
              },
              "Type": "Random",
              "ExecuteFor": [ 15, 20 ],
              "Instructions": [
                {
                  "Weight": { "Compute": "WeightFollowItem" },
                  "Sensor": {
                    "Type": "Target"
                  },
                  "ActionsBlocking": true,
                  "Actions": [
                    {
                      "Type": "SpawnParticles",
                      "ParticleSystem": "Hearts_Subtle",
                      "Offset": { "Compute": "ParticleOffset" },
                      "TargetNodeName": "Head"
                    },
                    {
                      "Type": "Timeout",
                      "Delay": { "Compute": "FollowItemPreDelay" }
                    },
                    {
                      "Type": "State",
                      "State": "SeekFood"
                    }
                  ]
                },
                {
                  "Enabled": { "Compute": "WeightFollowItem < 100" },
                  "Weight": { "Compute": "100 - WeightFollowItem" },
                  "Sensor": {
                    "Type": "Target"
                  },
                  "ActionsBlocking": true,
                  "Actions": [
                    {
                      "Type": "Nothing"
                    }
                  ]
                }
              ]
            },
            {
              "$Comment": "No target, back to idle",
               "Sensor": {
                "Type": "Not",
                "Sensor": {
                  "Type": "Target"
                }
              },
              "Actions": [
                {
                  "Type": "Timeout",
                  "Delay": [ 2, 2 ],
                  "Action": {
                    "Type": "State",
                    "State": "Idle"
                  }
                }
              ]
            }
          ]
        },
        {
          "Sensor": {
            "Type": "State",
            "State": "SeekFood"
          },
          "Instructions": [
            {
              "Reference": "Component_Instruction_Damage_Check",
              "Modify": {
                "_ExportStates": [ "Flee.Switch", "Panic" ],
                "AlertedRange": { "Compute": "AlertedRange" }
              }
            },
            {
              "$Comment": "If enabled, start a timer to give up on chasing a target",
              "Enabled": { "Compute": "FollowItemTimeoutEnabled" },
              "Continue": true,
              "Sensor": {
                "Type": "Target"
              },
              "ActionsBlocking": true,
              "Actions": [
                {
                  "Type": "Timeout",
                  "Delay": { "Compute": "FollowItemTimeout" }
                },
                {
                  "Type": "State",
                  "State": ".GiveUp"
                }
              ]
            },
            {
              "Sensor": {
                "Type": "State",
                "State": ".Ate"
              },
              "Instructions": [
                {
                  "Continue": true,
                  "Sensor": {
                    "Type": "Target",
                    "Range": { "Compute": "AlertedRange" },
                    "Filters": [
                      {
                        "Type": "LineOfSight"
                      }
                    ]
                  },
                  "HeadMotion": {
                    "Type": "Watch"
                  }
                },
                {
                  "ActionsBlocking": true,
                  "Actions": [
                    {
                      "Type": "SetAlarm",
                      "Name": "Eat_Ready",
                      "DurationRange": { "Compute": "EatTimeout" }
                    },
                    {
                      "$Comment": "No need to greet another player after being fed",
                      "Type": "SetAlarm",
                      "Name": "Greet_Ready",
                      "DurationRange": { "Compute": "GreetTimeout" }
                    },
                    {
                      "Type": "SetStat",
                      "Stat": "Health",
                      "Value": { "Compute": "MaxHealth" }
                    },
                    {
                      "Type": "Timeout",
                      "Delay": [ 3, 5 ]
                    },
                    {
                      "Type": "State",
                      "State": "Idle"
                    }
                  ]
                }
              ]
            },
            {
              "$Comment": "Watching a target always, if we have any",
              "Continue": true,
              "Sensor": {
                "Type": "Target",
                "Range": { "Compute": "AlertedRange" }
              },
              "HeadMotion": {
                "Type": "Watch"
              }
            },
            {
              "Sensor": {
                "Type": "State",
                "State": ".GiveUp"
              },
              "Instructions": [
                {
                  "Sensor": {
                    "Type": "And",
                    "Sensors": [
                      {
                        "Type": "Target",
                        "Range": { "Compute": "AlertedRange" }
                      },
                      {
                        "Type": "Alarm",
                        "Name": "Eat_Ready",
                        "State": "Unset"
                      }
                    ]
                  },
                  "ActionsBlocking": true,
                  "Actions": [
                    {
                      "Type": "PlayAnimation",
                      "Slot": "Status"
                    },
                    {
                      "Type": "Timeout",
                      "Delay": [ 3, 6 ]
                    },
                    {
                      "Type": "PlayAnimation",
                      "Slot": "Status",
                      "Animation": "Alerted"
                    },
                    {
                      "Type": "SpawnParticles",
                      "ParticleSystem": "Angry",
                      "Offset": { "Compute": "ParticleOffset" },
                      "TargetNodeName": "Head"
                    },
                    {
                      "Type": "State",
                      "State": "Idle"
                    }
                  ]
                },
                {
                  "Actions": [
                    {
                      "Type": "Timeout",
                      "Delay": [ 3, 5 ],
                      "Action": {
                        "Type": "State",
                        "State": "Idle"
                      }
                    }
                  ]
                }
              ]
            },
            {
              "Enabled": { "Compute": "!isEmptyStringArray(AttractiveItemSet)" },
              "$Comment": "If the target is holding a liked item, follow it",
              "Sensor": {
                "Type": "Target",
                "Range": { "Compute": "ViewRange" },
                "Filters": [
                  {
                    "Type": "ItemInHand",
                    "Items": { "Compute": "AttractiveItemSet" }
                  },
                  {
                    "Type": "Attitude",
                    "Attitudes": [ "Revered", "Friendly" ]
                  }
                ]
              },
              "BodyMotion": {
                "Type": "MaintainDistance",
                "DesiredDistanceRange": { "Compute": "FollowItemDistance" },
                "RelativeForwardsSpeed": 0.3,
                "RelativeBackwardsSpeed": 0.3
              },
              "Actions": [
                {
                  "Type": "PlayAnimation",
                  "Slot": "Status",
                  "Animation": "Curious"
                }
              ]
            },
            {
              "$Comment": "Target is no longer holding an item or is too far away, give up and go back to idle",
              "Sensor": {
                "Type": "Target"
              },
              "ActionsBlocking": true,
              "ActionsAtomic": true,
              "Actions": [
                {
                  "Type": "State",
                  "State": ".GiveUp"
                }
              ]
            },
            {
              "Actions": [
                {
                  "Type": "Timeout",
                  "Delay": [ 2, 3 ],
                  "Action": {
                    "Type": "State",
                    "State": "Idle"
                  }
                }
              ]
            }
          ]
        },
        {
          "Sensor": {
            "Type": "State",
            "State": "Flee"
          },
          "Instructions": [
            {
              "$Comment": "TODO: Add a state message",
              "Enabled": { "Compute": "!isEmptyStringArray(FlockArray)" },
              "Continue": true,
              "Sensor": {
                "Type": "Any",
                "Once": true
              },
              "Actions": [
                {
                  "Type": "FlockBeacon",
                  "Message": "Flock_Attack",
                  "SendTargetSlot": "LockedTarget"
                }
              ]
            },
            {
              "Reference": "Component_Instruction_Damage_Check",
              "Modify": {
                "_ExportStates": [ "Flee.Switch", "Panic" ],
                "AlertedRange": { "Compute": "AlertedRange" }
              }
            },
            {
              "Sensor": {
                "Type": "State",
                "State": ".Switch"
              },
              "Instructions": [
                {
                  "Sensor": {
                    "Type": "Target",
                    "TargetSlot": "LockedTarget",
                    "Range": { "Compute": "AttackRange" }
                  },
                  "Instructions": [
                    {
                      "Continue": true,
                      "Sensor": {
                        "Type": "Target",
                        "Once": true
                      },
                      "Actions": [
                        {
                          "$TODO": "Maybe friendly lifestock doesnt override it for player when hit",
                          "Type": "OverrideAttitude",
                          "Attitude": "Hostile",
                          "Duration": { "Compute": "IgnoreAttitudeOverride" }
                        }
                      ]
                    },
                    {
                      "Enabled": { "Compute": "AttackWhenStartled" },
                      "Sensor": {
                        "Type": "Target",
                        "Filters": [
                          {
                            "Type": "Not",
                            "Filter": {
                              "Type": "ViewSector",
                              "ViewSector": 270
                            }
                          },
                          {
                            "Type": "Not",
                            "Filter": {
                              "Type": "Attitude",
                              "Attitudes": [ "Revered", "Friendly" ]
                            }
                          }
                        ]
                      },
                      "ActionsBlocking": true,
                      "Actions": [
                        {
                          "Type": "PlayAnimation",
                          "Slot": "Status",
                          "Animation": "Alerted"
                        },
                        {
                          "Type": "Timeout",
                          "Delay": [ 0.2, 0.2 ]
                        },
                        {
                          "Type": "PlayAnimation",
                          "Slot": "Status"
                        },
                        {
                          "Type": "State",
                          "State": ".Attack"
                        }
                      ]
                    },
                    {
                      "Actions": [
                        {
                          "Type": "State",
                          "State": ".Default"
                        }
                      ]
                    }
                  ]
                },
                {
                  "Sensor": {
                    "Type": "Target",
                    "TargetSlot": "LockedTarget",
                    "Range": { "Compute": "AlertedRange" }
                  },
                  "Actions": [
                    {
                      "Type": "State",
                      "State": ".Default"
                    }
                  ]
                },
                {
                  "Actions": [
                    {
                      "Type": "State",
                      "State": "Panic"
                    }
                  ]
                }
              ]
            },
            {
              "Sensor": {
                "Type": "State",
                "State": ".Attack"
              },
              "ActionsBlocking": true,
              "Actions": [
                {
                  "Type": "Attack",
                  "Attack": { "Compute": "Attack" },
                  "AttackPauseRange": [ 1, 2 ]
                },
                {
                  "Type": "Timeout",
                  "Delay": [ 0.3, 0.3 ],
                  "Action": {
                    "Type": "State",
                    "State": ".Default"
                  }
                }
              ]
            },
            {
              "Sensor": {
                "Type": "Target",
                "Range": { "Compute": "AlertedRange + 3" }
              },
              "BodyMotion": {
                "Type": "Flee",
                "SlowDownDistance": { "Compute": "AlertedRange - 3" },
                "StopDistance": { "Compute": "AlertedRange + 3" },
                "RelativeSpeed": 0.68
              },
              "Actions": [
                {
                  "Type": "Timeout",
                  "Delay": [ 8, 8 ],
                  "Action": {
                    "Type": "State",
                    "State": ".Switch"
                  }
                }
              ]
            },
            {
              "Actions": [
                {
                  "Type": "Timeout",
                  "Delay": [ 3, 6 ],
                  "Action": {
                    "Type": "State",
                    "State": "Idle"
                  }
                }
              ]
            }
          ]
        },
        {
          "Sensor": {
            "Type": "State",
            "State": "Panic"
          },
          "Instructions": [
            {
              "Continue": true,
              "Sensor": {
                "Type": "Any",
                "Once": true
              },
              "Actions": [
                {
                  "Type": "PlayAnimation",
                  "Slot": "Status",
                  "Animation": "Alerted"
                }
              ]
            },
            {
              "Continue": true,
              "Actions": [
                {
                  "Type": "Timeout",
                  "Delay": [ 6, 12 ],
                  "Action": {
                    "Type": "State",
                    "State": "Idle"
                  }
                }
              ]
            },
            {
              "Sensor": {
                "Type": "Damage",
                "Combat": true
              },
              "BodyMotion": {
                "Type": "Flee",
                "SlowDownDistance": 9,
                "StopDistance": 14,
                "RelativeSpeed": 1,
                "RelaxedMoveConstraints": false
              }
            },
            {
              "BodyMotion": {
                "Type": "WanderInCircle",
                "Radius": 10,
                "MaxHeadingChange": 90,
                "RelativeSpeed": 1,
                "RelaxedMoveConstraints": true
              }
            }
          ]
        },
        {
          "Sensor": {
            "Type": "State",
            "State": "$Tamed",
            "IgnoreMissingSetState": true
          },
          "Instructions": [
            {
              "Sensor": {
                "Reference": "Component_Sensor_Standard_Detection",
                "Modify": {
                  "ViewRange": { "Compute": "ViewRange" },
                  "ViewSector": { "Compute": "ViewSector" },
                  "HearingRange": { "Compute": "SmellingRange" },
                  "AbsoluteDetectionRange": { "Compute": "AbsoluteDetectionRange" },
                  "Attitudes": [ "Revered", "Friendly" ],
                  "GetNPCs": false
                }
              },
              "Instructions": [
                {
                  "Sensor": {
                    "Type": "Any",
                    "Once": true
                  },
                  "Actions": [
                    {
                      "Type": "SpawnParticles",
                      "ParticleSystem": "Hearts",
                      "Offset": { "Compute": "ParticleOffset" },
                      "TargetNodeName": "Head"
                    }
                  ]
                },
                {
                  "Sensor": {
                    "Type": "Target",
                    "Range": { "Compute": "AlertedRange" },
                    "Filters": [
                      {
                        "Type": "LineOfSight"
                      }
                    ]
                  },
                  "HeadMotion": {
                    "Type": "Watch"
                  },
                  "Actions": [
                    {
                      "Type": "SetAlarm",
                      "Name": "Eat_Ready",
                      "DurationRange": { "Compute": "EatTimeout" }
                    },
                    {
                      "Type": "Timeout",
                      "Delay": [ 2, 2 ],
                      "Action": {
                        "Type": "State",
                        "State": "SeekFood"
                      }
                    }
                  ]
                },
                {
                  "Actions": [
                    {
                      "Type": "Timeout",
                      "Delay": [ 2, 2 ],
                      "Action": {
                        "Type": "State",
                        "State": "Idle"
                      }
                    }
                  ]
                }
              ]
            }
          ]
        },
        {
          "Sensor": {
            "Type": "State",
            "State": "$Harvest"
          },
          "Instructions": [
            {
              "$Comment": "Base harvest logic: particles, sound, alarm (always runs)",
              "Continue": true,
              "Sensor": {
                "Type": "Any",
                "Once": true
              },
              "Actions": [
                {
                  "Type": "PlayAnimation",
                  "Slot": "Status",
                  "Animation": "Alerted"
                },
                {
                  "Type": "SpawnParticles",
                  "ParticleSystem": { "Compute": "HarvestParticles" },
                  "Offset": { "Compute": "ParticleOffset" },
                  "TargetNodeName": "Head"
                },
                {
                  "Type": "PlaySound",
                  "SoundEventId": { "Compute": "HarvestSound" }
                },
                {
                  "Type": "SetAlarm",
                  "Name": "Harvest_Ready",
                  "DurationRange": { "Compute": "HarvestTimeout" }
                }
              ]
            },
            {
              "$Comment": "Drop item only if HarvestDropList is set",
              "Enabled": { "Compute": "!isEmpty(HarvestDropList)" },
              "Continue": true,
              "Sensor": {
                "Type": "Any",
                "Once": true
              },
              "Actions": [
                {
                  "Type": "DropItem",
                  "DropList": { "Compute": "HarvestDropList" },
                  "Distance": [ 0.2, 0.5 ],
                  "Delay": [ 0, 0 ],
                  "DropSector": [ -360, 360 ],
                  "PitchHigh": false,
                  "ThrowSpeed": 14
                }
              ]
            },
            {
              "$Comment": "Replace buckets",
              "Enabled": { "Compute": "!isEmpty(HarvestAddItemBucket) || !isEmpty(HarvestAddItemDecoBucket)" },
              "Continue": true,
              "Sensor": {
                "Type": "Any",
                "Once": true
              },
              "Instructions": [
                {
                  "Enabled": { "Compute": "!isEmpty(HarvestAddItemBucket)" },
                  "Sensor": {
                    "Type": "Target",
                    "Filters": [
                      {
                        "Type": "ItemInHand",
                        "Items": [ "Container_Bucket" ]
                      }
                    ]
                  },
                  "Actions": [
                    {
                      "Type": "Inventory",
                      "UseTarget": true,
                      "Operation": "RemoveHeldItem"
                    },
                    {
                      "Type": "Inventory",
                      "UseTarget": true,
                      "Operation": "Add",
                      "Item": { "Compute": "HarvestAddItemBucket" },
                      "Count": 1
                    }
                  ]
                },
                {
                  "Enabled": { "Compute": "!isEmpty(HarvestAddItemDecoBucket)" },
                  "Sensor": {
                    "Type": "Target",
                    "Filters": [
                      {
                        "Type": "ItemInHand",
                        "Items": [ "Container_Bucket" ]
                      }
                    ]
                  },
                  "Actions": [
                    {
                      "Type": "Inventory",
                      "UseTarget": true,
                      "Operation": "RemoveHeldItem"
                    },
                    {
                      "Type": "Inventory",
                      "UseTarget": true,
                      "Operation": "Add",
                      "Item": { "Compute": "HarvestAddItemDecoBucket" },
                      "Count": 1
                    }
                  ]
                }
              ]
            },
            {
              "$Comment": "Replace Deco_Bucket with milk when held",
              "Enabled": { "Compute": "!isEmpty(HarvestAddItemDecoBucket)" },
              "Continue": true,
              "Sensor": {
                "Type": "And",
                "Sensors": [
                  {
                    "Type": "Any",
                    "Once": true
                  },
                  {
                    "Type": "Target",
                    "Filters": [
                      {
                        "Type": "ItemInHand",
                        "Items": [ "Deco_Bucket" ]
                      }
                    ]
                  }
                ]
              },
              "Actions": [
                {
                  "Type": "Inventory",
                  "UseTarget": true,
                  "Operation": "RemoveHeldItem"
                },
                {
                  "Type": "Inventory",
                  "UseTarget": true,
                  "Operation": "Add",
                  "Item": { "Compute": "HarvestAddItemDecoBucket" },
                  "Count": 1
                }
              ]
            },
            {
              "$Comment": "If there are configured attachments for the 'harvested' state, apply them",
              "Enabled": { "Compute": "IsHarvestable && !isEmpty(HarvestModelSlot)" },
              "Continue": true,
              "Actions": [
                {
                  "Type": "ModelAttachment",
                  "Slot": { "Compute": "HarvestModelSlot" },
                  "Attachment": { "Compute": "HarvestModelAttachmentHarvested" }
                }
              ]
            },
            {
              "ActionsBlocking": true,
              "Actions": [
                {
                  "Type": "Timeout",
                  "Delay": [ 2, 3 ]
                },
                {
                  "Type": "State",
                  "State": "Idle"
                }
              ]
            }
          ]
        }
      ]
    }
  ],
  "InteractionInstruction": {
    "Instructions": [
      {
        "Continue": true,
        "Actions": [
          {
            "Type": "LockOnInteractionTarget",
            "TargetSlot": "InteractionTarget"
          }
        ]
      },
      {
        "Enabled": { "Compute": "IsPettable" },
        "TreeMode": true,
        "Instructions": [
          {
            "InvertTreeModeResult": true,
            "Sensor": {
              "$Comment": "Check the negative first so we can exit early and avoid the rest of the logic",
              "Type": "Not",
              "Sensor": {
                "Type": "And",
                "Sensors": [
                  {
                    "Type": "Alarm",
                    "Name": "Pet_Ready",
                    "State": "Unset"
                  },
                  {
                    "Type": "Not",
                    "Sensor": {
                      "Type": "State",
                      "State": "Sleep"
                    }
                  },
                  {
                    "Type": "CanInteract",
                    "Attitudes": { "Compute": "PetRequiredAttitudes" }
                  },
                  {
                    "Type": "Target",
                    "TargetSlot": "InteractionTarget",
                    "Filters": [
                      {
                        "Type": "Not",
                        "Filter": {
                          "Type": "ItemInHand",
                          "Hand": "Main",
                          "Items": [ "*" ]
                        }
                      }
                    ]
                  }
                ]
              }
            },
            "Actions": [
              {
                "Type": "Nothing"
              }
            ]
          },
          {
            "InvertTreeModeResult": true,
            "Continue": true,
            "Sensor": {
              "Type": "Any"
            },
            "Actions": [
              {
                "Type": "SetInteractable",
                "Interactable": true,
                "Hint": "server.interactionHints.pet"
              }
            ]
          },
          {
            "Sensor": {
              "Type": "HasInteracted"
            },
            "Instructions": [
              {
                "Sensor": {
                  "Type": "Target"
                },
                "Actions": [
                  {
                    "Type": "PlayAnimation",
                    "Slot": "Status",
                    "Animation": { "Compute": "PetAnimation" }
                  },
                  {
                    "Type": "SpawnParticles",
                    "ParticleSystem": "Hearts_Subtle",
                    "Offset": { "Compute": "ParticleOffset" },
                    "TargetNodeName": "Head"
                  },
                  {
                    "Type": "SetAlarm",
                    "Name": "Pet_Ready",
                    "DurationRange": { "Compute": "PetTimeout" }
                  }
                ]
              }
            ]
          }
        ]
      },
      {
        "TreeMode": true,
        "Instructions": [
          {
            "InvertTreeModeResult": true,
            "Sensor": {
              "$Comment": "Check the negative first so we can exit early and avoid the rest of the logic",
              "Type": "Not",
              "Sensor": {
                "Type": "And",
                "Sensors": [
                  {
                    "Type": "Alarm",
                    "Name": "Eat_Ready",
                    "State": "Unset"
                  },
                  {
                    "Type": "State",
                    "State": "SeekFood"
                  },
                  {
                    "Type": "Not",
                    "Sensor": {
                      "Type": "State",
                      "State": "SeekFood.Ate"
                    }
                  },
                  {
                    "Type": "CanInteract",
                    "Attitudes": { "Compute": "FeedRequiredAttitudes" }
                  },
                  {
                    "Type": "Target",
                    "TargetSlot": "InteractionTarget",
                    "Filters": [
                      {
                        "Type": "ItemInHand",
                        "Hand": "Main",
                        "Items": { "Compute": "AttractiveItemSet" }
                      }
                    ]
                  }
                ]
              }
            },
            "Actions": [
              {
                "Type": "Nothing"
              }
            ]
          },
          {
            "InvertTreeModeResult": true,
            "Continue": true,
            "Sensor": {
              "Type": "Any"
            },
            "Actions": [
              {
                "Type": "SetInteractable",
                "Interactable": true,
                "Hint": "server.interactionHints.feed"
              }
            ]
          },
          {
            "Sensor": {
              "Type": "HasInteracted"
            },
            "Instructions": [
              {
                "Sensor": {
                  "Type": "Target",
                  "TargetSlot": "InteractionTarget"
                },
                "Actions": [
                  {
                    "Type": "Inventory",
                    "UseTarget": true,
                    "Operation": "RemoveHeldItem",
                    "Count": 1
                  },
                  {
                    "Type": "SpawnParticles",
                    "ParticleSystem": "Hearts_Subtle",
                    "Offset": { "Compute": "ParticleOffset" },
                    "TargetNodeName": "Head"
                  },
                  {
                    "Type": "State",
                    "State": "SeekFood.Ate"
                  }
                ]
              }
            ]
          }
        ]
      },
      {
        "Enabled": { "Compute": "IsHarvestable" },
        "TreeMode": true,
        "Instructions": [
          {
            "InvertTreeModeResult": true,
            "Sensor": {
              "$Comment": "Check the negative first so we can exit early and avoid the rest of the logic",
              "Type": "Not",
              "Sensor": {
                "Type": "And",
                "Sensors": [
                  {
                    "Type": "Alarm",
                    "Name": "Harvest_Ready",
                    "State": "Unset"
                  },
                  {
                    "Type": "CanInteract",
                    "Attitudes": { "Compute": "HarvestRequiredAttitudes" }
                  },
                  {
                    "Type": "Target",
                    "TargetSlot": "InteractionTarget",
                    "Filters": [
                      {
                        "Enabled": { "Compute": "!isEmptyStringArray(HarvestInteractionRequiredItems)" },
                        "Type": "ItemInHand",
                        "Hand": "Main",
                        "Items": { "Compute": "HarvestInteractionRequiredItems" }
                      }
                    ]
                  }
                ]
              }
            },
            "Actions": [
              {
                "Type": "Nothing"
              }
            ]
          },
          {
            "InvertTreeModeResult": true,
            "Continue": true,
            "Sensor": {
              "Type": "Any"
            },
            "Actions": [
              {
                "Type": "SetInteractable",
                "Interactable": true,
                "Hint": ""
              }
            ]
          },
          {
            "Sensor": {
              "Enabled": { "Compute": "!isEmpty(HarvestInteractionContext)" },
              "Type": "InteractionContext",
              "Context": { "Compute": "HarvestInteractionContext" }
            },
            "Actions": [
              {
                "Type": "State",
                "State": "$Harvest"
              }
            ]
          }
        ]
      },
      {
        "Enabled": { "Compute": "IsMountable" },
        "TreeMode": true,
        "Instructions": [
          {
            "InvertTreeModeResult": true,
            "Sensor": {
              "$Comment": "Check the negative first so we can exit early and avoid the rest of the logic",
              "Type": "Not",
              "Sensor": {
                "Type": "And",
                "Sensors": [
                  {
                    "Type": "CanInteract",
                    "ViewSector": 360,
                    "Attitudes": [ "Revered", "Friendly" ]
                  },
                  {
                    "Type": "Not",
                    "Sensor": {
                      "Type": "State",
                      "State": "Sleep"
                    }
                  }
                ]
              }
            },
            "Actions": [
              {
                "Type": "Nothing"
              }
            ]
          },
          {
            "InvertTreeModeResult": true,
            "Continue": true,
            "Sensor": {
              "Type": "Any"
            },
            "Actions": [
              {
                "Type": "SetInteractable",
                "Interactable": true,
                "Hint": "server.interactionHints.mount"
              }
            ]
          },
          {
            "Sensor": {
              "Type": "HasInteracted"
            },
            "Actions": [
              {
                "Type": "PlayAnimation",
                "Slot": "Status"
              },
              {
                "Type": "Mount",
                "AnchorX": { "Compute": "MountAnchorX" },
                "AnchorY": { "Compute": "MountAnchorY" },
                "AnchorZ": { "Compute": "MountAnchorZ" },
                "MovementConfig": { "Compute": "MountMovementConfig" }
              }
            ]
          }
        ]
      },
      {
        "$Comment": "Only now that we've failed to match all possible interactions do we set interactability to false.",
        "Actions": [
          {
            "Type": "SetInteractable",
            "Interactable": false
          }
        ]
      }
    ]
  },
  "NameTranslationKey": { "Compute": "NameTranslationKey" }
}