From b74c1eb3d70f0db7765e065d244f57554e96a27b Mon Sep 17 00:00:00 2001 From: Jonathing Date: Mon, 6 Apr 2026 17:49:58 -0400 Subject: [PATCH 1/4] Display a warning if Renamer is not present using legacy Forge versions --- .../gradle/internal/ForgeGradleProblems.java | 22 ++++++++++ .../internal/MavenizerInstanceImpl.java | 42 ++++++++++++++++++- 2 files changed, 63 insertions(+), 1 deletion(-) diff --git a/src/main/java/net/minecraftforge/gradle/internal/ForgeGradleProblems.java b/src/main/java/net/minecraftforge/gradle/internal/ForgeGradleProblems.java index 4be9072e9..f8d3035ed 100644 --- a/src/main/java/net/minecraftforge/gradle/internal/ForgeGradleProblems.java +++ b/src/main/java/net/minecraftforge/gradle/internal/ForgeGradleProblems.java @@ -96,6 +96,28 @@ void reportMissingMinecraftDependency() { ); } + void reportMissingRenamerPluginForOldVersion(Dependency dependency) { + if (this.testFalse("net.minecraftforge.gradle.warnings.minecraft.legacy.renamer.missing")) return; + + LOGGER.warn("WARNING: Renamer Gradle not present with legacy Forge version. See Problems report for details."); + this.report("legacy-missing-renamer", "Missing Renamer Gradle for legacy Minecraft dependency", spec -> spec + .details(""" + A legacy Forge dependency was declared, but Renamer Gradle has not been applied to the project! + While the workspace will continue to function, this may cause problems with resultant artifacts not being renamed to obfuscated mappings. + Legacy Forge versions use obfuscated mappings at runtime, so this is a requirement if you are publishing this project as a mod that uses Minecraft names. + Dependency: '%s'""" + .formatted(Util.toString(dependency))) + .severity(Severity.WARNING) + .solution("Apply the 'net.minecraftforge.renamer' plugin.") + .solution("Disable this warning in 'gradle.properties' if you are an advanced user: `net.minecraftforge.gradle.warnings.minecraft.legacy.renamer.missing=false`") + .solution("Consider building your project for a newer version of Forge targeting Minecraft 1.20.5 or newer.") + .solution(HELP_MESSAGE)); + } + + void reportMissingRenamerCheckFailed(Dependency dependency, Throwable e) { + LOGG + } + RuntimeException invalidMinecraftDependencyType(Dependency dependency) { return this.throwing(new IllegalArgumentException("Minecraft dependency is not a module dependency"), "unsupported-minecraft-dependency-type", "Non-module dependency used as Minecraft dependency", spec -> spec .details(""" diff --git a/src/main/java/net/minecraftforge/gradle/internal/MavenizerInstanceImpl.java b/src/main/java/net/minecraftforge/gradle/internal/MavenizerInstanceImpl.java index 3b00abcda..bfdee20d4 100644 --- a/src/main/java/net/minecraftforge/gradle/internal/MavenizerInstanceImpl.java +++ b/src/main/java/net/minecraftforge/gradle/internal/MavenizerInstanceImpl.java @@ -20,6 +20,7 @@ class MavenizerInstanceImpl implements MavenizerInstance { private static final Logger LOGGER = Logging.getLogger(MavenizerInstanceImpl.class); private final MinecraftExtensionImpl.ForProjectImpl extension; + private final ForgeGradleProblems problems; private final Provider valueSource; private final ExternalModuleDependency dependency; private final File jsonFile; @@ -34,6 +35,7 @@ class MavenizerInstanceImpl implements MavenizerInstance { File jsonFile ) { this.extension = extension; + this.problems = this.extension.getObjects().newInstance(ForgeGradleProblems.class); this.dependency = dependency; this.valueSource = valueSource; this.jsonFile = jsonFile; @@ -45,12 +47,50 @@ class MavenizerInstanceImpl implements MavenizerInstance { private Map invoke() { if (this.map == null) { valueSource.get(); // Execute Mavenizer, probably called before, but just be sure. - this.map = (Map) new JsonSlurper().parse(this.jsonFile, "UTF-8"); + this.map = validate((Map) new JsonSlurper().parse(this.jsonFile, "UTF-8")); //this.map.forEach((k, v) -> this.extension.getProject().getLogger().lifecycle(k + " => " + v)); } return this.map; } + private Map validate(Map map) { + // this entire error check is gated behind a gradle property. if it's set to false, stop immediately. + // also don't bother checking if we aren't using Forge, which is net.minecraftforge:forge/fmlonly + // this code is kind of ugly but I don't know how to make it any cleaner without the nesting. + if (!problems.testFalse("net.minecraftforge.gradle.warnings.minecraft.legacy.renamer.missing") + && "net.minecraftforge".equals(dependency.getGroup()) + && ("forge".equals(dependency.getName()) || "fmlonly".equals(dependency.getName()))) { + var minecraftVersion = map.get("mc.version"); + if (minecraftVersion != null && !"UNKNOWN".equals(minecraftVersion)) { + boolean legacy = false; + try { + if (minecraftVersion.indexOf('w') > 0) { + var split = minecraftVersion.split("[w|a-z]"); + int int1 = Integer.parseInt(split[0]); + int int2 = Integer.parseInt(split[1]); + legacy = int1 <= 24 && int2 <= 13; // 24w13a was the last snapshot before 1.20.5 + } else { + var split = minecraftVersion.split("[.|-]"); + int int1 = Integer.parseInt(split[0]); + int int2 = Integer.parseInt(split[1]); + int int3 = split.length > 2 ? Integer.parseInt(split[2]) : 0; + legacy = int1 <= 1 && int2 <= 20 && int3 < 5; // version < 1.20.5 == legacy + } + } catch (Exception e) { + // there are a number of things that could go wrong here. + // but it should never cause a build failure. stop immediately and report problem. + problems.reportMissingRenamerCheckFailed(dependency, e); + } + + if (legacy && !extension.getProject().getPluginManager().hasPlugin("net.minecraftforge.renamer")) { + problems.reportMissingRenamerPluginForOldVersion(dependency); + } + } + } + + return map; + } + private Provider get(String key) { return this.invoke.getting(key) .orElse(this.extension.getProviders().provider(() -> { From 5d6c5f6be6bd1308940b0ef1ac518012533ca074 Mon Sep 17 00:00:00 2001 From: Jonathing Date: Mon, 6 Apr 2026 17:59:57 -0400 Subject: [PATCH 2/4] Check 26.1 for vanilla --- .../gradle/internal/MavenizerInstanceImpl.java | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/main/java/net/minecraftforge/gradle/internal/MavenizerInstanceImpl.java b/src/main/java/net/minecraftforge/gradle/internal/MavenizerInstanceImpl.java index bfdee20d4..76dba4440 100644 --- a/src/main/java/net/minecraftforge/gradle/internal/MavenizerInstanceImpl.java +++ b/src/main/java/net/minecraftforge/gradle/internal/MavenizerInstanceImpl.java @@ -57,10 +57,10 @@ private Map validate(Map map) { // this entire error check is gated behind a gradle property. if it's set to false, stop immediately. // also don't bother checking if we aren't using Forge, which is net.minecraftforge:forge/fmlonly // this code is kind of ugly but I don't know how to make it any cleaner without the nesting. - if (!problems.testFalse("net.minecraftforge.gradle.warnings.minecraft.legacy.renamer.missing") - && "net.minecraftforge".equals(dependency.getGroup()) - && ("forge".equals(dependency.getName()) || "fmlonly".equals(dependency.getName()))) { + if (!problems.testFalse("net.minecraftforge.gradle.warnings.minecraft.legacy.renamer.missing")) { var minecraftVersion = map.get("mc.version"); + boolean forge = "net.minecraftforge".equals(dependency.getGroup()) + && ("forge".equals(dependency.getName()) || "fmlonly".equals(dependency.getName())) if (minecraftVersion != null && !"UNKNOWN".equals(minecraftVersion)) { boolean legacy = false; try { @@ -74,7 +74,8 @@ private Map validate(Map map) { int int1 = Integer.parseInt(split[0]); int int2 = Integer.parseInt(split[1]); int int3 = split.length > 2 ? Integer.parseInt(split[2]) : 0; - legacy = int1 <= 1 && int2 <= 20 && int3 < 5; // version < 1.20.5 == legacy + legacy = forge ? int1 <= 1 && int2 <= 20 && int3 < 5 + : int1 < 26; // version < 1.20.5 == legacy for forge, 26 for vanilla } } catch (Exception e) { // there are a number of things that could go wrong here. From cec78c6366c7c74481ae9003eeebc8458c829c1f Mon Sep 17 00:00:00 2001 From: Jonathing Date: Sun, 19 Apr 2026 16:53:49 -0400 Subject: [PATCH 3/4] Fix remaining issues and add extra solutions --- .../gradle/internal/ForgeGradleProblems.java | 21 ++++++++++++++++--- .../internal/MavenizerInstanceImpl.java | 2 +- 2 files changed, 19 insertions(+), 4 deletions(-) diff --git a/src/main/java/net/minecraftforge/gradle/internal/ForgeGradleProblems.java b/src/main/java/net/minecraftforge/gradle/internal/ForgeGradleProblems.java index f8d3035ed..3985c6009 100644 --- a/src/main/java/net/minecraftforge/gradle/internal/ForgeGradleProblems.java +++ b/src/main/java/net/minecraftforge/gradle/internal/ForgeGradleProblems.java @@ -97,25 +97,40 @@ void reportMissingMinecraftDependency() { } void reportMissingRenamerPluginForOldVersion(Dependency dependency) { - if (this.testFalse("net.minecraftforge.gradle.warnings.minecraft.legacy.renamer.missing")) return; + // This should never happen, so assert this check for testing purposes. + assert !this.testFalse("net.minecraftforge.gradle.warnings.minecraft.legacy.renamer.missing"); LOGGER.warn("WARNING: Renamer Gradle not present with legacy Forge version. See Problems report for details."); this.report("legacy-missing-renamer", "Missing Renamer Gradle for legacy Minecraft dependency", spec -> spec .details(""" A legacy Forge dependency was declared, but Renamer Gradle has not been applied to the project! - While the workspace will continue to function, this may cause problems with resultant artifacts not being renamed to obfuscated mappings. + While your mod will work in development, the built jar won't work in production without Renamer Gradle's reobf functionality. Legacy Forge versions use obfuscated mappings at runtime, so this is a requirement if you are publishing this project as a mod that uses Minecraft names. Dependency: '%s'""" .formatted(Util.toString(dependency))) .severity(Severity.WARNING) .solution("Apply the 'net.minecraftforge.renamer' plugin.") + .solution("Review MDKExamples to cross-reference your setup with a working example using Renamer Gradle.") .solution("Disable this warning in 'gradle.properties' if you are an advanced user: `net.minecraftforge.gradle.warnings.minecraft.legacy.renamer.missing=false`") .solution("Consider building your project for a newer version of Forge targeting Minecraft 1.20.5 or newer.") .solution(HELP_MESSAGE)); } void reportMissingRenamerCheckFailed(Dependency dependency, Throwable e) { - LOGG + assert !this.testFalse("net.minecraftforge.gradle.warnings.minecraft.legacy.renamer.missing"); + + LOGGER.warn("WARNING: Failed to check if Renamer Gradle is required. See Problems report for details."); + this.report("failed-missing-renamer-check", "Failed to check if Renamer is required", spec -> spec + .details(""" + Failed to check if Renamer Gradle is required for the Minecraft dependency. + This issue may have been caused due to an invalid or unknown Minecraft version. + Dependency: '%s'""" + .formatted(Util.toString(dependency))) + .withException(e) + .severity(Severity.WARNING) + .solution("Review MDKExamples to cross-reference your setup with a working example using Renamer Gradle.") + .solution("Disable this warning in 'gradle.properties' if you are an advanced user: `net.minecraftforge.gradle.warnings.minecraft.legacy.renamer.missing=false`") + .solution(HELP_MESSAGE)); } RuntimeException invalidMinecraftDependencyType(Dependency dependency) { diff --git a/src/main/java/net/minecraftforge/gradle/internal/MavenizerInstanceImpl.java b/src/main/java/net/minecraftforge/gradle/internal/MavenizerInstanceImpl.java index 76dba4440..933a731a5 100644 --- a/src/main/java/net/minecraftforge/gradle/internal/MavenizerInstanceImpl.java +++ b/src/main/java/net/minecraftforge/gradle/internal/MavenizerInstanceImpl.java @@ -60,7 +60,7 @@ private Map validate(Map map) { if (!problems.testFalse("net.minecraftforge.gradle.warnings.minecraft.legacy.renamer.missing")) { var minecraftVersion = map.get("mc.version"); boolean forge = "net.minecraftforge".equals(dependency.getGroup()) - && ("forge".equals(dependency.getName()) || "fmlonly".equals(dependency.getName())) + && ("forge".equals(dependency.getName()) || "fmlonly".equals(dependency.getName())); if (minecraftVersion != null && !"UNKNOWN".equals(minecraftVersion)) { boolean legacy = false; try { From 9ab7ca32c358fd33643ab451323fe44c1e01198c Mon Sep 17 00:00:00 2001 From: Jonathing Date: Sun, 19 Apr 2026 17:40:12 -0400 Subject: [PATCH 4/4] Update src/main/java/net/minecraftforge/gradle/internal/ForgeGradleProblems.java Co-authored-by: Paint_Ninja --- .../net/minecraftforge/gradle/internal/ForgeGradleProblems.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/net/minecraftforge/gradle/internal/ForgeGradleProblems.java b/src/main/java/net/minecraftforge/gradle/internal/ForgeGradleProblems.java index 3985c6009..3c48bf0ba 100644 --- a/src/main/java/net/minecraftforge/gradle/internal/ForgeGradleProblems.java +++ b/src/main/java/net/minecraftforge/gradle/internal/ForgeGradleProblems.java @@ -104,7 +104,7 @@ void reportMissingRenamerPluginForOldVersion(Dependency dependency) { this.report("legacy-missing-renamer", "Missing Renamer Gradle for legacy Minecraft dependency", spec -> spec .details(""" A legacy Forge dependency was declared, but Renamer Gradle has not been applied to the project! - While your mod will work in development, the built jar won't work in production without Renamer Gradle's reobf functionality. + While your mod will work in development, the built jar won't work in production without Renamer Gradle's reobf functionality explicitly setup. Legacy Forge versions use obfuscated mappings at runtime, so this is a requirement if you are publishing this project as a mod that uses Minecraft names. Dependency: '%s'""" .formatted(Util.toString(dependency)))