CubicChunks

CubicChunks

840k Downloads

About Fabric, Forge and MinecraftMappingData

Naheulf opened this issue ยท 2 comments

commented

I will summarize what I understood from the answer to the question "Q: How about 1.13.x/1.14.x/1.15.x/1.16.x/1.17.x versions?".

Mojang/Microsoft build Minecraft.jar from a Java Code. This code is the "official" code. In this code there a lot of Java class, methods and properties. All of them have a "human" mean-full clear names. At compile time all theses names are obfuscated (replaced with dummy and mean-less names : aaa, aab, aac, ...).

To create a mod you need to interact with the Minecraft compiled code. You could use obfuscated names but this is not practical at all. To make it a lot easier you can map theses obfuscated names to some human names. At this point there two choices:

  • Create (or use) a community mapping. In previous Minecraft versions (1.12 and earlier) it was the only way available. That why Minecraft Forge do that.
  • Use the "official" mapping from Mojang/Microsoft. That what Fabric does. However this mapping is property of Microsoft. You can't share some code using theses names and Forge don't want to use it for this reason.

However this have a huge drawback. if you want to use the class "aaa" you need to call it "foo" in the forge mapping ans "bar" in the official one. So you can't use the same code to make the mod compatible with both Forge and Fabric.

So what about that:

  1. You first create a mod for forge with the Forge mapping. Then you can share the code with the community name.
  2. You use a script to obfuscate Minecraft related names with the forge mapping to get a commented code with Forge and CubicChunks human names but Minecraft obfuscated names.
  3. You use a script (the same ?) to de-obfuscate theses Minecraft names with the official and private private mapping.
  4. You write the Fabric specific code.
  5. To merge changes with the original forge mod you use another script to reverse steps 3 and 2 (official names -> obfuscate -> community names).
  6. When it works with both Forge and Fabric in dev mode you can return to obfuscate names and build a jar compatible with both Forge and Fabric.
commented

Sadly it's not quite that simple, and maintaining a second version of the mod (at least for 1.12) is unlikely as it's a lot of work.
For 1.17 the plan is to support forge, though several people have said they would like to maintain support for fabric themselves.
Versions below 1.17 are very unlikely to happen as there was significant improvements for mod compatibility in 1.17 thanks to the increasing world height

commented

Use the "official" mapping from Mojang/Microsoft. That what Fabric does. However this mapping is property of Microsoft. You can't share some code using theses names and Forge don't want to use it for this reason.

You actually can share code using it now, most likely. And some developers are using it. We are already using those mappings.

  1. You first create a mod for forge with the Forge mapping. Then you can share the code with the community name.
  2. You use a script to obfuscate Minecraft related names with the forge mapping to get a commented code with Forge and CubicChunks human names but Minecraft obfuscated names.
  3. You use a script (the same ?) to de-obfuscate theses Minecraft names with the official and private private mapping.
  4. You write the Fabric specific code.
  5. To merge changes with the original forge mod you use another script to reverse steps 3 and 2 (official names -> obfuscate -> community names).
  6. When it works with both Forge and Fabric in dev mode you can return to obfuscate names and build a jar compatible with both Forge and Fabric.

The general problem with this approach is that there is a significant portion of code in the forge version that would be different in the fabric version. Such a script is possible, and in fact has been already used to do the majority of work when porting from forge to fabric (it's called devoldefy). Converting back is also possible with minimal changes to the same script. The problem is that keeping these 2 versions in sync would be significantly harder, and it also makes it practically impossible to deal with version control (git) in a useful way.

And it's not a big issue to do it once or even once in a while. But maintaining both and supporting them well is. It's entirely possible for me to port forge code to fabric once in a while, or fabric code to forge. But each of fabric and forge will require different code for mod support, different code for dealing with the platform's API and patches, and code for forge, directly remapped to fabric won't even compile (due to significant portion of forge APIs not existing on fabric). And code from fabric version directly remapped to forge will probably run but will break a significant amount of mods due to missing forge patches. When developing specifically on one platform and only periodically porting to the other one, one of the platform becomes effectively much less supported and issues in the code specific for that platform become much harder to deal with, and debug. If one of the platforms would be practically unsupported anyway with the main focus being on the other one, I prefer to actually focus only on that one platform.

While creating a special setup that deals with it in more or less the way you describe is theoretically possible, it's too much effort on top of an already hard to develop and maintain mod, as it would significantly complicate even simple things.

The only way that would work well is generating forge-style mojang mappings (MCP class names + method and fieeld names from mojang mappings) on fabric. The problem is that this leaves supporting snapshots impossible, which removes my main reason for using fabric in the first place (not because I can't technically make it work, but because of how MCPConfig is allowed to be used).

And the only problem with using full mojang mappings on forge is that forge toolchain doesn't support using different class name mappings (and again, I theoretically could make even that happen, but forge most likely wouldn't even run with different class names).