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.
Where the files are
Section titled “Where the files are”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 petsHow the plugin reads pet-types/:
- Every
.jsonfile belowpet-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
modulefield. Without it, the folder decides:combat/andmount/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
idmust be unique across all folders. With duplicates the file that loads last (alphabetical by path) wins.
Quick start
Section titled “Quick start”- Copy the
_template.jsonof the module you want (for examplepet-types/collector/_template.json) and give the copy a new name, for examplephoenix.json. - Edit the copy. The fields are explained below.
- Restart the server. The log shows
Loaded: collector/phoenix rarity=epic (item=Pet_Egg_Phoenix, file=...). Because no itemPet_Egg_Phoenixexists yet, the plugin writes one and logsGenerated item 'Pet_Egg_Phoenix' for custom pet 'phoenix'andRestart the server once more to load the new items. - Restart again. Hytale now loads the new item.
- 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.
Fields for every pet type
Section titled “Fields for every pet type”Defaults are the values the plugin uses when a field is left out. The templates set most fields explicitly.
| Field | Type | Default | Meaning |
|---|---|---|---|
id | text | (required) | Unique ID, used in commands and as the base of the item ID. Use lowercase letters, digits and _; commands lowercase what you type |
displayName | text | (empty: the ID is shown) | Name shown in the compendium, the admin window and generated item names; new pets get it as their name |
entityTypeId | text | (required) | Model to use, by model name, for example Fox, Wolf_Black, Dragon_Frost |
modelScale | number | 0.8 | Size of the model in the world (0.5 = half size) |
maxLevel | number | 50 | Highest level |
baseXpPerLevel | number | 100 | XP needed for level 2 |
xpScaleFactor | number | 1.15 | Growth of the XP requirement per level (1.15 = 15 % more each level) |
rarity | text | common | uncommon, rare, epic or legendary (lowercase); see Rarity effects |
description | text | empty | Shown in the compendium for players who do not own the pet |
obtainHint | text | empty | Since 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.” |
previewScale | number | 0 | Since 1.9.0: extra size factor for the compendium’s 3D stage (0 = automatic only) |
module | text | from the folder | collector, combat or mount |
The XP needed from level L to L + 1 is baseXpPerLevel * xpScaleFactor ^ (L - 1).
Collector pets
Section titled “Collector pets”| Field | Type | Default | Meaning |
|---|---|---|---|
pickupRadius | number | 5.0 | Distance 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 |
eggItemId | text | Pet_Egg_<Id> | Item that summons the pet (see Summon items) |
Combat pets
Section titled “Combat pets”| Field | Type | Default | Meaning |
|---|---|---|---|
runeItemId | text | Battle_Rune_<Id> | Item that summons the pet |
combatStats.baseDamage | number | 8.0 | Base damage; the pet hits for (baseDamage + level * damagePerLevel) * (1 + Damage stat) |
combatStats.damagePerLevel | number | 0.5 | Damage added per level |
combatStats.attackSpeed | number | 1.5 | Attacks per second |
combatStats.attackRange | number | 3.0 | Distance in blocks from which the pet hits |
combatStats.aggroRange | number | 15.0 | Shown in the stats; not used for targeting |
combatStats.leashDistance | number | 20.0 | Maximum distance between pet and a new target |
combatStats.attackAnimation | text | Bite | Animation played on each hit (Bite, Ram, SwingLeft, …); an empty value plays Attack |
combatStats.attackAnimationsId | text | empty | Animation set of the model, for example Wolf_Black_Default; empty uses <entityTypeId>_Default |
combatStats.baseHealth | number | 0 | HP at level 1 when combat pet mortality is on; 0 = use combatBalance.mortality.baseHealth |
combatStats.healthPerLevel | number | -1 | HP 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.
Mounts
Section titled “Mounts”| Field | Type | Default | Meaning |
|---|---|---|---|
hornItemId | text | Mount_Horn_<Id> | Item that summons the mount |
mountConfig.mountType | text | walk | walk, fly or swim |
mountConfig.mountYOffset | number | 2.5 | Seat height of the rider above the mount, in blocks |
mountConfig.speed | number | 1.5 | Movement speed while riding (1.0 = normal) |
mountConfig.baseHealth | number | 200 | Added 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.
Advanced and legacy fields
Section titled “Advanced and legacy fields”| Field | Meaning |
|---|---|
npcRoleId | NPC 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, followSpeed | Still in the shipped files, but not read in 1.12.1; the NPC role decides how the pet follows |
baseBuffs, buffsPerLevel | Fixed 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 |
abilities | Read from the file, but not used |
Fields starting with _ (such as the templates’ _comment) are ignored.
Summon items
Section titled “Summon items”- If you leave the item ID out, it is built from the pet’s ID with every part capitalised:
baby_phoenixbecomesPet_Egg_Baby_Phoenix,Battle_Rune_Baby_PhoenixorMount_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>.jsonand creates that folder’smanifest.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>orMount 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.
Rarity effects
Section titled “Rarity effects”| What | Effect |
|---|---|
| Stats | Number 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 quality | The 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 item | Uses the egg, rune or horn texture of the rarity (Uncommon for any other value) |
| Compendium | Pets are sorted by rarity (legendary first); names and rings show the rarity colour, also on the HUD |
| First hatch | Hatching the first egg of a collector pet type shows the “New Pet Discovered!” title with the pet name in the rarity colour |
Compendium fields
Section titled “Compendium fields”obtainHintanddescriptionare 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.
previewScalemultiplies 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.lockedPetsinconfig.json(see Configuration and UI Pages).
Examples
Section titled “Examples”Collector pet
Section titled “Collector pet”{ "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}Combat pet
Section titled “Combat pet”{ "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 }}Models
Section titled “Models”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).
Reload or restart
Section titled “Reload or restart”| Change | What 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 item | Two restarts |
| A mount speed whose speed role does not exist yet | One 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.
Troubleshooting
Section titled “Troubleshooting”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>: ...orInvalid pet type in <file>: missing id.
No item was generated
- Look for
Generated item '...'in the log and inmods/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’snpcRoleId) is missing; restart the server after a speed change.
The collector pet does not fetch items
- Keep
pickupRadiusat 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
npcRoleIdwithout the shipped role’s leash instruction follows but never fetches.
The pet is too big or too small
modelScalesizes the pet in the world,previewScaleonly in the compendium.
Useful admin commands while testing: /kspetadmin list, /kspetadmin give <player> <type>, /kspetadmin reload and /kspetadmin inspect hand. Full syntax: Commands.