NeoGradle
Gradle plugin for NeoForge development
Install / Use
/learn @neoforged/NeoGradleREADME
NeoGradle
Minecraft mod development framework, used by NeoForge and FML for the Gradle build system.
For a quick start, see how the NeoForge Mod Development Kit uses NeoGradle, or see our official Documentation.
To see the latest available version of NeoGradle, visit the NeoForged project page.
Plugins
NeoGradle is separated into several different plugins that can be applied independently of each other.
Userdev Plugin
This plugin is used for building mods with NeoForge. As a modder, this will in many cases be the only plugin you use.
plugins {
id 'net.neoforged.gradle.userdev' version '<neogradle_version>'
}
dependencies {
implementation 'net.neoforged:neoforge:<neoforge_version>'
}
<a id="userdev-access-transformer" /> Access Transformers
The userdev plugin provides a way to configure access transformers for your mod. You need to create an access transformer configuration file in your resources directory, and then configure the userdev plugin to use it.
accessTransformers {
file 'src/main/resources/META-INF/accesstransformer.cfg'
}
The path here is up to you, and does not need to be included in your final jar.
<a id="userdev-access-transformers-from-dependencies" /> From Dependencies
When you want to access transformers during the transform process from a dependency you can do so by using the consume and consumeApi dependency collector:
accessTransformers {
consume 'net.something.group:module:1.0.0-version' //Use the access transformers published by this dependency.
consumeApi 'net.something.group:module:1.0.0-version' //Use the access transformers published by this dependency, and expose it for your consumers as a dependency as well.
}
Alternatively you can use the configurations, accessTransformer or accessTransformerApi respectively, to handle this:
dependencies {
accessTransformer 'net.something.group:module:1.0.0-version' //Use the access transformers published by this dependency.
accessTransformerApi 'net.something.group:module:1.0.0-version' //Use the access transformers published by this dependency, and expose it for your consumers as a dependency as well.
}
<a id="userdev-interface-injections" /> Interface Injections
The userdev plugin provides a way to configure interface injections for your mod. This allows you to have a decompiled minecraft artifact that contains the interfaces you want to inject via mixins already statically applied. The advantage of this approach is that you can use the interfaces in your code, and the mixins will be applied to the interfaces, and not the classes that implement them.
interfaceInjections {
file 'src/main/resources/META-INF/interfaceinjection.json'
}
You can find more information on the format of the file here.
<a id="userdev-interface-injections-from-dependencies" /> From Dependencies
When you want to include interfaces during the injection process from a dependency you can do so by using the consume and consumeApi dependency collector:
interfaceInjections {
consume 'net.something.group:module:1.0.0-version' //Use the interface injections published by this dependency.
consumeApi 'net.something.group:module:1.0.0-version' //Use the interface injections published by this dependency, and expose it for your consumers as a dependency as well.
}
Alternatively you can use the configurations, interfaceInjection or interfaceInjectionApi respectively, to handle this:
dependencies {
interfaceInjection 'net.something.group:module:1.0.0-version' //Use the interface injections published by this dependency.
interfaceInjectionApi 'net.something.group:module:1.0.0-version' //Use the interface injections published by this dependency, and expose it for your consumers as a dependency as well.
}
Dependency management by the userdev plugin
When this plugin detects a dependency on NeoForge, it will spring into action and create the necessary NeoForm runtime tasks to build a usable Minecraft JAR-file that contains the requested NeoForge version. It additionally (if configured to do so via conventions, which is the default) will create runs for your project, and add the necessary dependencies to the classpath of the run.
Version Catalogues
Using gradles modern version catalog feature means that dependencies are added at the very last moment possible, regardless of that is during script evaluation or not. This means that if you use this feature it might sometimes not be possible to configure the default runs exactly as you wished. In that case it might be beneficial to disable the conventions for runs, and configure them manually.
See the following example:
lib.versions.toml:
[versions]
# Neoforge Settings
neoforge = "+"
[libraries]
neoforge = { group = "net.neoforged", name = "neoforge", version.ref = "neoforge" }
build.gradle:
java {
toolchain {
languageVersion = JavaLanguageVersion.of(21)
}
}
repositories {
mavenCentral()
}
dependencies {
implementation(libs.neoforge)
}
runs {
configureEach { run ->
run.modSource sourceSets.main
}
client { }
server { }
datagen { }
gameTestServer { }
junit { }
}
You do not need to create all five of the different runs, only the ones you need. This is because at the point where gradle actually adds the dependency, we can not create any further runs, yet we can still configure them for you when the dependency is added.
<a id="userdev-binary-mode" /> Binary patch mode
The userdev plugin modifies the NeoForm pipeline when it detects that the decompiler should be disabled. In that case it will run a completely seperate subsystem, known as the binary patcher to generate a production like jar, and then apply the binary patches to that. This is significantly faster to setup, better for caching and disk usage, but does not produce a sources jar to debug against.
The binary mode is enabled in one of two conditions:
- The environment variable
CIcontainstrue - The gradle property:
neogradle.subsystems.decompiler.enabledis set tofalse
[!WARNING] For now this mode is only available to the UserDev plugin, it will eventually be ported to the NeoForm plugin as well.
Common Plugin
<a id="common-dep-management" /> Available Dependency Management
<a id="common-dep-management-extra-jar" /> Extra Jar
The common plugin provides dependency management for extra-jar of minecraft. This is a special jar containing just the resources and assets of minecraft, no code. This is useful for mods that want to depend on the resources of minecraft, but not the code.
plugins {
id 'net.neoforged.gradle.common' version '<neogradle_version>'
}
dependencies {
implementation "net.minecraft:client:<minecraft_version>:client-extra"
}
Jar-In-Jar support
The common plugin provides support for jar-in-jar dependencies, both for publishing and when you consume them.
Consuming Jar-In-Jar dependencies
If you want to depend on a project that uses jar-in-jar dependencies, you can do so by adding the following to your build.gradle:
dependencies {
implementation "project.with:jar-in-jar:1.2.3"
}
Obviously you need to replace project.with:jar-in-jar:1.2.3 with the actual coordinates of the project you want to depend on,
and any configuration can be used to determine the scope of your dependency.
<a id="common-jar-in-jar-publishing" /> Publishing
If you want to publish a jar-in-jar dependency, you can do so by adding the following to your build.gradle:
dependencies {
jarJar("project.you.want.to:include-as-jar-in-jar:[my.lowe.supported.version,potentially.my.upper.supported.version)") {
version {
prefer "the.version.you.want.to.use"
}
}
}
Important here to note is that specifying a version range is needed. Jar-in-jar dependencies are not supported with a single version, directly.
If you need to specify a single version, you can do so by specifying the same version for both the lower and upper bounds of the version range: [the.version.you.want.to.use].
<a id="common-jar-in-jar-publishing-moves-and-collisions" /> Handling of moved Jar-In-Jar dependencies
When dependency gets moved from one GAV to another, generally a transfer coordinate gets published, either via maven-metadata.xml, a seperate pom file, or via gradles available-at metadata. This can cause the version of the dependency to be different from the version you specified. It is best that you update your dependency to the new GAV to prevent problems and confusion in the future.
Managing runs
The common plugin provides a way to manage runs in your project. Its main purpose is to ensure that whether you use the vanilla, neoform, platform or userdev modules, you can always manage your runs in the same way.
plugins {
id 'net.neoforged.gradle.common' version '<neogradle_version>'
}
runs {
//...Run configuration
}
<a id="common-runs-configuring-runs" /> Configuring runs
When you create a run in your project, it will initially be empty. If you do not use a run type, or clone the configuration from another run, as described below, you will have to configure the run yourself.
runs {
someRun {
isIsSingleInstance true //This will make the run a single instance run, meaning that only one instance of the run can be run at a t
