Modding API Change: Loadouts

Hey modders!

In the last update, the format of the loadouts file was changed to require an “ordinal” field, which broke several mods. I’m really sorry about that! However, since compatibility got broken anyway, in the next release (roughly targeted at next Thursday) we’re switching loadouts to an explicitly backward-incompatible format which allows finer customization. The changes are:

  • The loadouts block is an object rather than an array, and each loadout must be specified under a unique ID (any string is fine, but using your mod name as part of it reduces the likelihood of mod conflicts). This allows mods to override parts of a loadout.
  • Each loadout can specify an ordinal field to determine where in the list it appears. The defaults use ordinals 1-3, and if the ordinal is not specified, it’s assumed to be 0 (i.e. the loadout will appear before the existing ones).
  • The content field in each loadout is also an object rather than an array, and its entries also support the ordinal field with the same meaning.
  • Kingdoms can specify a custom loadout file to use by specifying a loadouts field in their population JSON pointing at a custom loadouts JSON path or URI.

As an example, here’s the loadouts file from the Miner Profession mod converted to the new format:

  "loadouts": {
    "miner_prof:miner": {
       "alias": "miner_prof:data:loadouts:load_metal",
       "display_name":  "i18n(miner_prof:loadouts.load_metal.display_name)",
       "description": "i18n(miner_prof:loadouts.load_metal.description)",
       "tooltip": "i18n(miner_prof:loadouts.load_metal.tooltip)",
       "splash": "file(images/load_metal/splash.png)",
       "seal": "file(images/load_metal/seal.png)",
       "ordinal": 10,
       "content": {
          "hammer": {
             "ordinal": 1,
             "display_name": "i18n(stonehearth:jobs.blacksmith.blacksmith_description.display_name)",
             "type": "entity",
             "uri": "stonehearth:blacksmith:talisman",
             "icon": "file(images/items/blacksmith_hammer.png)",
             "amount": 1
          "pick": {
             "ordinal": 2,
             "display_name": "i18n(",
             "type": "entity",
             "uri": "miner_prof:miner:talisman",
             "icon": "file(images/items/iron_pick.png)",
             "amount": 1
          "copper": {
             "ordinal": 3,
             "display_name": "i18n(miner_prof:loadouts.load_metal.ore)",
             "type": "entity",
             "uri": "stonehearth:resources:copper:ore",
             "icon": "file(images/items/copper_ore.png)",
             "amount": 12
          "tin": {
             "ordinal": 4,
             "display_name": "i18n(miner_prof:loadouts.load_metal.ore2)",
             "type": "entity",
             "uri": "stonehearth:resources:tin:ore",
             "icon": "file(images/items/tin_ore.png)",
             "amount": 12
          "iron": {
             "ordinal": 5,
             "display_name": "i18n(miner_prof:loadouts.load_metal.ore3)",
             "type": "entity",
             "uri": "stonehearth:resources:iron:ore",
             "icon": "file(images/items/iron_ore.png)",
             "amount": 6

If you know mods that are affected by this change, please direct their authors to this thread. The ones that I know of are @tim1, @Moai, and @Froggy.


The advised setup does not work (as, I suppose, it shouldn’t, since you said it’ll be next Thursday).

However, simply adding an ordinal field also does not work. My loadout is breaking, no matter what I do. The only change currently is the ordinal number, and the expected change is the transformation of the loadouts property from an array to a table, right? So I should do the first, but not the second, for the mod to work until Thursday? But when I do just that, the mod still doesn’t work. What am I missing?

I’m afraid mixing into the loadouts is just broken in the current release. I’ll see if I can get a hotfix out on Monday that would use the new system. If it’s critical for the mod to work in the meantime, removing the loadout temporarily is probably easiest.


It isn’t essential, but you know how you want your users to have the best experience possible. I’ll remove the loadout for now, until there’s a heads up about the fix.

I posted this to Steam so folks who aren’t on the forums but working on mods know what to expect.

1 Like

Actually I got it working for one of my mods. I just added

"mixintypes": { 
   "loadouts" : "override" 

at the top of my loadouts.json and everything just worked fine.

Well, that just overwrites it, which means it wouldn’t work together with other mods that modify loadouts. It’s partial mixintos that are problematic in the current release.


I keep my custom loadouts in the UI sub-mod. So the loadout is only mixed in when the custom kingdom is selected. Still, this may not work for everyone.

The API change is live.


This new format only works for current and newer versions, right?
This means that the stable version will not work if a mod uses this new change?

Correct. This fix should make it to stable sometime in mid July.

1 Like

you heard him boys/girls. JULY

1 Like

unstable is love, unstable is life :wink:

First off, thanks for this usefull guide, it really helped me with updating my mod.

Using the modspace appears to be causing problems. Using


“loadouts”: {
“extraload_shepherd”: {

Works fine, everything is selectable, but using

“loadouts”: {
“extraload:shepherd”: {

Results in this the ui freezing once the loadout is clicked on and nothing being selected (although starting a new game correctly gives the loadout selected when it freezes):

I would suggest maybe spacing the default ordinals further apart (10/20/30? 100/200/300?), to allow mods to squeeze them in-between.

Since lua just knows numbers, floats would probably work as well, but then mods would have to define a number, and having a mod using 1.875 as ordinal to fit between two other mods would seem kinda weird.

I wonder if “extraload:shepherd” is defined as an alias and so using it in this other way also is causing trouble?

Using the modspace appears to be causing problems.

Ugh. Fixed in the next release, but underscores are fine either way.

18 and 1.8 are really no different in this context. ¯\_(ツ)_/¯

My issue with it is less a technical one, and more of a psychological one. It doesn’t really matter, I suppose. Especially not if there are no other instances where a JSON is expecting an integer, but a float could be supplied… which shouldn’t be the case?

I got the habit to add random decimal valuers, from the version that added ordinal for jobs. At the time, jobs with equal ordinals would overwrite each other. Probably not the case anymore, but I still use it.