Skip to content

Custom Pets Guide

You can add your own collector pets, combat pets and mounts without touching any code. Each pet type is one JSON file in the plugin folder.


The plugin keeps its files in mods/kyuubisoft_pets/ on the server:

mods/kyuubisoft_pets/
├── config.json
├── stat-pool.json stats, rarity rules, combat defaults
├── loot_luck_blacklist.json
├── pets.db pet database (SQLite)
├── npc-roles/ NPC roles, written on every server start
└── pet-types/
├── collector/ 26 collector pets + _template.json
├── combat/ 13 combat pets + _template.json
└── mount/ 9 mounts + _template.json
mods/KyuubiSoftPets_CustomItems/ items generated for your custom pets

How the plugin reads pet-types/:

  • Every .json file below pet-types/ is loaded, also in further subfolders. Files whose name starts with _ are skipped; that is why the templates are called _template.json.
  • The module comes from the module field. Without it, the folder decides: combat/ and mount/ give that module, every other folder gives a collector pet.
  • JSON files placed directly in pet-types/ are moved into the folder of their module on the next load.
  • The shipped files are only written when they are missing. Your changes to them survive plugin updates, but a deleted shipped file comes back on the next start or reload, so change a shipped pet by editing its file.
  • Every id must be unique across all folders. With duplicates the file that loads last (alphabetical by path) wins.

  1. Copy the _template.json of the module you want (for example pet-types/collector/_template.json) and give the copy a new name, for example phoenix.json.
  2. Edit the copy. The fields are explained below.
  3. Restart the server. The log shows Loaded: collector/phoenix rarity=epic (item=Pet_Egg_Phoenix, file=...). Because no item Pet_Egg_Phoenix exists yet, the plugin writes one and logs Generated item 'Pet_Egg_Phoenix' for custom pet 'phoenix' and Restart the server once more to load the new items.
  4. Restart again. Hytale now loads the new item.
  5. Hand the pet out with /kspetadmin give <player> phoenix, in the admin window (“Create pet”, see Admin Panel), or as a blank egg (/give, shops, loot); a blank egg hatches on its first right-click.

Defaults are the values the plugin uses when a field is left out. The templates set most fields explicitly.

FieldTypeDefaultMeaning
idtext(required)Unique ID, used in commands and as the base of the item ID. Use lowercase letters, digits and _; commands lowercase what you type
displayNametext(empty: the ID is shown)Name shown in the compendium, the admin window and generated item names; new pets get it as their name
entityTypeIdtext(required)Model to use, by model name, for example Fox, Wolf_Black, Dragon_Frost
modelScalenumber0.8Size of the model in the world (0.5 = half size)
maxLevelnumber50Highest level
baseXpPerLevelnumber100XP needed for level 2
xpScaleFactornumber1.15Growth of the XP requirement per level (1.15 = 15 % more each level)
raritytextcommonuncommon, rare, epic or legendary (lowercase); see Rarity effects
descriptiontextemptyShown in the compendium for players who do not own the pet
obtainHinttextemptySince 1.9.0: text under “How to get it” in the compendium, for players who do not own the pet. Empty shows “Ask the server team how to get this pet.”
previewScalenumber0Since 1.9.0: extra size factor for the compendium’s 3D stage (0 = automatic only)
moduletextfrom the foldercollector, combat or mount

The XP needed from level L to L + 1 is baseXpPerLevel * xpScaleFactor ^ (L - 1).

FieldTypeDefaultMeaning
pickupRadiusnumber5.0Distance in blocks at which the pet grabs an item; the Pickup Range stat adds to it. The shipped pets use 1.5 to 2.5
eggItemIdtextPet_Egg_<Id>Item that summons the pet (see Summon items)
FieldTypeDefaultMeaning
runeItemIdtextBattle_Rune_<Id>Item that summons the pet
combatStats.baseDamagenumber8.0Base damage; the pet hits for (baseDamage + level * damagePerLevel) * (1 + Damage stat)
combatStats.damagePerLevelnumber0.5Damage added per level
combatStats.attackSpeednumber1.5Attacks per second
combatStats.attackRangenumber3.0Distance in blocks from which the pet hits
combatStats.aggroRangenumber15.0Shown in the stats; not used for targeting
combatStats.leashDistancenumber20.0Maximum distance between pet and a new target
combatStats.attackAnimationtextBiteAnimation played on each hit (Bite, Ram, SwingLeft, …); an empty value plays Attack
combatStats.attackAnimationsIdtextemptyAnimation set of the model, for example Wolf_Black_Default; empty uses <entityTypeId>_Default
combatStats.baseHealthnumber0HP at level 1 when combat pet mortality is on; 0 = use combatBalance.mortality.baseHealth
combatStats.healthPerLevelnumber-1HP per level above 1 with mortality on; -1 = use combatBalance.mortality.healthPerLevel

Combat pets need the combat module (modules.combat); their NPC role is only loaded while it is on. How combat pets behave: Combat Pets.

FieldTypeDefaultMeaning
hornItemIdtextMount_Horn_<Id>Item that summons the mount
mountConfig.mountTypetextwalkwalk, fly or swim
mountConfig.mountYOffsetnumber2.5Seat height of the rider above the mount, in blocks
mountConfig.speednumber1.5Movement speed while riding (1.0 = normal)
mountConfig.baseHealthnumber200Added to the mount’s health; mounts are invulnerable, so it has no effect in 1.12.1

A speed other than 1.0 needs a speed role (KS_Mount_Walk_S14_Role for 1.4). Walk roles for 1.1 to 3.0 and the fly role for 1.8 ship with the plugin; any other speed is generated on server start. Restart the server after adding a mount with a new speed. How mounts behave: Mounts.

FieldMeaning
npcRoleIdNPC role to use instead of the default (KS_Pet_Follow_Role for collector pets, KS_Pet_Combat_Role for combat pets, the KS_Mount_* roles for mounts). If the role does not exist, a collector or combat pet falls back to KS_Pet_Follow_Role; a mount is not summoned. A collector pet with a role that lacks the shipped role’s leash instruction still follows you but does not fetch items
followDistance, followSpeedStill in the shipped files, but not read in 1.12.1; the NPC role decides how the pet follows
baseBuffs, buffsPerLevelFixed buffs from older versions, only used for pets that have no rolled stats. An xp_bonus entry in them is always added to the pet’s XP gain
abilitiesRead from the file, but not used

Fields starting with _ (such as the templates’ _comment) are ignored.


  • If you leave the item ID out, it is built from the pet’s ID with every part capitalised: baby_phoenix becomes Pet_Egg_Baby_Phoenix, Battle_Rune_Baby_Phoenix or Mount_Horn_Baby_Phoenix.
  • On every start and reload the plugin checks each pet type’s item. If no item with that ID exists (not in the jar, not in any loaded asset pack, not generated before), it writes one to mods/KyuubiSoftPets_CustomItems/Server/Item/Items/<ItemId>.json and creates that folder’s manifest.json (“Custom Pet Items”). Hytale loads it on the next start.
  • The generated item uses the plugin’s egg, rune or horn model with the texture of its rarity, is called <displayName> Egg, Battle Rune: <displayName> or Mount Horn: <displayName>, does not stack and is not dropped on death. You can edit the generated file; the plugin does not overwrite an existing one.
  • You can also point the item ID at an item from your own asset pack. It needs the plugin’s interaction on secondary use, or right-clicking it does nothing:
"Interactions": {
"Secondary": {
"Interactions": [ { "Type": "pet_egg_use" } ]
}
}

Use battle_rune_use for combat pets and mount_horn_use for mounts.


WhatEffect
StatsNumber of stats, unlock levels and roll quality from rarityRules in stat-pool.json (uncommon 2, rare 3, epic 4, legendary 5 stats; details in Collector Pets)
Item qualityThe summon item’s quality is set to the rarity on every start and reload (uncommon, rare, epic, legendary; anything else becomes Common), which colours the item name
Generated itemUses the egg, rune or horn texture of the rarity (Uncommon for any other value)
CompendiumPets are sorted by rarity (legendary first); names and rings show the rarity colour, also on the HUD
First hatchHatching the first egg of a collector pet type shows the “New Pet Discovered!” title with the pet name in the rarity colour

  • obtainHint and description are plain text from the file; they are not translated. Players who own the pet see its stats instead.
  • The 3D stage scales every model to a common size from its hitbox. previewScale multiplies on top of that: 1.5 shows the model larger, 0.7 smaller, 0 leaves it automatic.
  • Whether players see pets they do not own is set with ui.lockedPets in config.json (see Configuration and UI Pages).

{
"id": "phoenix",
"displayName": "Baby Phoenix",
"entityTypeId": "Skrill_Chick",
"modelScale": 0.6,
"pickupRadius": 2.0,
"maxLevel": 50,
"baseXpPerLevel": 120,
"xpScaleFactor": 1.18,
"eggItemId": "Pet_Egg_Phoenix",
"rarity": "epic",
"description": "A fiery phoenix chick that collects items.",
"obtainHint": "Sold by the pet trader at spawn.",
"previewScale": 0
}
{
"id": "fire_golem_combat",
"displayName": "Fire Golem",
"entityTypeId": "Bramblekin",
"modelScale": 1.2,
"maxLevel": 50,
"baseXpPerLevel": 140,
"xpScaleFactor": 1.15,
"rarity": "epic",
"description": "A burning golem that fights by your side.",
"obtainHint": "Boss drop.",
"previewScale": 0,
"module": "combat",
"runeItemId": "Battle_Rune_Fire_Golem",
"combatStats": {
"baseDamage": 12.0,
"damagePerLevel": 0.7,
"attackSpeed": 1.0,
"attackRange": 3.0,
"aggroRange": 15.0,
"leashDistance": 20.0,
"attackAnimation": "Bite",
"attackAnimationsId": "Bramblekin_Default",
"baseHealth": 0,
"healthPerLevel": -1
}
}
{
"id": "war_bison_mount",
"displayName": "War Bison",
"entityTypeId": "Bison",
"modelScale": 1.3,
"maxLevel": 30,
"baseXpPerLevel": 180,
"xpScaleFactor": 1.2,
"rarity": "legendary",
"description": "A massive war bison. Slow but unstoppable.",
"obtainHint": "",
"previewScale": 0,
"module": "mount",
"hornItemId": "Mount_Horn_War_Bison",
"mountConfig": {
"mountType": "walk",
"mountYOffset": 2.8,
"speed": 1.2,
"baseHealth": 200
}
}

entityTypeId takes any model name of the game; write it exactly as the model is named. The shipped pets use these:

  • Collector pets: Archaeopteryx, Bat, Bluebird, Bunny, Cactee, Cat, Crab, Dragon_Fire, Dragon_Frost, Duck, Fen_Stalker, Feran_Cube, Fox, Frog_Green, Gecko, Hatworm, Lizard_Sand, Meerkat, Owl_Snow, Parrot, Penguin, Skrill_Chick, Squirrel, Trork, Wolf_Black, Yeti
  • Combat pets: Boar, Bramblekin, Crawler_Void, Crocodile, Hyena, Lizard_Sand, Rex_Cave, Scorpion, Shadow_Knight, Spider, Wolf_Black, Wolf_Outlander_Priest, Yeti
  • Mounts: Bear_Polar, Bison, Camel, Dragon_Frost, Horse, Moose_Bull, Rex_Cave, Tiger_Sabertooth, Wolf_Black

Small modelScale values make baby versions of big creatures (the shipped Fire Dragon uses 0.16).


ChangeWhat you need
Values of an existing pet type (names, texts, rarity, XP curve, pickup radius, combat stats)/kspetadmin reload or “Reload” in the admin window
A new pet type whose item already exists/kspetadmin reload
A new pet type that needs a new itemTwo restarts
A mount speed whose speed role does not exist yetOne restart

/kspetadmin reload reloads config.json, the pet types, stat-pool.json, the loot luck blacklist and the language files. Pets that already exist keep their rolled stats; new rolls use the new rules. Stats outside the new ranges are clamped when the owner joins next time.


The pet type is missing in /kspetadmin list

  • Check the folder (mods/kyuubisoft_pets/pet-types/...) and that the file name does not start with _.
  • Check the JSON syntax (no trailing commas). The log shows Failed to load <file>: ... or Invalid pet type in <file>: missing id.

No item was generated

  • Look for Generated item '...' in the log and in mods/KyuubiSoftPets_CustomItems/Server/Item/Items/.
  • No file is generated when an item with that ID already exists somewhere (jar, another asset pack). Then that item is used.

Right-clicking the item does nothing

  • The log line Pet egg interaction: no pet type for item '<id>' — registered eggs: [...] means the item ID in the pet type does not match the item.
  • Items from your own asset pack need the interaction shown in Summon items.
  • Battle Runes and Mount Horns do nothing while their module is off.

The pet does not appear

  • Invalid entityTypeId for pet: <name>: the model name is wrong.
  • Invalid entityTypeId for mount: <name>: the same for a mount.
  • NPC Role not found: KS_Pet_Follow_Role — cannot spawn pet <id>: the plugin’s NPC roles did not load; check the start of the server log.
  • Mount role not found: <role>: the speed role of a new mount speed (or the mount’s npcRoleId) is missing; restart the server after a speed change.

The collector pet does not fetch items

  • Keep pickupRadius at 1.5 or more. The shipped follow role stops the pet about one block from the item, so a smaller radius may never reach it.
  • A custom npcRoleId without the shipped role’s leash instruction follows but never fetches.

The pet is too big or too small

  • modelScale sizes the pet in the world, previewScale only in the compendium.

Useful admin commands while testing: /kspetadmin list, /kspetadmin give <player> <type>, /kspetadmin reload and /kspetadmin inspect hand. Full syntax: Commands.