Resource Conditions 26.1.2
A guide to allowing your mod's data to load conditionally.
When designing integrations with other mods, a common need is a way to define when your mod's resources should be loaded. For this reason, Fabric API offers Resource Conditions.
By default, this API can be used with recipes, advancements, loot tables, predicates, and item modifiers.
Resource conditions can either be added via data generation or when writing JSON by hand. For more information about how to add resource conditions via data generation, see the Data Generation docs.
Load conditions are added to the root of a JSON file.
A recipe with a condition that makes it only load when a tag is populated.
json
{
"fabric:load_conditions": [
{
"condition": "fabric:tags_populated",
"registry": "minecraft:item",
"values": [
"minecraft:dirt"
]
}
],
"type": "minecraft:crafting_shapeless",
"category": "building",
"ingredients": [
"#minecraft:sand"
],
"result": {
"id": "minecraft:sand"
}
}1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
Built-in Conditions
Fabric API provides nine built-in conditions for your mod to use.
Operators
These are the standard boolean operators.
True
Always succeeds:
json
{
"fabric:load_conditions": [
{
"condition": "fabric:true"
}
]
}1
2
3
4
5
6
7
2
3
4
5
6
7
Not
Inverts the load condition specified in value. For example, the following will fail:
json
{
"fabric:load_conditions": [
{
"condition": "fabric:not",
"value": {
"condition": "fabric:true"
}
}
]
}1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
Or
Succeeds if at least one of the conditions in values succeeds. For example, the following will succeed:
json
{
"fabric:load_conditions": [
{
"condition": "fabric:or",
"values": [
{
"condition": "fabric:true"
},
{
"condition": "fabric:not",
"value": {
"condition": "fabric:true"
}
}
]
}
]
}1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
And
Succeeds if every condition in values succeeds. For example, the following will fail:
json
{
"fabric:load_conditions": [
{
"condition": "fabric:and",
"values": [
{
"condition": "fabric:true"
},
{
"condition": "fabric:not",
"value": {
"condition": "fabric:true"
}
}
]
}
]
}1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
All Mods Loaded
Succeeds if all mods in values are loaded. For example, the following succeeds only if both example-mod and another-mod are loaded:
json
{
"fabric:load_conditions": [
{
"condition": "fabric:all_mods_loaded",
"values": [
"example-mod",
"another-mod"
]
}
]
}1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11
Any Mods Loaded
Succeeds if at least one of the mods in values is loaded. For example, the following will succeed if either example-mod, or another-mod, or both, are loaded:
json
{
"fabric:load_conditions": [
{
"condition": "fabric:any_mods_loaded",
"values": [
"example-mod",
"another-mod"
]
}
]
}1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11
Tags Populated
Succeeds if the specified registry contains all tags in values. For example, the following will succeed if the example-mod:smelly_items item tag is loaded:
json
{
"fabric:load_conditions": [
{
"condition": "fabric:tags_populated",
"registry": "minecraft:item",
"values": [
"example-mod:smelly_items"
]
}
]
}1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11
Features Enabled
Succeeds if all feature flags in features are enabled. For example, the following will succeed if both minecraft:vanilla and minecraft:redstone_experiments are enabled:
json
{
"fabric:load_conditions": [
{
"condition": "fabric:features_enabled",
"features": [
"minecraft:vanilla",
"minecraft:minecart_improvements"
]
}
]
}1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11
Registry Contains
Succeeds if the registry contains all of the identifiers in values. For example, the following will succeed if minecraft:cobblestone exists in the registry:
json
{
"fabric:load_conditions": [
{
"condition": "fabric:registry_contains",
"registry": "minecraft:block",
"values": [
"minecraft:cobblestone"
]
}
]
}1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11
Custom Conditions
PREREQUISITES
You must first understand how to create a codec before setting a custom resource condition.
Fabric API also provides the flexibility of creating your own resource conditions.
To demonstrate this, we'll create a condition that checks the current date. This could be used for special behavior on holidays like Halloween or April Fools.
Preparing Your Condition
For simplicity, we'll be creating a helper method that instantiates your resource condition from a name and a MapCodec. You should put this method in a class called ModResourceConditions (or whatever you want to name it).
TIP
Fabric does the same with its built-in conditions; you can refer to the DefaultResourceConditionTypes class to see this in action.
java
public class ModResourceConditions {
private static <T extends ResourceCondition> ResourceConditionType<T> createResourceConditionType(String name, MapCodec<T> codec) {
return ResourceConditionType.create(Identifier.fromNamespaceAndPath(ExampleMod.MOD_ID, name), codec);
}
}1
2
3
4
5
2
3
4
5
Creating Your Condition
A resource condition consists of three parts:
- A constructor that accepts values.
- A
MapCodecto serialize those values. - A
testmethod that uses the values to determine whether the condition should pass.
We'll create a new class for the resource condition, named DateMatchesResourceCondition. First, create a new record that accepts an int for the month, and an int for the day:
java
public record DateMatchesResourceCondition(int month, int day) implements ResourceCondition {
}1
2
2
Next, add a MapCodec that reflects what the constructor accepts:
java
public static final MapCodec<DateMatchesResourceCondition> CODEC = RecordCodecBuilder.<DateMatchesResourceCondition>mapCodec(instance -> instance.group(
ExtraCodecs.POSITIVE_INT.fieldOf("month").forGetter(DateMatchesResourceCondition::month),
ExtraCodecs.POSITIVE_INT.fieldOf("day").forGetter(DateMatchesResourceCondition::day)
).apply(instance, DateMatchesResourceCondition::new)).validate(DateMatchesResourceCondition::validate);1
2
3
4
2
3
4
What is validate?
This codec uses the .validate method to ensure the provided date can exist, using the logic in a helper method also called validate:
java
private static DataResult<DateMatchesResourceCondition> validate(DateMatchesResourceCondition o) {
try {
MonthDay.of(o.month(), o.day());
} catch (DateTimeException e) {
return DataResult.error(e::getMessage);
}
return DataResult.success(o);
}1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
This is only relevant in this exact example.
Next, we'll add a test method that checks the current date. This example is based on logic from vanilla itself, in SpecialDates.
java
@Override
public boolean test(RegistryOps.@Nullable RegistryInfoLookup registryInfo) {
var monthDay = MonthDay.of(this.month, this.day);
return SpecialDates.dayNow().equals(monthDay);
}1
2
3
4
5
2
3
4
5
Registering Your Condition
Back in ModResourceConditions, we can now register our resource condition:
java
public static final ResourceConditionType<DateMatchesResourceCondition> DATE_MATCHES =
createResourceConditionType("date_matches", DateMatchesResourceCondition.CODEC);
public static void register() {
ResourceConditions.register(DATE_MATCHES);
}1
2
3
4
5
6
2
3
4
5
6
This condition type can then be referenced from DateMatchesResourceCondition as well:
java
@Override
public ResourceConditionType<?> getType() {
return ModResourceConditions.DATE_MATCHES;
}1
2
3
4
2
3
4
Be sure to call ModResourceConditions.register in your mod's initializer:
java
public class ExampleModResourceConditions implements ModInitializer {
@Override
public void onInitialize() {
ModResourceConditions.register();
}
}1
2
3
4
5
6
2
3
4
5
6
Using Your Condition
Now, we have a condition that succeeds if the system date matches the date provided in the resource condition. For example, this condition will only succeed on April Fools:
json
{
"fabric:load_conditions": [
{
"condition": "example-mod:date_matches",
"day": 1,
"month": 4
}
]
}1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9

