Content Default Object Modification
|
You can find a JSON Schema for CDOs here. |
You can also use ContentLib to perform (Class Default Object) CDO edits, to a limited degree, by overwriting property values.
To learn more about what a CDO is, see this Unreal Engine documentation page.
This is an advanced feature that can modify most fields on any asset, as long as you know where the asset is, what field to look for, and understand the structure of the data type you are modifying.
In order to find the names of fields, you probably will need to either have a set up modding project, and/or look at the C++ headers shipped with the game. Experimentation will be required to find out what fields do what.
You can attempt to hot reload CDOs via the button on the Mod Configuration screen,
or the /CLCDOReload chat command.
Hot reloading is a WIP feature, and could work, have no effect,
or possibly even crash you depending on the fields you are modifying.
There are no restrictions on the names for CDO JSON files.
This feature becomes even more powerful when paired with a mod of your own. For example, you can use CDO edits to change the parent class of other Materials to one you packaged with your mod, changing the appearance of anything using that material.
You can see the field types supported by ContentLib CDOs
by looking at the UCLCDOBPFLib::EditCDO implementation
here.
It attempts to convert what you’ve entered as a string into structs and other types as needed,
but it is far from perfect.
|
Remember that CDOs need to go in the correct Folder. |
Disclaimer
It’s possible to do a lot of cool things with this feature, but also cause crashes. On the flip side, the modifications could have absolutely no effect whatsoever. ContentLib simply provides the tools to allow modifying the CDO - there is no guarantee that the asset you are modifying will still work correctly after the fact.
For example, it is possible to use a CDO
to change the mManufacturingSpeed and mExtractCycleTime properties of miners.
Content Inspector will confirm that the values have been changed,
but the miner’s behavior in-game will not be affected.
This is not because the CDO edit has failed,
but because something about the miner’s implementation is causing it to not use the values in a way we expected.
Other modders have found out through experimentation and research with a decompiler
that miner behavior can be changed via
hooking,
an advanced technique that requires a regular mod to use.
In this specific case, the same outcome (increased miner speed)
can be achieved by using a CDO to modify the mCollectSpeedMultiplier of the resource item instead.
JSON Examples
Rename an Item
This renames Caterium Ingots to Gold Ingots. You should use Item Patches instead of CDOs for this in practice. This is just an example with a field you’re likely already familiar with.
This is an example of a CDO edit that works with hot reloading.

{
"$schema": "https://raw.githubusercontent.com/budak7273/ContentLib_Documentation/main/JsonSchemas/CL_CDO.json",
"Class": "/Game/FactoryGame/Resource/Parts/GoldIngot/Desc_GoldIngot.Desc_GoldIngot_C",
"Edits": [
{
"Property": "mDisplayName",
"Value": "Gold Ingot"
}
]
}
Adjust Hover Pack Power Consumption
Created by Izeau.
{
"$schema": "https://raw.githubusercontent.com/budak7273/ContentLib_Documentation/main/JsonSchemas/CL_CDO.json",
"Class": "/Game/FactoryGame/Equipment/HoverPack/Equip_HoverPack.Equip_HoverPack_C",
"Edits": [
{
"Property": "mPowerConsumption",
"Value": "10.0"
}
]
}
Replace Chainsaw Fuel Type
Created by leatherneck6017. Note that the base game implements this field is a single class field, so trying to add multiple classes via an array will fail.
{
"$schema": "https://raw.githubusercontent.com/budak7273/ContentLib_Documentation/main/JsonSchemas/CL_CDO.json",
"Class": "/SuperChainsaw/Equipment/SuperChainsaw/Equip_SuperChainsaw.Equip_SuperChainsaw_C",
"Edits": [
{
"Property": "mFuelClass",
"Value": "/Game/FactoryGame/Resource/Parts/BioFuel/Desc_Biofuel.Desc_Biofuel_C"
}
]
}
Data Asset Modification
This CDO Edit by McGalleon is used by Satisfactory Plus to edit a Data Asset that controls Refined Power boiler behaviors.
{
"Class": "/SatisfactoryPlus/AssetDatas/RRD/RP/Boiler/PDA_SFP_Boiler_Mk1_Water.PDA_SFP_Boiler_Mk1_Water",
"Edits": [
{
"Property": "mInput",
"Value": {
"ItemClass": "/Game/FactoryGame/Resource/RawResources/Water/Desc_Water.Desc_Water_C",
"amount": 1500
}
},
{
"Property": "mOutput",
"Value": {
"ItemClass": "/KLib/Assets/Ressources/Raw/Gas/Desc_Gas_Steam_Hot.Desc_Gas_Steam_Hot_C",
"amount": 3000
}
},
{
"Property": "mDuration",
"Value": 6
},
{
"Property": "mPriority",
"Value": 1
}
]
}
Drone Port Fuels
This demonstrates the CDO feature’s ability to work with arbitrary structs, to a degree.
Note that using a ContentLib CDO here overwrites the entire mFuelTypes array,
which is not desirable for compatibility with other mods.
Unfortunately, ContentLib CDOs do not currently offer a way to append to arrays instead of replacing them.
From the FlexFuel Drones mod, developed in this conversation on the modding discord.
{
"$schema": "https://raw.githubusercontent.com/budak7273/ContentLib_Documentation/main/JsonSchemas/CL_CDO.json",
"Class": "/Game/FactoryGame/Buildable/Factory/DroneStation/BP_DroneTransport.BP_DroneTransport_C",
"Edits": [
{
"Property": "mFuelTypes",
"Value": [
{
"Item": "/Game/FactoryGame/Resource/Parts/Battery/Desc_Battery.Desc_Battery_C",
"ThrusterColor": {
"R": 0,
"G": 128,
"B": 255,
"A": 255
},
"ThrusterEndColor": {
"R": 255,
"G": 200,
"B": 64,
"A": 255
},
"FlightSpeed": 1500.0,
"TravelSpeed": 7500.0
},
{
"Item": "/Game/FactoryGame/Resource/Parts/BioFuel/Desc_PackagedBiofuel.Desc_PackagedBiofuel_C",
"ThrusterColor": {
"R": 59,
"G": 83,
"B": 44,
"A": 255
},
"ThrusterEndColor": {
"R": 85,
"G": 189,
"B": 44,
"A": 255
},
"FlightSpeed": 1500.0,
"TravelSpeed": 7500.0
},
{
"Item": "/Game/FactoryGame/Resource/Parts/Fuel/Desc_Fuel.Desc_Fuel_C",
"ThrusterColor": {
"R": 255,
"G": 149,
"B": 0,
"A": 255
},
"ThrusterEndColor": {
"R": 255,
"G": 212,
"B": 125,
"A": 255
},
"FlightSpeed": 1000.0,
"TravelSpeed": 5000.0
},
{
"Item": "/Game/FactoryGame/Resource/Parts/Turbofuel/Desc_TurboFuel.Desc_TurboFuel_C",
"ThrusterColor": {
"R": 255,
"G": 32,
"B": 0,
"A": 255
},
"ThrusterEndColor": {
"R": 255,
"G": 100,
"B": 100,
"A": 255
},
"FlightSpeed": 1000.0,
"TravelSpeed": 6000.0
},
{
"Item": "/Game/FactoryGame/Resource/Parts/RocketFuel/Desc_PackagedRocketFuel.Desc_PackagedRocketFuel_C",
"ThrusterColor": {
"R": 255,
"G": 0,
"B": 0,
"A": 255
},
"ThrusterEndColor": {
"R": 255,
"G": 240,
"B": 0,
"A": 255
},
"FlightSpeed": 1000.0,
"TravelSpeed": 7500.0
},
{
"Item": "/Game/FactoryGame/Resource/Parts/IonizedFuel/Desc_PackagedIonizedFuel.Desc_PackagedIonizedFuel_C",
"ThrusterColor": {
"R": 255,
"G": 102,
"B": 0,
"A": 255
},
"ThrusterEndColor": {
"R": 255,
"G": 182,
"B": 0,
"A": 255
},
"FlightSpeed": 1000.0,
"TravelSpeed": 10000.0
},
{
"Item": "/Game/FactoryGame/Resource/Parts/NuclearFuelRod/Desc_NuclearFuelRod.Desc_NuclearFuelRod_C",
"ThrusterColor": {
"R": 0,
"G": 255,
"B": 0,
"A": 255
},
"ThrusterEndColor": {
"R": 192,
"G": 255,
"B": 64,
"A": 255
},
"FlightSpeed": 1000.0,
"TravelSpeed": 9000.0
},
{
"Item": "/Game/FactoryGame/Resource/Parts/PlutoniumFuelRods/Desc_PlutoniumFuelRod.Desc_PlutoniumFuelRod_C",
"ThrusterColor": {
"R": 248,
"G": 255,
"B": 255,
"A": 255
},
"ThrusterEndColor": {
"R": 95,
"G": 151,
"B": 255,
"A": 255
},
"FlightSpeed": 1000.0,
"TravelSpeed": 10000.0
}
]
}
]
}
Curve Point Overwriting
The points on curve assets can be overwritten with CDOs. Look at a curve asset with Content Inspector to learn more about the structure of the data. This example from BlueBeka makes Portals consume fewer Singularity Cells per minute (0.25 instead of 2) Unfortunately the CDO edit feature’s implementation does not allow modifying specific keys or appending new keys - you must replace the entire array. For this particular curve, that doesn’t matter, as the curve only has one key.
{
"$schema": "https://raw.githubusercontent.com/budak7273/ContentLib_Documentation/main/JsonSchemas/CL_CDO.json",
"Class": "/Game/FactoryGame/Buildable/Factory/Portal/Curves/Curve_PortalFuelConsumption.Curve_PortalFuelConsumption",
"Edits": [
{
"Property": "FloatCurve",
"Value": {
"Keys": [
{
"Value": 0.25
}
]
}
}
]
}
Recipe Ingredients Quantity Change
You should use Recipe Patches instead of CDOs for this; this is just a proof of concept.
{
"$schema": "https://raw.githubusercontent.com/budak7273/ContentLib_Documentation/main/JsonSchemas/CL_CDO.json",
"Class": "/Game/FactoryGame/Recipes/Blender/Recipe_FusedModularFrame.Recipe_FusedModularFrame_C",
"Edits": [
{
"Property": "mIngredients",
"Value": [
{
"ItemClass": "/Game/FactoryGame/Resource/Parts/ModularFrameHeavy/Desc_ModularFrameHeavy.Desc_ModularFrameHeavy_C",
"Amount": 643
},
{
"ItemClass": "/Game/FactoryGame/Resource/Parts/AluminumCasing/Desc_AluminumCasing.Desc_AluminumCasing_C",
"Amount": 245
},
{
"ItemClass": "/Game/FactoryGame/Resource/RawResources/NitrogenGas/Desc_NitrogenGas.Desc_NitrogenGas_C",
"Amount": 123
}
]
}
]
}
Change Material Instance Parent Class
Unreal material instances store their parent Material as a field. This field can be changed with CDO edits, although it is rarely a good idea to do so. This point of this example is just to demonstrate editing an arbitrary field on an asset.
{
"$schema": "https://raw.githubusercontent.com/budak7273/ContentLib_Documentation/main/JsonSchemas/CL_CDO.json",
"Class": "/Game/FactoryGame/-Shared/Material/MI_Factory_Base_01.MI_Factory_Base_01",
"Edits": [
{
"Property": "Parent",
"Value": "/AdaptingGenerators/Assets/MM_FactoryCopy.MM_FactoryCopy"
}
]
}