MinecraftForge / ForgeGradle

Minecraft mod development framework used by Forge and FML for the gradle build system
GNU Lesser General Public License v2.1
508 stars 437 forks source link

Implement a Legacy Extension #913

Closed TheCurle closed 1 year ago

TheCurle commented 1 year ago

What?

This is for the Retrogradle Initiative. See https://gist.github.com/TheCurle/fe7ad3ede188cbdd15c235cc75d52d4a for more details on what that means.

In short, we're making old versions of Minecraft work under newer toolchains, by porting them to MCPConfig and implementing some changes into an opt-in extension in ForgeGradle.

This Legacy Extension is added for both UserdevPlugin and PatcherPlugin, so that it applies to both userdev and forgedev.
It hooks into the generation of run configs to apply some changes:

It only activates (expresses its features) if it is manually activated; this is done by having an

ext {
    MC_VERSION = '1.11.2'
}

or

legacy {
    <fix> = true
    ie.
    fixClasspath = true
}

entry in the buildscript at the root level. Any version that is registered as being lower than '1.13' by ForgeGradle internally is deemed a trigger for the LegacyExtension.

The fixes implemented are:

Why?

These changes are done to account for the fact that FML1 (1.12 and below) was designed to work with the functionality of ForgeGradle 2.3 and below.

Namely, ForgeGradle 2.3 merges classes and resources into a single folder, thus FML only consumes a single folder when looking for classes and resources.

ForgeGradle 3 cleaned this up to separate them, but FML only consuming a single path means that it only finds the classes, leaving all mod resources out of the runtime.

When activated, the LegacyExtension hijacks the run configs to change the classes output to the jar task input, essentially merging all the compiled classes+resources pre-obfuscation and providing them all to FML.

Additionally, FML1 does runtime remapping of certain things; it is fed the mapping data by ForgeGradle 2, which was removed in FG3 as a cleanup. This is required to make dependencies with coremods work, so the LegacyExtension puts the mappings file into a SystemProperty that the LegacyDev system can make use of at runtime.

Maintenance?

All of the features added by RetroGradle are implemented in a single location; net.minecraftforge.gradle.common.legacy.LegacyExtension. The extension is added to the UserDev and Patcher plugins, and is called once from Utils.createRunConfigTasks.

This makes a maintenance surface of 3 lines for the LegacyExtension.

Additionally, the rationale and functionality of the LegacyExtension is documented thoroughly in code, so that someone trying to fix or reimplement these changes in the future is able to understand what and why is going on.