Files
Iris/adapters/forge/build.gradle
T
Brian Neumann-Fopiano 94c7181aec Modded 26.3 targets
- Fabric, Forge, and NeoForge build against Minecraft 26.3 with Fabric Loader 0.19.5, Forge 26.3-66.0.8, and NeoForge 26.3.0.33-beta
- Fabric API modules follow fabric-api 0.161.0+26.3, ForgeGradle is 7.0.40, and ModDevGradle is 2.0.147
- Loader metadata requires Fabric Loader 0.19.5, Forge 66, NeoForge 26.3, and Minecraft 26.3
- The mod resource pack declares formats 97.1 through 121.0
- The v26_3_R1 headless sources no longer unpack a version overlay
- The README lists the 26.3 loader targets
2026-09-29 02:48:50 -04:00

347 lines
13 KiB
Groovy

/*
* Iris is a World Generator for Minecraft Servers
* Copyright (c) 2026 Arcane Arts (Volmit Software)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar
import org.gradle.api.file.DeleteSpec
import org.gradle.api.file.FileCopyDetails
import org.gradle.api.file.FileSystemOperations
import org.gradle.api.file.FileTree
import org.gradle.api.tasks.compile.JavaCompile
import org.gradle.jvm.toolchain.JavaLanguageVersion
import javax.inject.Inject
buildscript {
repositories {
mavenCentral()
maven { url = uri('https://jitpack.io') }
}
dependencies {
Properties libraryProperties = new Properties()
file('../../gradle.properties').withInputStream { InputStream stream -> libraryProperties.load(stream) }
String libraryCoordinate = providers.gradleProperty('volmLibCoordinate')
.getOrElse(libraryProperties.getProperty('volmLibCoordinate'))
classpath("com.github.VolmitSoftware.VolmLib:packaging:${libraryCoordinate.tokenize(':').last()}")
}
}
plugins {
id 'java'
id 'net.minecraftforge.gradle' version '7.0.40'
alias(libs.plugins.shadow)
}
apply plugin: 'art.arcane.volmit-packaging'
interface IrisFileOperations {
@Inject
FileSystemOperations getFileSystemOperations()
}
IrisFileOperations irisFileOperations = objects.newInstance(IrisFileOperations)
apply from: file('../../gradle/modded-generation-build-revision.gradle')
Properties rootProperties = new Properties()
file('../../gradle.properties').withInputStream { InputStream stream -> rootProperties.load(stream) }
String irisVersion = providers.gradleProperty('irisVersion').getOrElse(rootProperties.getProperty('irisVersion', '4.1.2-26.2'))
String minecraftVersion = providers.gradleProperty('minecraftVersion').getOrElse(rootProperties.getProperty('minecraftVersion', '26.3'))
String forgeVersion = providers.gradleProperty('forgeVersion').getOrElse(rootProperties.getProperty('forgeVersion', '26.3-66.0.8'))
String volmLibCoordinate = providers.gradleProperty('volmLibCoordinate').getOrElse(rootProperties.getProperty('volmLibCoordinate', 'com.github.VolmitSoftware:VolmLib:master-SNAPSHOT'))
Closure<String> loaderDisplayVersion = { String loaderVersion ->
String coordinatePrefix = "${minecraftVersion}-"
if (loaderVersion.startsWith(coordinatePrefix)) {
return loaderVersion.substring(coordinatePrefix.length())
}
return loaderVersion
}
Closure<String> irisArtifactName = { String platform, String targetVersion ->
return "Iris v${project.version} [${platform}] ${targetVersion}.jar"
}
group = 'art.arcane'
version = irisVersion
java {
toolchain {
languageVersion = JavaLanguageVersion.of(25)
}
}
ext.nativeSourceLoader = 'forge'
apply from: file('../../gradle/native-minecraft-sources.gradle')
sourceSets {
main {
java {
srcDir '../modded-common/src/main/java'
srcDir '../client-common/src/main/java'
}
resources {
srcDir '../modded-common/src/main/resources'
}
}
test {
java {
srcDir '../modded-common/src/test/java'
}
}
}
repositories {
minecraft.mavenizer(it)
maven fg.forgeMaven
maven fg.minecraftLibsMaven
mavenCentral()
maven { url = uri('https://repo.codemc.org/repository/maven-public/') }
maven { url = uri('https://jitpack.io') }
maven { url = uri('https://hub.spigotmc.org/nexus/content/repositories/snapshots/') }
}
configurations {
bundle {
canBeConsumed = false
canBeResolved = true
}
devBundle {
canBeConsumed = false
canBeResolved = true
}
runBundle {
canBeConsumed = false
canBeResolved = true
}
}
configurations.named('bundle').configure {
exclude(group: 'com.google.code.gson')
exclude(group: 'com.google.guava')
exclude(group: 'commons-io')
exclude(group: 'org.apache.commons', module: 'commons-lang3')
exclude(group: 'it.unimi.dsi', module: 'fastutil')
exclude(group: 'org.slf4j')
exclude(group: 'org.apache.logging.log4j')
exclude(group: 'de.crazydev22.slimjar.helper')
exclude(group: 'de.crazydev22.slimjar')
exclude(group: 'io.github.slimjar')
}
configurations.named('runBundle').configure {
exclude(group: 'de.crazydev22.slimjar.helper')
exclude(group: 'de.crazydev22.slimjar')
exclude(group: 'io.github.slimjar')
}
configurations.compileClasspath.extendsFrom(configurations.devBundle)
configurations.runtimeClasspath.extendsFrom(configurations.runBundle)
configurations.testCompileClasspath.extendsFrom(configurations.compileClasspath, configurations.devBundle)
configurations.testRuntimeClasspath.extendsFrom(configurations.runtimeClasspath, configurations.runBundle)
['compileClasspath', 'runtimeClasspath', 'testCompileClasspath', 'testRuntimeClasspath'].each { String name ->
configurations.named(name).configure {
resolutionStrategy.capabilitiesResolution.withCapability('org.lz4:lz4-java') {
selectHighestVersion()
}
}
}
dependencies {
implementation minecraft.dependency("net.minecraftforge:forge:${forgeVersion}")
testImplementation('junit:junit:4.13.2')
testImplementation('org.mockito:mockito-core:5.23.0')
testImplementation(testFixtures('art.arcane:core'))
testImplementation(libs.spigot) {
transitive = false
}
compileOnly('org.slf4j:slf4j-api:2.0.17')
compileOnly(libs.spigot) {
transitive = false
}
add('bundle', volmLibCoordinate) {
transitive = false
}
add('devBundle', volmLibCoordinate) {
transitive = false
}
add('runBundle', volmLibCoordinate) {
transitive = false
}
add('bundle', libs.zip) {
transitive = false
}
add('devBundle', libs.zip) {
transitive = false
}
add('runBundle', libs.zip) {
transitive = false
}
List<Object> shared = [
"art.arcane:core:${irisVersion}".toString(),
"art.arcane:spi:${irisVersion}".toString(),
libs.paralithic,
libs.asm,
libs.lru,
libs.caffeine,
'com.fulcrumgenomics:jlibdeflate:0.2.0',
libs.dom4j,
libs.jaxen
]
shared.each { Object notation ->
add('bundle', notation)
add('devBundle', notation)
add('runBundle', notation)
}
}
minecraft {
accessTransformer.from(art.arcane.volmit.packaging.NativeAccessRules.prepare(nativeSourceImplementation, "forge", layout.buildDirectory.dir("native-access").get().asFile))
runs {
register('client') {
workingDir = layout.projectDirectory.dir('run')
jvmArgs('-Xmx8G')
args('--mixin.config', 'volmlib.entity.mixins.json',
'--mixin.config', 'volmlib.client.mixins.json')
}
register('server') {
workingDir = layout.projectDirectory.dir('run')
String parity = providers.gradleProperty('irisParity').getOrNull()
if (parity != null) {
systemProperty('iris.parity', parity)
}
String parityGolden = providers.gradleProperty('irisParityGolden').getOrNull()
if (parityGolden != null) {
systemProperty('iris.parity.golden', parityGolden)
}
String parityDeep = providers.gradleProperty('irisParityDeep').getOrNull()
if (parityDeep != null) {
systemProperty('iris.parity.deep', parityDeep)
}
String worldCheck = providers.gradleProperty('irisWorldCheck').getOrNull()
if (worldCheck != null) {
systemProperty('iris.worldcheck', worldCheck)
}
jvmArgs('-Xmx8G')
args('--mixin.config', 'volmlib.entity.mixins.json', '--nogui')
}
}
}
tasks.named('compileJava', JavaCompile).configure {
options.encoding = 'UTF-8'
options.release.set(25)
}
tasks.named('test').configure {
}
processResources {
inputs.property('version', irisVersion)
inputs.property('minecraftVersion', minecraftVersion)
filesMatching('META-INF/mods.toml') {
expand('version': irisVersion, 'minecraftVersion': minecraftVersion)
}
}
FileTree staleLoaderJars = fileTree(layout.buildDirectory.dir('libs')) {
include('Iris v* [Forge] *.jar')
include('iris-forge-*.jar')
}
File legacyLoaderJar = layout.buildDirectory.file("libs/Iris-${project.version}+mc${minecraftVersion}-forge.jar").get().asFile
tasks.named('shadowJar', ShadowJar).configure {
doFirst {
irisFileOperations.fileSystemOperations.delete { DeleteSpec spec ->
spec.delete(staleLoaderJars, legacyLoaderJar)
}
}
manifest {
// FML 26.3 has no TOML mixin handling at all (ModFileParser reads neither [[mixins]] nor
// accessTransformers on Forge). This manifest attribute is the only registration mechanism;
// do not move it into mods.toml.
attributes('MixinConfigs': 'volmlib.entity.mixins.json,volmlib.client.mixins.json')
}
archiveFileName.set(irisArtifactName('Forge', "${minecraftVersion}+${loaderDisplayVersion(forgeVersion)}"))
configurations = [project.configurations.named('bundle').get()]
from(sourceSets.main.output)
mergeServiceFiles()
exclude('META-INF/maven/**')
exclude('META-INF/proguard/**')
exclude('META-INF/*.SF')
exclude('META-INF/*.DSA')
exclude('META-INF/*.RSA')
// The only multi-release entry any bundled dependency contributes is an OSGi manifest. Keeping
// it forces `Multi-Release: true` onto the mod jar, which makes the loaders treat the whole
// archive as versioned and re-scan it per release directory for nothing.
exclude('META-INF/versions/**')
addMultiReleaseAttribute.set(false)
exclude('art/arcane/volmlib/util/localization/BukkitLanguageSwitcher*.class')
exclude('art/arcane/volmlib/util/localization/BukkitLanguageEditor*.class')
exclude('art/arcane/volmlib/util/localization/BukkitVolmitCommand*.class')
// Invalid package name on Java 9+ ('enum' is a keyword); a module-path scan chokes on it.
exclude('org/apache/commons/lang/enum/**')
// Compile-only annotation carriers. Shipping them duplicates packages other mods also ship.
exclude('org/jspecify/**')
exclude('com/google/errorprone/**')
exclude('com/google/j2objc/**')
exclude('org/checkerframework/**')
exclude('org/jetbrains/annotations/**')
exclude('org/intellij/lang/**')
// The Bukkit platform binding cannot load without org.bukkit on the classpath, which no mod
// loader has. Shipping it only adds dead classes that reference a missing package.
exclude('art/arcane/iris/platform/bukkit/**')
duplicatesStrategy = DuplicatesStrategy.EXCLUDE
filesMatching('META-INF/services/**') { FileCopyDetails entry ->
entry.duplicatesStrategy = DuplicatesStrategy.INCLUDE
}
relocate('org.objectweb.asm', 'art.arcane.iris.shadow.asm')
// Split-package guard. A co-installed mod that ships any of these at their original coordinates
// puts two copies of the same package on one module layer, which the loaders reject at boot
// (Terra ships paralithic; caffeine and dom4j are common in mod dependency trees). First-party
// art.arcane.volmlib is deliberately NOT relocated.
relocate('com.github.benmanes.caffeine', 'art.arcane.iris.shadow.caffeine')
relocate('com.googlecode.concurrentlinkedhashmap', 'art.arcane.iris.shadow.clhm')
relocate('com.dfsek.paralithic', 'art.arcane.iris.shadow.paralithic')
relocate('org.dom4j', 'art.arcane.iris.shadow.dom4j')
relocate('org.jaxen', 'art.arcane.iris.shadow.jaxen')
relocate('org.zeroturnaround.zip', 'art.arcane.iris.shadow.ztzip')
}
// The thin `jar` output carries valid mods.toml metadata plus the MixinConfigs manifest attribute
// but bundles zero dependencies. Installing it is an instant NoClassDefFoundError, and it sits in
// build/libs right next to the real artifact. shadowJar is the only shippable Forge jar.
tasks.named('jar').configure {
enabled = false
}
tasks.named('assemble').configure {
dependsOn(tasks.named('shadowJar'))
}
pluginPackaging {
artifacts {
create('distribution') {
taskName = 'shadowJar'
policyName = 'Iris Forge'
prunePrefixes = ['art/arcane/volmlib/']
keepPrefixes = ['art/arcane/volmlib/util/matter/slices/']
}
}
}