Mixintypes

How to remove content using mixintypes

Now we know how to add/modify things using mixintos and overrides. But what happens if we don't want to add content, but instead want to remove it? Do we need to override the entire file?

What if we wanted to remove some campaigns, crafting recipes or hearthling's names? We can use overrides to do that, but as we explained, overrides are bad for mod compatibility.

Fortunately, the modding API has a system that allows us to override only certain values from within a JSON file. It is a way for modders to specify that a certain part of a mixinto will override an entire node. This allows us to replace arrays instead of adding to them.

Overriding JSON nodes in mixintos with "mixintypes"

Normally, a mixinto can only add to an existing array, which means replacing a value in an array is difficult. To replace the entire array, you can either specify the JSON as an override in the manifest, which will blow away the original file (potentially game breaking), or create a special "mixintypes" field in your mixinto at the same level in the JSON as the field you want to modify, to ONLY replace that single node in the original file.

Mixintype "remove"

For removing a node from the JSON, the syntax is like this:

  "mixintypes": { "name_of_node" : "remove" }

For example, this is how the Rayya's Children weaver's recipe list removes the Ascendancy's winter worker outfit from the list of available recipes (also replaces the recipe for the worker_outfit_2 with its own recipe, and adds an extra recipe for another outfit):

  {
     "mixins": "/stonehearth/jobs/weaver/recipes/recipes.json",
     "craftable_recipes": {
        "clothing_armor": {
           "recipes": {
              "worker_outfit_2": {
                 "recipe": "file(worker_outfit_2_recipe.json)"
              },
              "mixintypes": {
                 "worker_outfit_winter": "remove"
              },
              "outfit_worker_goldthread": {
                 "recipe": "file(outfit_worker_goldthread_recipe.json)"
              }
           }
        }
     }
  }

The "mixintypes" keyword is at the same level than the key we want to remove. We tell which node(s) we want to modify within a mixintype, and then indicate that we want to remove it. This can be done in a mixinto or in a new file referenced elsewhere.

The example above imports all the recipes from the Ascendancy weaver via "mixins" and then modifies the ones that don't match with Rayya's Children. It's a file referenced in other files that are eventually added via a mixinto, but it's not a mixinto in itself. It just borrows data from the stonehearth mod so that it doesn't have to specify all the recipes manually.

We can't use "mixintypes" : "remove" for array values, since arrays can't contain key-value pairs.

Mixintype "override"

You can use the mixintype "override" to replace existing arrays instead of appending to them. This is very important for translation mods that used to override population JSON files for translated names.

With mixintype "override" you can now provide your translation's population names as a mixinto in your mod's manifest instead of overriding the entire population.json file.

Within the target file, declare the node(s) you want to override, and then provide your replacement version.
In the example below, your manifest would look something like:

  {
     "info" : {
        "name" : "My Translation",
        "namespace" : "my_namespace"
        "version" : 3
     },
     "mixintos" : {
        "stonehearth/locales/supported_languages.json" : "file(added_languages.json)",
        "stonehearth/services/server/population/data/ascendancy_population.json": "file(translations/stonehearth/population/ascendancy_population.json)",
        "stonehearth/services/server/population/data/goblin_population.json": "file(translations/stonehearth/population/goblin_population.json)",
        "stonehearth/services/server/population/data/undead_population.json": "file(translations/stonehearth/population/undead_population.json)",
        "rayyas_children/data/rayyas_children_population.json": "file(translations/rayyas_children/population/rayyas_children_population.json)"
     },
     "overrides" : {
        "stonehearth/locales/en­XA.json": "file(translations/stonehearth/en­XA.json)",
        "rayyas_children/locales/en­XA.json": "file(translations/rayyas_children/rayyas_children.json)"
     }
  }

(Remember that use of overrides to add unexisting files to the stonehearth folders? This is another example.) And then the mixinto files for the populations would look like this (shortened example):

  {
     "roles" : {
        "default" : {
           "male" : {
              "mixintypes": {
                 "given_names": "override"
              },
              "given_names" : [
                 "MaleName1",
                 "MaleName2",
                 "MaleName3"
              ]
           },
           "female" : {
              "mixintypes": {
                 "given_names": "override"
              },
              "given_names" : [
                 "FemaleName1",
                 "FemaleName2",
                 "FemaleName3"
              ]
           },
           "mixintypes": {
              "surnames": "override"
           },
           "surnames" : [
              "Surname1",
              "Surname2"
           ]
        }
     },
     "town_pieces" : {
        "mixintypes": {
           "optional_prefix": "override"
        },
        "optional_prefix" : [
           "Prefix1",
           "Prefix2",
           "Prefix3"
        ]
     }
  }

As you can see, we define a "mixintypes" node in the same way than the mixintypes for removing content, that is, at the level of the node we want to override. Then, we specify the node (for example "given_names") plus a colon and "override". Only after that we can declare again the node and include the values that we want it to have.

This is the way to override arrays without having to override the entire file, which could cause conflicts on other nodes from the JSON file if the game updates.

You can also remove specific values from the array with this method, by overriding the node and then declaring only the values you want to keep.

Removing content from Lua files

Unfortunately, the systems explained above don't work for Lua files, so if you want to remove content from them, you'll have to override the entire file, meaning that it would not be compatible with other mods that rely on that file.