Skip to content

Commit 39bb3eb

Browse files
shartteMatyrobbrt
andcommitted
Add legacy support for Forge 1.17 to 1.20.1
Co-authored-by: Matyrobbrt <65940752+matyrobbrt@users.noreply.github.com>
1 parent 951a5c8 commit 39bb3eb

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

42 files changed

+1564
-60
lines changed

.github/workflows/build-prs.yml

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,9 @@ jobs:
2828
strategy:
2929
matrix:
3030
os: [ubuntu-latest, windows-latest]
31+
project: [testproject, legacytest]
3132
runs-on: ${{ matrix.os }}
32-
name: Test on ${{ matrix.os }}
33+
name: Test ${{ matrix.project }} on ${{ matrix.os }}
3334
steps:
3435
- name: Checkout project sources
3536
uses: actions/checkout@v4
@@ -47,12 +48,12 @@ jobs:
4748

4849
- name: Run build
4950
run: ./gradlew build neoForgeIdeSync
50-
working-directory: ./testproject
51+
working-directory: ./${{ matrix.project }}
5152

5253
- name: Ensure clean, build and test work in the same run
5354
run: ./gradlew clean build check
54-
working-directory: ./testproject
55+
working-directory: ./${{ matrix.project }}
5556

5657
- name: Ensure runData runs
5758
run: ./gradlew runData
58-
working-directory: ./testproject
59+
working-directory: ./${{ matrix.project }}

LEGACY.md

Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
# ModDevGradle Legacy Plugin
2+
ModDevGradle has a secondary plugin (ID: `net.neoforged.moddevgradle.legacy`, released alongside the normal plugin with the same version)
3+
that adds support for developing mods against MinecraftForge and Vanilla Minecraft versions 1.17 up to 1.20.1.
4+
5+
The legacy plugin is an "addon" plugin, meaning it operates on top of the normal plugin. This means that the APIs normally used
6+
are also available when using the legacy plugin.
7+
8+
## Basic Usage for MinecraftForge Mods
9+
An example `build.gradle` file for developing a mod against MinecraftForge for 1.20.1 is provided below:
10+
```groovy
11+
plugins {
12+
// Apply the plugin. You can find the latest version at https://projects.neoforged.net/neoforged/ModDevGradle
13+
id 'net.neoforged.moddev.legacy' version '2.0.28-beta'
14+
}
15+
16+
neoForge {
17+
// Develop against MinecraftForge version 47.3.0 for 1.20.1 (the versions can be found at https://files.minecraftforge.net/)
18+
version = "1.20.1-47.3.0"
19+
20+
// Validate AT files and raise errors when they have invalid targets
21+
// This option is false by default, but turning it on is recommended
22+
validateAccessTransformers = true
23+
24+
runs {
25+
client {
26+
client()
27+
}
28+
data {
29+
data()
30+
}
31+
server {
32+
server()
33+
}
34+
}
35+
36+
mods {
37+
testproject {
38+
sourceSet sourceSets.main
39+
}
40+
}
41+
}
42+
```
43+
44+
## Reobfuscating artifacts
45+
Forge used SRG mappings as intermediary mappings in 1.20.1 and below. While your mod is developed against the mappings provided
46+
by Mojang (known as official mappings), you need to reobfuscate it to SRG mappings for it to work in production.
47+
Reobfuscation will automatically be configured for the `jar` task; the non-obfuscated jar will have a `-dev` classifier
48+
and will not be published in favour of the reobfuscated variant. You should upload the `reobfJar` task's output when using a
49+
task to upload to a mod hosting platform, or otherwise the jar without a `-dev` classifier if you're uploading it manually.
50+
51+
You may reobfuscate other jar tasks using `obfuscation.reobfuscate(TaskProvider<AbstractArchiveTask>, SourceSet, Action<RemapJarTask>)`.
52+
For instance, if you want to reobfuscate a `shadowJar` task:
53+
```groovy
54+
shadowJar {
55+
// Change the classifier of the shadow jar to be -dev-all as it's not mapped in intermediary and not usable for production
56+
archiveClassifier = 'dev-all'
57+
}
58+
59+
obfuscation {
60+
// Reobfuscate the shadowJar task, using the classpath of the main sourceset for properly remapping inherited members
61+
reobfuscate(tasks.named('shadowJar'), sourceSets.main) {
62+
// Make the reobfuscated shadowJar have the all classifier
63+
// You could also change it to an empty string if you want it to not have a classifier (in that case, you will also need to change the classifier of the slim `reobfJar` task
64+
archiveClassifier = 'all'
65+
}
66+
}
67+
```
68+
69+
When reobfuscating a jar, it will be replaced in publications with the obfuscated version to avoid publishing jars that aren't mapped to SRG.
70+
71+
## Remapping mod dependencies
72+
As published mods are using intermediary mappings, you must remap them to official mappings before being able to use them as a dependencies.
73+
ModDevGradle creates configurations that will automatically remap dependencies added to them from SRG mappings to official mappings.
74+
The following configurations are created automatically and are children of the configurations without the `mod` prefix:
75+
- `modImplementation`
76+
- `modRuntimeOnly`
77+
- `modCompileOnly`
78+
- `modApi` (only if the `java-library` plugin is applied)
79+
- `modCompileOnlyApi` (only if the `java-library` plugin is applied)
80+
81+
You may create your own remapping configurations using `obfuscation.createRemappingConfiguration(Configuration)`:
82+
```groovy
83+
configurations {
84+
// Create a custom configuration named "custom"
85+
custom
86+
}
87+
88+
obfuscation {
89+
// Create a configuration named "modCustom" that remaps its dependencies and then adds them to the "custom" configuration
90+
createRemappingConfiguration(configurations.custom)
91+
}
92+
```
93+
94+
## Effects of applying the legacy plugin
95+
When applied, the legacy plugin will change the base NeoForm and NeoForge artifact coordinates of the `neoForge` extension to
96+
`de.oceanlabs.mcp:mcp_config` and `net.minecraftforge:forge`.
97+
It will also trigger the creation of various intermediary (SRG) to named (official) mapping files used by various parts of the toolchain, such as
98+
mod reobfuscation and runtime naming services.
99+
Reobfuscation to the intermediary mappings will automatically be configured for the `jar` task, the non-obfuscated jar will have a `-dev` classifier
100+
and will not be published in favour of the reobfuscated variant.

build.gradle

Lines changed: 16 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -70,13 +70,15 @@ sourceSets {
7070
compileClasspath += java8.output
7171
runtimeClasspath += java8.output
7272
}
73+
legacy
7374
}
7475

7576
configurations {
7677
// Configuration for all dependencies that we want shaded.
7778
shaded
7879
// Place shaded dependencies into `compileOnly` so that they do not leak into our publications' dependencies.
7980
compileOnly.extendsFrom shaded
81+
legacyCompileOnly.extendsFrom shaded
8082
testCompileOnly.extendsFrom shaded
8183
testRuntimeOnly.extendsFrom shaded
8284
shadowRuntimeElements {
@@ -123,6 +125,10 @@ dependencies {
123125
testImplementation gradleTestKit()
124126
testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine'
125127
testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
128+
129+
legacyImplementation(sourceSets.main.output)
130+
legacyImplementation(sourceSets.java8.output)
131+
legacyImplementation gradleApi()
126132
}
127133

128134
java {
@@ -135,12 +141,14 @@ java {
135141
jar {
136142
archiveClassifier = 'slim'
137143
from sourceSets.java8.output
144+
from sourceSets.legacy.output
138145
}
139146

140147
shadowJar {
141148
archiveClassifier = "" // Required for the Plugin Publish Plugin to publish this jar
142149

143150
from sourceSets.java8.output
151+
from sourceSets.legacy.output
144152

145153
configurations = [project.configurations.shaded]
146154
enableRelocation = true
@@ -188,6 +196,13 @@ gradlePlugin {
188196
description = "This plugin helps you create Minecraft mods using the NeoForge platform"
189197
tags = ["minecraft", "neoforge", "java", "mod"]
190198
}
199+
legacy {
200+
id = 'net.neoforged.moddev.legacy'
201+
implementationClass = 'net.neoforged.moddevgradle.boot.LegacyModDevPlugin'
202+
displayName = "NeoForge Legacy Mod Development Plugin"
203+
description = "This plugin helps you create Minecraft mods using the Forge platform, up to 1.20.1"
204+
tags = ["minecraft", "neoforge", "forge", "java", "mod"]
205+
}
191206
repositories {
192207
id = 'net.neoforged.moddev.repositories'
193208
implementationClass = 'net.neoforged.moddevgradle.boot.RepositoriesPlugin'
@@ -212,21 +227,7 @@ artifacts {
212227

213228
publishing {
214229
repositories {
215-
maven {
216-
name = 'NeoForge'
217-
if (System.getenv('MAVEN_USER') && System.getenv('MAVEN_PASSWORD')) {
218-
it.url = "https://maven.neoforged.net/releases/"
219-
it.authentication {
220-
it.create('basic', BasicAuthentication)
221-
}
222-
it.credentials { credentials ->
223-
credentials.username = System.getenv('MAVEN_USER')
224-
credentials.password = System.getenv('MAVEN_PASSWORD')
225-
}
226-
} else {
227-
it.url = 'file://' + file("repo").getAbsolutePath()
228-
}
229-
}
230+
maven(gradleutils.publishingMaven)
230231
}
231232
}
232233

gradle/wrapper/gradle-wrapper.jar

79 Bytes
Binary file not shown.

gradle/wrapper/gradle-wrapper.properties

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
distributionBase=GRADLE_USER_HOME
22
distributionPath=wrapper/dists
3-
distributionUrl=https\://services.gradle.org/distributions/gradle-8.9-all.zip
3+
distributionUrl=https\://services.gradle.org/distributions/gradle-8.10-bin.zip
44
networkTimeout=10000
55
validateDistributionUrl=true
66
zipStoreBase=GRADLE_USER_HOME

gradlew

100644100755
File mode changed.

legacytest/.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
run/
2+
repo/
3+
*.log

legacytest/build.gradle

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
plugins {
2+
id 'maven-publish'
3+
id 'net.neoforged.moddev.legacy'
4+
}
5+
6+
group = 'com.example.legacy'
7+
version = '1.0.0'
8+
9+
repositories {
10+
mavenLocal()
11+
maven {
12+
name 'cursemaven'
13+
url 'https://cursemaven.com'
14+
content {
15+
includeGroup "curse.maven"
16+
}
17+
}
18+
}
19+
20+
java {
21+
toolchain {
22+
languageVersion = JavaLanguageVersion.of(17)
23+
}
24+
}
25+
26+
neoForge {
27+
neoFormVersion = '1.19.2'
28+
}
29+
30+
publishing {
31+
publications {
32+
maven(MavenPublication) {
33+
from components.java
34+
}
35+
}
36+
repositories {
37+
maven {
38+
url file('local')
39+
}
40+
}
41+
}

legacytest/forge/build.gradle

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
plugins {
2+
id 'net.neoforged.moddev.legacy'
3+
}
4+
5+
repositories {
6+
mavenLocal()
7+
maven {
8+
name = "Jared's maven"
9+
url = "https://maven.blamejared.com/"
10+
}
11+
maven {
12+
name 'cursemaven'
13+
url 'https://cursemaven.com'
14+
content {
15+
includeGroup "curse.maven"
16+
}
17+
}
18+
}
19+
20+
java {
21+
toolchain {
22+
languageVersion = JavaLanguageVersion.of(17)
23+
}
24+
}
25+
26+
dependencies {
27+
modCompileOnly('mezz.jei:jei-1.20.1-forge:15.17.0.76') {
28+
transitive = false
29+
}
30+
modRuntimeOnly('curse.maven:mekanism-268560:5662583')
31+
modImplementation('curse.maven:applied-energistics-2-223794:5641282')
32+
}
33+
34+
neoForge {
35+
version = '1.20.1-47.3.0'
36+
runs {
37+
client {
38+
client()
39+
}
40+
data {
41+
data()
42+
}
43+
}
44+
mods {
45+
myMod {
46+
sourceSet(sourceSets.main)
47+
}
48+
}
49+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
package mymod;
2+
3+
import mezz.jei.api.IModPlugin;
4+
import mezz.jei.api.JeiPlugin;
5+
import mezz.jei.api.registration.ISubtypeRegistration;
6+
import net.minecraft.resources.ResourceLocation;
7+
import net.minecraft.world.item.Items;
8+
9+
@JeiPlugin
10+
public class JeiCompat implements IModPlugin {
11+
@Override
12+
public ResourceLocation getPluginUid() {
13+
return new ResourceLocation("mymod:mymod");
14+
}
15+
16+
@Override
17+
public void registerItemSubtypes(ISubtypeRegistration registration) {
18+
registration.registerSubtypeInterpreter(Items.ALLIUM, (ingredient, context) -> "allium");
19+
}
20+
}

0 commit comments

Comments
 (0)