Conditionally-Loaded Data
There are times when modders may want to include data-driven objects using information from another mod without having to explicitly make that mod a dependency. Other cases may be to swap out certain objects with other modded entries when they are present. This can be done through the conditional subsystem.
Implementations
Conditions are loaded from a top-level neoforge:conditions
array of objects that represent the conditions to check. If all conditions specified are met, then the rest of the JSON will be loaded, or neoforge:value
if the value is not an object; otherwise, it will be discarded.
{
"neoforge:conditions": [
// Condition 1
{
},
// Condition 2
{
}
],
// The rest of the object
// ...
}
All JSON files support conditions; however, only a few data providers have been directly patched for data generation. Currently, the following data generators support conditions:
- Recipes via
RecipeOutput#withConditions
- Implementations of
JsonCodecProvider
viaconditionally
(e.g.SpriteSourceProvider
) - Data Maps via
DataMapProvider.Builder#add
Loot tables that do not meet their loading conditions will not be ignored, but rather replaced with an empty loot table.
{
"neoforge:conditions": [
{
"type": "neoforge:mod_loaded",
"modid": "examplemod"
}
],
"type": "minecraft:crafting_shaped",
"category": "redstone",
"key": {
"#": {
"item": "examplemod:example_planks"
}
},
"pattern": [
"##",
"##",
"##"
],
"result": {
"count": 3,
"item": "mymod:compat_door"
}
}
Conditions
True and False
Boolean conditions consist of no data and return the expected value of the condition. They are represented by neoforge:true
and neoforge:false
.
// For some condition
{
// Will always return true (or false for 'neoforge:false')
"type": "neoforge:true"
}
Not, And, and Or
Boolean operator conditions consist of the condition(s) being operated upon and apply the following logic. They are represented by neoforge:not
, neoforge:and
, and neoforge:or
.
// For some condition
{
// Inverts the result of the stored condition
"type": "neoforge:not",
"value": {
// A condition
}
}
// For some condition
{
// ANDs the stored conditions together (or ORs for 'neoforge:or')
"type": "neoforge:and",
"values": [
{
// First condition
},
{
// Second condition to be ANDed (or ORed for 'neoforge:or')
}
]
}
Mod Loaded
ModLoadedCondition
returns true whenever the specified mod with the given id is loaded in the current application. This is represented by neoforge:mod_loaded
.
// For some condition
{
"type": "neoforge:mod_loaded",
// Returns true if 'examplemod' is loaded
"modid": "examplemod"
}
Item Exists
ItemExistsCondition
returns true whenever the given item has been registered in the current application. This is represented by neoforge:item_exists
.
// For some condition
{
"type": "neoforge:item_exists",
// Returns true if 'examplemod:example_item' has been registered
"item": "examplemod:example_item"
}
Tag Empty
TagEmptyCondition
returns true whenever the given item tag has no items within it. This is represented by neoforge:tag_empty
.
// For some condition
{
"type": "neoforge:tag_empty",
// Returns true if 'examplemod:example_tag' is an item tag with no entries
"tag": "examplemod:example_tag"
}
Creating Custom Conditions
Custom conditions can be created by implementing ICondition
and creating a map codec for it.
ICondition
A condition needs to implement the ICondition#test(IContext)
method. This method will return true
if the object should be loaded, and false
otherwise.
Every #test
has access to some IContext
representing the state of the game. Currently, this only allows obtaining tags from a registry.
Some objects may be loaded earlier than tags. In those cases, the condition context will be IContext.EMPTY
.
The ICondition#codec
method should return the codec used to encode and decode the condition. This codec must be registered to the NeoForgeRegistries#CONDITION_SERIALIZERS
registry. The name the codec is registered under will be the name used to refer to that condition in the type
field.