diff --git a/loader/build.gradle b/loader/build.gradle
index 2a52ef74c..6bef80531 100644
--- a/loader/build.gradle
+++ b/loader/build.gradle
@@ -1,5 +1,5 @@
plugins {
- id 'net.neoforged.jarcompatibilitychecker' version '0.1.3'
+ id 'net.neoforged.jarcompatibilitychecker' version '0.1.13'
}
checkJarCompatibility {
diff --git a/loader/src/main/java/net/neoforged/fml/loading/LoadingModList.java b/loader/src/main/java/net/neoforged/fml/loading/LoadingModList.java
index 4df143958..f5b962253 100644
--- a/loader/src/main/java/net/neoforged/fml/loading/LoadingModList.java
+++ b/loader/src/main/java/net/neoforged/fml/loading/LoadingModList.java
@@ -5,6 +5,7 @@
package net.neoforged.fml.loading;
+import com.mojang.logging.LogUtils;
import cpw.mods.modlauncher.api.LambdaExceptionUtils;
import java.net.URL;
import java.nio.file.Files;
@@ -24,16 +25,19 @@
import net.neoforged.fml.loading.mixin.DeferredMixinConfigRegistration;
import net.neoforged.fml.loading.moddiscovery.ModFile;
import net.neoforged.fml.loading.moddiscovery.ModFileInfo;
+import net.neoforged.fml.loading.moddiscovery.ModFileParser;
import net.neoforged.fml.loading.moddiscovery.ModInfo;
import net.neoforged.fml.loading.modscan.BackgroundScanHandler;
import net.neoforged.neoforgespi.language.IModFileInfo;
import net.neoforged.neoforgespi.language.IModInfo;
+import org.slf4j.Logger;
/**
* Master list of all mods in the loading context. This class cannot refer outside the
* loading package
*/
public class LoadingModList {
+ private static final Logger LOGGER = LogUtils.getLogger();
private static LoadingModList INSTANCE;
private final List plugins;
private final List modFiles;
@@ -77,7 +81,13 @@ public void addMixinConfigs() {
.map(ModFileInfo::getFile)
.forEach(file -> {
final String modId = file.getModInfos().get(0).getModId();
- file.getMixinConfigs().forEach(cfg -> DeferredMixinConfigRegistration.addMixinConfig(cfg, modId));
+ for (ModFileParser.MixinConfig potential : file.getMixinConfigs()) {
+ if (potential.requiredMods().stream().allMatch(id -> this.getModFileById(id) != null)) {
+ DeferredMixinConfigRegistration.addMixinConfig(potential.config(), modId);
+ } else {
+ LOGGER.debug("Mixin config {} for mod {} not applied as required mods are missing", potential.config(), modId);
+ }
+ }
});
}
diff --git a/loader/src/main/java/net/neoforged/fml/loading/moddiscovery/ModFile.java b/loader/src/main/java/net/neoforged/fml/loading/moddiscovery/ModFile.java
index 388d0834b..114c1a968 100644
--- a/loader/src/main/java/net/neoforged/fml/loading/moddiscovery/ModFile.java
+++ b/loader/src/main/java/net/neoforged/fml/loading/moddiscovery/ModFile.java
@@ -56,7 +56,7 @@ public class ModFile implements IModFile {
private ModFileScanData fileModFileScanData;
private volatile CompletableFuture futureScanResult;
private List coreMods;
- private List mixinConfigs;
+ private List mixinConfigs;
private List accessTransformers;
public static final Attributes.Name TYPE = new Attributes.Name("FMLModType");
@@ -135,7 +135,7 @@ public List getCoreMods() {
return coreMods;
}
- public List getMixinConfigs() {
+ public List getMixinConfigs() {
return mixinConfigs;
}
diff --git a/loader/src/main/java/net/neoforged/fml/loading/moddiscovery/ModFileParser.java b/loader/src/main/java/net/neoforged/fml/loading/moddiscovery/ModFileParser.java
index 2bfb74d1f..96e41f4b5 100644
--- a/loader/src/main/java/net/neoforged/fml/loading/moddiscovery/ModFileParser.java
+++ b/loader/src/main/java/net/neoforged/fml/loading/moddiscovery/ModFileParser.java
@@ -16,12 +16,14 @@
import java.lang.reflect.Type;
import java.nio.file.Files;
import java.nio.file.Path;
+import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import net.neoforged.fml.loading.LogMarkers;
import net.neoforged.fml.loading.moddiscovery.readers.JarModsDotTomlModFileReader;
+import net.neoforged.neoforgespi.language.IConfigurable;
import net.neoforged.neoforgespi.language.IModFileInfo;
import net.neoforged.neoforgespi.locating.IModFile;
import net.neoforged.neoforgespi.locating.InvalidModFileException;
@@ -85,17 +87,28 @@ protected static List getCoreMods(final ModFile modFile) {
.toList();
}
- protected static List getMixinConfigs(IModFileInfo modFileInfo) {
+ /**
+ * Represents a potential mixin configuration.
+ *
+ * @param config The name of the mixin configuration.
+ * @param requiredMods The mod ids that are required for this mixin configuration to be loaded. If empty, will be loaded regardless.
+ */
+ public record MixinConfig(String config, List requiredMods) {}
+
+ protected static List getMixinConfigs(IModFileInfo modFileInfo) {
try {
var config = modFileInfo.getConfig();
var mixinsEntries = config.getConfigList("mixins");
- return mixinsEntries
- .stream()
- .map(entry -> entry
- .getConfigElement("config")
- .orElseThrow(
- () -> new InvalidModFileException("Missing \"config\" in [[mixins]] entry", modFileInfo)))
- .toList();
+
+ var potentialMixins = new ArrayList();
+ for (IConfigurable mixinsEntry : mixinsEntries) {
+ var name = mixinsEntry.getConfigElement("config")
+ .orElseThrow(() -> new InvalidModFileException("Missing \"config\" in [[mixins]] entry", modFileInfo));
+ var requiredModIds = mixinsEntry.>getConfigElement("requiredMods").orElse(List.of());
+ potentialMixins.add(new MixinConfig(name, requiredModIds));
+ }
+
+ return potentialMixins;
} catch (Exception exception) {
LOGGER.error("Failed to load mixin configs from mod file", exception);
return List.of();