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.
NeoGradle is separated into several different plugins that can be applied independently of each other.
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>'
}
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.
This plugin enables use of the NeoForm runtime and allows projects to depend directly on deobfuscated but otherwise unmodified Minecraft artifacts.
This plugin is used internally by other plugins and is usually only needed for advanced use cases.
plugins {
id 'net.neoforged.gradle.neoform' version '<neogradle_version>'
}
dependencies {
// For depending on a Minecraft JAR-file with both client- and server-classes
implementation "net.minecraft:neoform_joined:<neoform-version>"
// For depending on the Minecraft client JAR-file
implementation "net.minecraft:neoform_client:<neoform-version>"
// For depending on the Minecraft dedicated server JAR-file
implementation "net.minecraft:neoform_server:<neoform-version>"
}
To get human-readable parameter names in decompiled Minecraft source-code, as well as Javadocs, crowdsourced data from the Parchment project can be applied to the Minecraft source-code before it is recompiled.
This is currently only supported when applying the NeoGradle userdev Plugin.
The most basic configuration is using the following properties in gradle.properties:
neogradle.subsystems.parchment.minecraftVersion=1.20.2
neogradle.subsystems.parchment.mappingsVersion=2023.12.10
The subsystem also has a Gradle DSL and supports more parameters, explained in the following Gradle snippet:
subsystems {
parchment {
// The Minecraft version for which the Parchment mappings were created.
// This does not necessarily need to match the Minecraft version your mod targets
// Defaults to the value of Gradle property neogradle.subsystems.parchment.minecraftVersion
minecraftVersion = "1.20.2"
// The version of Parchment mappings to apply.
// See https://parchmentmc.org/docs/getting-started for a list.
// Defaults to the value of Gradle property neogradle.subsystems.parchment.mappingsVersion
mappingsVersion = "2023.12.10"
// Overrides the full Maven coordinate of the Parchment artifact to use
// This is computed from the minecraftVersion and mappingsVersion properties by default.
// If you set this property explicitly, minecraftVersion and mappingsVersion will be ignored.
// The built-in default value can also be overriden using the Gradle property neogradle.subsystems.parchment.parchmentArtifact
// parchmentArtifact = "org.parchmentmc.data:parchment-$minecraftVersion:$mappingsVersion:checked@zip"
// Set this to false if you don't want the https://maven.parchmentmc.org/ repository to be added automatically when
// applying Parchment mappings is enabled
// The built-in default value can also be overriden using the Gradle property neogradle.subsystems.parchment.addRepository
// addRepository = true
// Can be used to explicitly disable this subsystem. By default, it will be enabled automatically as soon
// as parchmentArtifact or minecraftVersion and mappingsVersion are set.
// The built-in default value can also be overriden using the Gradle property neogradle.subsystems.parchment.enabled
// enabled = true
}
}
The settings used by the decompiler when preparing Minecraft dependencies can be overridden using Gradle properties. This can be useful to run NeoGradle on lower-end machines, at the cost of slower build times.
Property | Description |
---|---|
neogradle.subsystems.decompiler.maxMemory |
How much heap memory is given to the decompiler. Can be specified either in gigabyte (4g ) or megabyte (4096m ). |
neogradle.subsystems.decompiler.maxThreads |
By default the decompiler uses all available CPU cores. This setting can be used to limit it to a given number of threads. |
neogradle.subsystems.decompiler.logLevel |
Can be used to override the decompiler loglevel. |
The settings used by Neogradle for recompiling the decompiled Minecraft source code can be customized using Gradle properties.
Property | Description |
---|---|
neogradle.subsystems.recompiler.maxMemory |
How much heap memory is given to the decompiler. Can be specified either in gigabyte (4g ) or megabyte (4096m ). Defaults to 1g . |
neogradle.subsystems.recompiler.jvmArgs |
Pass arbitrary JVM arguments to the forked Gradle process that runs the compiler. I.e. -XX:+HeapDumpOnOutOfMemoryError |
neogradle.subsystems.recompiler.args |
Pass additional command line arguments to the Java compiler. |
neogradle.subsystems.recompiler.shouldFork |
Indicates whether or not a process fork should be used for the recompiler. (Default is true). |
This implements run specific dependency management for the classpath of a run. In the past this had to happen via a manual modification of the "minecraft_classpath" token, however tokens don't exist anymore as a component that can be configured on a run. It was as such not possible to add none FML aware libraries to your classpath of a run. This PR enables this feature again.
dependencies {
implementation 'some:library:1.2.3'
}
runs {
testRun {
dependencies {
runtime 'some:library:1.2.3'
}
}
}
configurations {
libraries {}
implementation.extendsFrom libraries
}
dependencies {
libraries 'some:library:1.2.3'
}
runs {
testRun {
dependencies {
runtime project.configurations.libraries
}
}
}
The dependency handler on a run works very similar to a projects own dependency handler, however it has only one "configuration" available to add dependencies to: "runtime". Additionally, it provides a method to use when you want to turn an entire configuration into a runtime dependency.
In general, we suggest, no strongly encourage, to not use fat jars for this solution. The process of creating a fat jar with all the code from your sibling projects is difficult to model in a way that is both correct and efficient for a dev project, especially if the sibling project does not use NeoGradle.
If it is possible to use a NeoGradle module (for example the Vanilla module, instead of VanillaGradle) then you can use the source-set's mod identifier:
sourceSets {
main {
run {
modIdentifier '<some string that all projects in your fat jar have in common>'
}
}
}
The value of the modIdentifier does not matter here, all projects with the same source-set mod identifier will be included in the same fake fat jar when running your run.
If the sibling project does not use NeoGradle, then you have to make sure that its Manifest is configured properly:
FMLModType: GAMELIBRARY #Or any other mod type that is not a mod, like LIBRARY
Automatic-Module-Name: '<some string that is unique to this project>'
Caution
If you do this, then your sibling projects are not allowed to contain a class in the same package! This is because no two modules are allowed to contain the same package. If you have two sibling projects with a class in the same package, then you will need to move one of them!
To include the sibling project in your run, you need to add it as a modSource to your run:
runs {
someRun {
modSources {
add project.sourceSets.main // Adds the owning projects main sourceset to a group based on that sourcesets mod identifier (could be anything here, depending on the sourcesets extension values, or the project name)
add project(':api').sourceSets.main // Assuming the API project is not using NeoGradle, this would add the api project to a group using the `api` key, because the default mod identifier for non-neogradle projects is the projects name, here api
local project(':api').sourceSets.main // Assuming the API project is not using NeoGradle, this would add the api project to a group using the owning projects name, instead of the api projects name as a fallback (could be anything here, depending on the sourcesets extension values, or the project name)
add('something', project(':api').sourceSets.main) // This hardcodes the group identifier to 'something', performing no lookup of the mod identifier on the sourceset, or using the owning project, or the sourcesets project.
}
}
}
No other action is needed.
By default, conventions are enabled. If you want to disable conventions, you can do so by setting the following property in your gradle.properties:
neogradle.subsystems.conventions.enabled=false
We will consider the conventions to be enabled going forward, so if you want to disable them, you will have to do so explicitly.
NeoGradle will add several Configurations
to your project.
This convention can be disabled by setting the following property in your gradle.properties:
neogradle.subsystems.conventions.configurations.enabled=false
Per SourceSet the following configurations are added, where XXX is the SourceSet name:
- XXXLocalRuntime
- XXXLocalRunRuntime
Note
For this to work, your SourceSets need to be defined before your dependency block.
Per Run the following configurations are added:
- XXXRun
Note
For this to work, your Runs need to be defined before your dependency block.
Globally the following configurations are added:
- runs
This configuration is used to add dependencies to your local projects runtime only, without exposing them to the runtime of other projects. Requires source set conventions to be enabled
This configuration is used to add dependencies to the local runtime of the runs you add the SourceSets too, without exposing them to the runtime of other runs. Requires source set conventions to be enabled
This configuration is used to add dependencies to the runtime of a specific run only, without exposing them to the runtime of other runs.
This configuration is used to add dependencies to the runtime of all runs.
To disable the sourceset management, you can set the following property in your gradle.properties:
neogradle.subsystems.conventions.sourcesets.enabled=false
By default, the current project is automatically included in its runs. If you want to disable this, you can set the following property in your gradle.properties:
neogradle.subsystems.conventions.sourcesets.automatic-inclusion=false
This is equivalent to setting the following in your build.gradle:
runs {
configureEach { run ->
run.modSource sourceSets.main
}
}
By default, the local run runtime configuration of a sourceset is automatically included in the runs configuration of the run. If you want to disable this, you can set the following property in your gradle.properties:
neogradle.subsystems.conventions.sourcesets.automatic-inclusion-local-run-runtime=false
This is equivalent to setting the following in your build.gradle:
runs {
configureEach { run ->
run.dependencies {
runtime sourceSets.main.configurations.localRunRuntime
}
}
}
If this functionality is disabled then the relevant configurations local run runtime configurations will not be created.
To disable the IDE integrations, you can set the following property in your gradle.properties:
neogradle.subsystems.conventions.ide.enabled=false
To disable the IDEA integration, you can set the following property in your gradle.properties:
neogradle.subsystems.conventions.ide.idea.enabled=false
If you have configured your IDEA IDE to run with its own compiler, you can disable the autodetection of the IDEA compiler by setting the following property in your gradle.properties:
neogradle.subsystems.conventions.ide.idea.compiler-detection=false
This will set the DSL property:
idea {
runs {
runWithIdea = true / false
}
}
If you want to change the output directory of the IDEA compiler, you can set the following property in your gradle.properties:
neogradle.subsystems.conventions.ide.idea.compiler-output-dir=<path>
By default, this is set to 'out', and configured in the DSL as:
idea {
runs {
outDirectory = '<path>'
}
}
By default, the import in IDEA is run during the sync task. If you want to disable this, and use a post sync task, you can set the following property in your gradle.properties:
neogradle.subsystems.conventions.ide.idea.use-post-sync-task=true
To disable the runs conventions, you can set the following property in your gradle.properties:
neogradle.subsystems.conventions.runs.enabled=false
By default, a run is created for each type of run. If you want to disable this, you can set the following property in your gradle.properties:
neogradle.subsystems.conventions.runs.create-default-run-per-type=false
To configure tools used by different subsystems of NG, the subsystems dsl and properties can be used to configure the following tools:
This tool is used by the parchment subsystem to apply its names and javadoc, as well as by the source access transformer system to apply its transformations. The following properties can be used to configure the JST tool:
neogradle.subsystems.tools.jst=<artifact coordinate for jst cli tool>
This tool is used by the runs subsystem to enable Minecraft authentication in client runs. The following properties can be used to configure the DevLogin tool:
neogradle.subsystems.tools.devLogin=<artifact coordinate for devlogin cli tool>
More information on the relevant tool, its released version and documentation can be found here: DevLogin by Covers1624
The DevLogin tool is a tool that allows you to log in to a Minecraft account without having to use the Minecraft launcher, during development. During first start it will show you a link to log in to your Minecraft account, and then you can use the tool to log in to your account. The credentials are cached on your local machine, and then reused for future logins, so that re-logging is only needed when the tokens expire. This tool is used by the runs subsystem to enable logged in plays on all client runs. The tool can be configured using the following properties:
neogradle.subsystems.devLogin.enabled=<true/false>
By default, the subsystem is enabled, and it will prepare everything for you to log in to a Minecraft account, however you will still need to enable it on the runs you want. If you want to disable this you can set the property to false, and then you will not be asked to log in, but use a random non-signed in dev account.
If you want to configure the dev login tool per run, you can do so by setting the following properties in your run configuration:
runs {
someRun {
devLogin {
enabled true
}
}
}
This will enable the dev login tool for this run. By default, the dev login tool is disabled, and can only be enabled for client runs.
Warning
If you enable the dev login tool for a non-client run, you will get an error message.
If you want to enable the dev login tool for all client runs, you can set the following property in your gradle.properties:
neogradle.subsystems.devLogin.conventionForRun=true
This will enable the dev login tool for all client runs, unless explicitly disabled.
Additionally, it is possible to use a different user profile for the dev login tool, by setting the following property in your run configuration:
runs {
someRun {
devLogin {
profile '<profile>'
}
}
}
If it is not set then the default profile will be used. See the DevLogin documentation for more information on profiles: DevLogin by Covers1624
To add the dev login tool to your run we create a custom configuration to which we add the dev login tool. This configuration is created for the first source-set you register with the run as a mod source set. The suffix for the configuration can be configured to your personal preference, by setting the following property in your gradle.properties:
neogradle.subsystems.devLogin.configurationSuffix=<suffix>
By default, the suffix is set to "DevLoginLocalOnly". We use this approach to create a runtime only configuration, that does not leak to other consumers of your project.
NeoGradle has a centralized cache that can be used to store the decompiled Minecraft sources, the recompiled Minecraft sources, and other task outputs of complex tasks. The cache is enabled by default, and can be disabled by setting the following property in your gradle.properties:
net.neoforged.gradle.caching.enabled=false
You can clean the artifacts that are stored in the cache by running the following command:
./gradlew cleanCache
This command is also automatically run, when you run the clean task. The command will check if the stored artifact count is higher than the configured threshold, and if so, remove the oldest artifacts until the count is below the threshold. The count is configured by the following property in your gradle.properties:
net.neoforged.gradle.caching.maxCacheSize=<number>
There are two properties you can tweak to get more information about the cache:
net.neoforged.gradle.caching.logCacheHits=<true/false>
and
net.neoforged.gradle.caching.debug=<true/false>
The first property will log when a cache hit occurs, and the second property will log more information about the cache in general, including how hashes are calculated. If you are experiencing issues with the cache, you can enable these properties to get more information about what is happening.