So an aspiring modder asked how one does to add a creature with its own animations into the world of Stonehearth, and I thought I’d write up some sort of tutorial on this. And then I thought: “let’s start from the beginning, why not!” So here we go!
I’m going to use the Golem from The Mythical Creatures mod for the examples. Furthermore, this tutorial is still valid even if you don’t have your own animations; just ignore those parts.
This turned out to be a whole lot longer than I anticipated…
Part 1 - The beginnings of an entity
The first and most important step is to add the models in the mod! Yeah ok, chanses are you’ve already done this, though I want to point out that you should have a good organization for your files. It will make your modding life easier (trust me).
Here’s the folder structure for this tutorial:
It’s a bit hard to see, but manifest.json is actually directly under the tmc folder.
Before we get to how the entity’s description is supposed to look like, let’s take a quick gander at the manifest.
Here, it’s enough to add one or two extra values under "aliases"
:
{
"info":
{
"name" : "The Mythical Creatures",
"version" : 1
},
"aliases":
{
"forest:golem" : "file(entities/forest_myth/golem)", // The actual creature
"skeletons:golem" : "file(data/rigs/golem)" // The effects and animations for the golem
}
}
These will be used to get a path to other files much easier, which will be more apparent later on.
## 1.1 - Molding a personality
So, with that out of the way, we can take a look at how an entity is described. There’s much to consider in what kind of behavior an entity should have. It’s a good thing though that there are existing entities that pretty much behave how we want to and can then do a copy-paste and changing some details. When defining the Golem; I took the description off of the Goblin and changed it to fit the Golem.
Though it’s always a good thing to know what detail you’re changing, so let’s take a look at the Golem’s description and go into more detail of each part.
{
"type" : "entity",
"mixins" : "stonehearth:mixins:monster",
"components":
{
"render_info":
{
"animation_table" : "tmc:skeletons:golem",
"scale" : 0.12
},
"model_variants":
{
"default":
{
"models": [ "file(golem.qb)" ]
}
},
"sensor_list":
{
"sensors":
{
"sight":
{
"radius" : 64
}
}
},
"unit_info":
{
"name" : "A Golem",
"description" : "An ancient guardian of the Dryads",
"player_id" : "critters"
},
"stonehearth:material":
{
"tags" : "stone golem"
},
"stonehearth:attributes":
{
"max_health":
{
"type" : "basic",
"value" : 200
},
"health":
{
"type" : "variable",
"equation" : "max_health"
},
"speed":
{
"type" : "basic",
"value" : 20
},
"courage":
{
"type" : "basic",
"value" : 99999
},
"menace":
{
"type" : "basic",
"value" : 70
}
},
"stonehearth:equipment" : {}
},
"entity_data":
{
"stonehearth:entity_radius" : 1.8,
"stonehearth:entity_reach" : 2.2,
"stonehearth:observers:avoid_threatening_entities":
{
"min_avoidance_distance" : 16,
"max_avoidance_distance" : 16
}
}
}
Let’s break down and try to explain each part:
-
"type"
- Describes what type this is for; must have value “entity” for creatures. So no touchie! -
"mixins"
- Takes data from another file. In this case it’s from “monster”, though it doesn’t necessarily mean that this creature is a monster so don’t take it too literally.I’ll cover different kinds of mixins, which are useful for creatures, below.
-
"components"
- Here’s a collection of all the components this entity starts off with, remember that all interactable objects that exist in the world are called entities and that components describes an entity. Note that there are much more components but these are among the more important ones for creatures.-
"render_info"
- The renderer component.-
"animation_table"
- Points to a file which describes the animations and effects for this entity. Note that we’re using the alias “skeletons:golem” from the mod “tmc” in this example. -
"scale"
- This entity’s scale. Standard value is 0.1.
-
-
"model_variants"
- What models to use.-
"default"
- The default models. There can be other kinds other than default, for example: berry bushes also has “depleted” to show a different model when it has no more berries to harvest.
-"models"
- An array of all the models to use.
-
-
"sensor_list"
- A core component that gives the entity a kind of awareness of its surroundings. This one has a sight of radius 64, which means the golem can see up to 64 units away from itself. -
"unit_info"
- Some basic information of the entity.-
"name"
- Its name. -
"description"
- Its description. -
"player_id"
- What faction this entity belongs to. Currently, this is most commonly used for animals with the id being"critters"
. Obviously the golem doesn’t belong to that faction, but this is for the sake of showing an example. If you’re curious about how to create a faction of your own, maybe there’ll be a different tutorial on that. At least I can mention that you can take a look at the factions that already exist and go from there (located in"stonehearth/services/server/population/data"
)
-
-
"stonehearth:material"
- What the entity is made of.-
"tags"
- Contains all the relevant tags for this entity. Example: the golem has two tags: “stone” and “golem”.
-
-
"stonehearth:attributes"
- All the attributes for this entity. In other words: these are the values that makes this entity perform differently from others. Note that these attributes are far from all that exist, though I’ve found that these are the most important for regular creatures at least.-
"max_health"
- Maximum health. -
"health"
- Current health (it’s independent of max_health). -
"speed"
- The running speed. -
"courage"
- How brave the creature is. -
"menace"
- How terryfying it is.-
"type"
- What kind of value to expect. Here we see the types “variable” and “basic”, but there’s also “random_range”. -
"value"
- Just some number. Expected when type = “basic”. -
"equation"
- Some equation which calculates what value to use. Useful if you want to derive from a variable, “health” uses “max_health” to decide its value for example. Expected when type = “variable”.
-
-
-
"stonehearth:equipment"
- This simply states that the entity can equip an item; it can’t take any values to start off with. Remember though, that if you want this creature to be able to attack, it needs to have a weapon equipped.
-
-
"entity_data"
- Has some general information of this entity.-
"stonehearth:entity_radius"
- The size of the entity. -
"stonehearth:entity_reach"
- How far the entity can reach. -
"stonehearth:observers:avoid_threatening_entities"
- The distance to check for enemies and run from them.
-
Mixins:
-
"stonehearth:mixins:monster"
: For creatures that are more aggressively inclined. Use this if you want your creature to be more combat oriented. -
"stonehearth:mixins:critter"
: Simple creatures, these are given simple attributes and AI. -
"stonehearth:mixins:pet"
: A kind of critter with some extra attributes. -
"stonehearth:mixins:base_human"
: A mixin for humans. Note though that this gives your creature the same AI and attributes as the hearthlings have, so it’s (currently) only recommended if your creature going to belong directly to a player and be part of building up a kingdom, ie build houses, craft various stuff, and so on. -
"stonehearth:mixins:undead"
: For undead creatures, obviously. -
"stonehearth:mixins:mob"
: The core mixin for any creature. All the above mixins have this mixin included so there’s rarely any need for this one, though if you’re specifically going to use this as your mixin; you’ll have to include what AI you want to use for the creature, since it has none itself.
AI. This is a really large subject and not something this tutorial will go into great detail, though it’s worth mentioning that you can specify what kind of AI you want your creature to have. Again, this tutorial won’t go into detail of what you can choose, but you can see an example of how to choose in the file "stonehearth/mixins/base_human/base_human.json"
.
Furthermore, in stonehearth’s manifest; you can take a peek at what kinds of AI you can choose (you can find them under "aliases"
, and they all begin with "ai_pack:"
).
## 1.2 - Putting on the moves
So now we’re looking at adding in custom animations for the entity.
Let’s start off with looking at the Golem’s skeleton file (located where its alias is pointing at):
{
"type" : "rig",
"skeleton":
{
BUNCH o' DATA
},
"animation_root" : "file(animations)",
"effects_root" : "file(effects)",
"postures" : "file(postures.json)"
}
Let’s break these down once more:
-
"type"
- As before this describes what type this is, and this must be set to “rig”. -
"skeleton"
- Contains the origin position of each object in the model. The origin of an object is the point around which that object animates. -
"animation_root"
- Points to the folder where all of the animations are stored. -
"effects_root"
- Points to the folder where all of the effects are stored (more on that in a bit). -
"postures"
- The file which describes what postures the entity uses. It’s used to replace specific effects for specific circumstances. E.g. when a hearthling is sitting down, all its idle animations will then be replaced with a sitting down animation.
So, effects.
Effects are those that play an animation, start up audio, show some particle effect, etc. So whenever some entity is doing something, an effect is being played! This can be anything from being idle to admiring a fire to fighting off a goblin horde.
Here’s the file structure for the Golem’s effects and animations:
It should be noted that while the animations can be named however you wish, most effects has to have a specific name. For example, when an entity is running the “run.json” effect is being played, and so there must exist be such a file, or else you will witness the big red wall of errors!
Let’s look at a couple of the effects. We’ve already mentioned “run.json” so let’s go with that one:
{
"type" : "effect",
"tracks":
{
"animation":
{
"type" : "animation_effect",
"animation" : "walk.json",
"start_time" : 0,
"loop" : true
}
}
}
As usual let’s break it down:
-
"type"
- You know this already! -
"tracks"
- Contains all the animations, audio, etc that will be played.-
"animation"
- An animation will be played, this is only symbolic though and can be named however you wish.-
"type"
- What kind of track will be played, this also decides what other values are to be expected. Since this is an animation type, the following data will show for such types. -
"start_time"
- How long to wait before playing the animation (in milliseconds). -
"animation"
- The name of the animation to play (it must exist under the animation root folder, which is specified in the rig file). -
"loop"
- Whether or not this animation should loop.
-
-
The second effect I’ll be showing is “combat_block.json”, though this time I’ll exclude the detailing; see if you can figure it all out on your own!
{
"type" : "effect",
"tracks":
{
"animation":
{
"type" : "animation_effect",
"animation" : "combat_block.json",
"start_time" : 0,
"loop" : false
},
"sound":
{
"type" : "sound_effect",
"duration" : 1000,
"start_time" : 200,
"min_distance" : 30,
"falloff" : 3.6,
"volume" : 30,
"track":
{
"type" : "one_of",
"items":
[
"stonehearth:sounds:woodsword_block_01",
"stonehearth:sounds:woodsword_block_02",
"stonehearth:sounds:woodsword_block_03"
]
}
},
"hit_spark":
{
"type" : "cubemitter",
"start_time" : 200,
"end_time" : 240,
"cubemitter" : "particles/combat/parry.cubemitter.json",
"transforms":
{
"x" : 0,
"y" : 2,
"z" : -1.5,
"rx" : 0,
"ry" : 0,
"rz" : 0
}
}
}
}
And that’s pretty much it! This ought to be everything you need to create your own creatures!
Next we’ll be looking at how to have these creatures show up in your game!