Skip to content

xyz.unifycraft.gradle.multiversion

Deftu edited this page Jul 3, 2022 · 4 revisions

About

Sets up ReplayMod preprocessor and Architectury Loom plugins to support multi-versioning. This is best used along with xyz.unifycraft.gradle.tools or xyz.unifycraft.gradle.tools.loom.

Setup

To set up preprocessor, you're going to need to make multiple Gradle subprojects for each Minecraft version and platform that you want to support. To do this, it is recommended to use the Gradle Kotlin DSL for a more reliable setup. Set this up in your Gradle settings file:

listOf(
    "1.8.9-forge",
    "1.12.2-forge"
).forEach { version ->
    include(":$version")
    project(":$version").apply {
        projectDir = file("versions/$version")
        buildFileName = "../../version.gradle.kts"
    }
}

Once the above is in your settings.gradle.kts file, rename what would be (or set up) your build.gradle(.kts) as version.gradle.kts. We do this because it's easier to understand what build file is used for your source. Your new build.gradle(.kts) file will now serve as a preprocessor config file. Inside this root build file, add this:

plugins {
    id("xyz.unifycraft.gradle.multiversion-root") version("...")
}

preprocess {
    // Setup
}

Inside the preprocess block, we're going to need to link all of our Minecraft versions in order to map them correctly with one another when preprocessing our code. The standard for doing this will be creating a variable where the loader is the first bit, and the version number when empty space is padded with a 0 and the .s are removed. For example, instead of 1.8.9 we'd be using 10809 and our variable will be called forge10809. To link our mappings correctly, we need to have them connected to the more recent version to what we're linking. So for 1.8.9, it'd be 1.12.2. Mappings cannot be linked between types unless they're the same Minecraft version. For example, Forge 1.15.2 cannot be linked to Fabric 1.16.2, but Forge 1.16.2 can be linked to Fabric 1.16.2. This must be kept in mind when deciding what Minecraft versions and mod loaders to support.

Usage

ReplayMod's preprocessor will match comments in your code with specific Minecraft versions and loaders based on variables you provide in your version build file. The toolkit will automatically configure these variables for you. In some cases where your entire class is version-dependant, you can write that code in the version folder's src directory.

As an example of usage for preprocessing, we will use a Kotlin function for checking if a mod is currently loaded, which is dependant on the mod loader.

package com.example

//#if MC<=11202
import net.minecraft.launchwrapper.Launch
import net.minecraftforge.fml.common.Loader
//#elseif MC>=11404 && FORGE==1
//$$ import org.apache.maven.artifact.versioning.DefaultArtifactVersion
//$$ import net.minecraftforge.fml.loading.FMLEnvironment
//$$ import net.minecraftforge.fml.ModList
//#elseif FABRIC==1
//$$ import net.fabricmc.loader.api.FabricLoader
//#endif

class ExampleMod {

    fun isModLoaded(id: String): Boolean {
        //#if MC<=11202
        return Loader.isModLoaded(id)
        //#elseif MC>=11404 && FORGE==1
        //$$ return ModList.get().isLoaded(id)
        //#elseif FABRIC==1
        //$$ return FabricLoader.getInstance().isModLoaded(id)
        //#endif
    }

}

As you can see in the example code, we make checks by beginning our comment with a hash (#) and we define code used if that check is met using a double dollar sign ($$). To check the current Minecraft version, also padded with zeros and without dots, we can use the MC variable. To check which mod loader we're using out of Forge or Fabric, we can use their respective variables FORGE and FABRIC. Booleans are not a valid type in preprocessor, so we use integers with either the value 0 or 1. In this context, 0 is false and 1 is true.