Patching

In addition to creating new content, you can also use ContentLib to modify existing items, recipes, and schematics, both base-game and those added by other mods.

File Naming Scheme and Location

Patch JSON file names do not need to follow any specific pattern, as they are modifying an existing asset as opposed to creating a new one, but it is advised that you start them with the prefix of the type of asset you are patching. For example, recipe patches should start with Recipe_ and item patches with Desc_

The json file must go in a Patches directory instead of the usual asset folder. For example, an Item patch would go in ItemPatches. See Folder Names for more info on where the file should go.

Syntax

Make sure that you read about the JSON Schema for the asset you are patching before trying to patch it.

The JSON syntax is mostly the same as creating the content, but you must put an additional line at the start of the file to specify what item to overwrite. This is called the 'patch target'. It’s the target asset’s class path, with the _C suffix, prefixed with an extra slash (/). The Finding Assets page covers how to find this path.

For example, the line at the top of the file overriding the Turbofuel recipe must be //Game/FactoryGame/Recipes/AlternateRecipes/Parts/Recipe_Alternate_Turbofuel.Recipe_Alternate_Turbofuel_C

If the path you provide is invalid, a log message will be output.

Just like when creating content, all fields in a patch (except the target) are optional. If you exclude a field, the patched asset will keep its original value from before the patch was applied.

Since comments aren’t normally allowed in JSON files, your editor may mark the line as an error. You can set up VSCode to ignore it by following the directions here.

JSON Schema

The JSON Schema used for a Patch should be that of the asset type it is modifying.

Your editor might complain about the patch target line being a comment, since comments are not normally supported in JSON. This is to be expected You can hide this error by following these steps.

Example Item Patch

Remember that Item Patches need to go in the correct Folder.

Below is an example modification of the base game’s "Caterium Ore" item, which is named OreGold internally. With the power of ContentLib, you can reveal who’s really behind that mask - Gold Ore!

The Big Reveal

Meme

This example replaces the item name and description, but you can modify other fields, too.

//Game/FactoryGame/Resource/RawResources/OreGold/Desc_OreGold.Desc_OreGold_C
{
  "$schema": "https://raw.githubusercontent.com/budak7273/ContentLib_Documentation/main/JsonSchemas/CL_Item.json",
  "Name": "Gold Ore",
  "Description": "Surely not Caterium Ore. Couldn't be!"
}

Example Recipe Patch

Remember that Recipe Patches need to go in the correct Folder.

Crafting Component Recipes

This patch changes the ingredients of the usual Solid Biofuel recipe to have a custom name and custom ingredients/products.

//Game/FactoryGame/Recipes/Constructor/Recipe_Biofuel.Recipe_Biofuel_C
{
  "$schema": "https://raw.githubusercontent.com/budak7273/ContentLib_Documentation/main/JsonSchemas/CL_Recipe.json",
  "Name": "Coal-based BioFuel",
  "Ingredients": [
    {
      "Item": "Desc_Coal",
      "Amount": 1
    }
  ],
  "Products": [
    {
      "Item": "Desc_Biofuel",
      "Amount": 10
    }
  ]
}

Building Recipes

Remember, the syntax for building recipes is the same as normal recipes as described on the Recipe Creation page.

This patch changes the the Blueprint Designer to not cost anything to build. Yes, it’s that short. Remember - you don’t need to repeat any information from the original asset that you aren’t modifying!

//Game/FactoryGame/Recipes/Buildings/Recipe_BlueprintDesigner.Recipe_BlueprintDesigner_C
{
  "$schema": "./../CL_Recipe.json",
  "ClearIngredients": true
}

Example Schematic Patch

Remember that Schematic Patches need to go in the correct Folder.

By default, schematic patches will only append unlocks and costs to what already exists, because this behavior provides the most compatibility with other mods.

The ClearCost, ClearRecipes, and ClearDeps fields may be of use here.

Here’s an example schematic patch that also unlocks the 3 Turbofuel recipes at the same time as regular Fuel while still preserving the existing unlocks.

//Game/FactoryGame/Schematics/Progression/Schematic_5-1.Schematic_5-1_C
{
    "$schema": "https://raw.githubusercontent.com/budak7273/ContentLib_Documentation/main/JsonSchemas/CL_Schematic.json",
    "Recipes": [
        "Recipe_Alternate_Turbofuel",
        "Recipe_Alternate_TurboHeavyFuel",
        "Recipe_Alternate_TurboBlendFuel"
    ]
}

Due to a base-game bug/feature, schematics and items without assigned categories are usually not displayed in menus unless they are explicitly searched for. You can use this behavior to hide schematics from display.

Here’s an example patch that makes it so the "Pretty Good Pioneering" statue does not show up in the AWESOME Shop unless specifically searched for:

//Game/FactoryGame/Schematics/ResourceSink/ResourceSink_StatueSilverPioneer.ResourceSink_StatueSilverPioneer_C
{
    "$schema": "https://raw.githubusercontent.com/budak7273/ContentLib_Documentation/main/JsonSchemas/CL_Schematic.json",
    "ClearSubCategories": true
}

Here’s an example schematic patch from RePan that entirely replaces the recipe unlocks of an existing schematic with another set of recipe unlocks:

//Game/FactoryGame/Schematics/Progression/Schematic_6-1.Schematic_6-1_C
{
    "$schema": "https://raw.githubusercontent.com/budak7273/ContentLib_Documentation/main/JsonSchemas/CL_Schematic.json",
    "ClearRecipes": true,
    "Recipes": [
        "Recipe_GeneratorFuel",
        "Recipe_ConveyorBeltMk4",
        "Recipe_ConveyorLiftMk4",
        "Recipe_LiquidFuel"
    ]
}

Troubleshooting

If your patch isn’t working, don’t fret, ContentLib logs a lot of information about what it’s doing to help you track down the problem. Read more on the Troubleshooting page.

Background Info

Why do patches need the blueprint path?

The reason is simple:

  • This content may not be loaded at this point in the loading sequence.

  • There is no way to "Find" it by name without loading everything.

Therefore, this mod uses a Blueprint Path here to reliably load the Item to be Patched.

Why is the blueprint path not part of the Json itself?

  • The step of turning the raw text into JSON is skipped when the item class fails to load to improve performance.

  • Putting the path inside of the JSON would have forced this mod to do the parsing step earlier.

  • Even if it were part of the JSON, it has no actual value for the Items themselves, just for the mod figuring out what to overwrite. The path resolves to either a useless nullptr or a valid pointer with no further use.