Skip to content

[7.1/MG] Support Mixin Interface Injections on the Compile Classpath #999

@Jonathing

Description

@Jonathing

A long-term goal of the new toolchain is to expand the capabilities of modder frameworks, such as Mixin, on the user-side. One such request in this regard is to support the injection of interfaces from user-side Mixins on the compile classpath.

Ideal Implementation

While I am creating this initial issue in the ForgeGradle issue tracker, my hope is that this could be a feature in MixinGradle. A part of ForgeGradle 7's new design philosophy is decentralized functionality, meaning that we now have a slew of new plugins that are each mostly single-purpose. The only exception to this is ForgeGradle, which will end up containing Magic for some certain functionalities.

ForgeGradle Magic will be discussed at a later time.

My ideal is that MixinGradle would be updated and rewritten to be framework agnostic, severing its ties from ForgeGradle, while also providing enhanced functionality for buildscripts that use Mixin. Interface injection would be one of them. The idea is to grab the user-side mixins and process the interface injections in an artifact transformer. This artifact transformer would only affect the relevant dependencies (details TBD) and would only affect the compile classpath; the runtime classpath will remain unaffected.

Limitations

Implementing this naturally comes with a few limitations, the biggest one being the need for a standalone Mixin processor. It is simply unreasonable for ForgeGradle or MixinGradle themselves to process Mixin configs and apply changes within Gradle's limited scope. Instead, we can use ExecOperations#javaexec in the artifact transformer to invoke an external tool that can process the configurations for us and transforms the requested dependencies.

The other limitation to be aware of is that this will not play nice with Mixin Connectors, an alternative way to declare Mixin configs as opposed to declaring the Mixin configs in the JAR manifest. MixinConnector implementations reside in the GAME later (🤮), so it would be very difficult to process them without causing some weird issues. In theory, the tool could attempt to run MixinConnector#connect on it in a very limited classpath and gracefully fail if there is some sort of issue running it.

Finally, the existence of a Mixin processor tool for this means yet another (sub)project of Mixin itself. Additionally, we would need to find a way to teach the annotation processor about the changes made to the dependencies in the compile classpath, so that it doesn't process the ahead-of-time transformed classes.

In short, this is going to be a very difficult thing to implement. Very like a post-toolchain goal, but I'm willing to stick through with it. And if we can get it in MixinGradle instead of ForgeGradle, it would benefit way more people than just us. Mixin is framework-agnostic, after all.

Magic

Those of you who have seen my discussions on Magic know that I am often very opposed to it. Yet, this will be a case where magic might end up necessary. For example, how will we know what Mixins to apply to the artifact transformer? We would need to grab the JAR's manifest jar.getManifest().getAttributes().get('MixinConfigs') and use it to grab the declared Mixin config. This is something I consider magic, because this is behavior that is not formally requested in the buildscript.

Nevertheless, it might be prudent to consider magic for this feature, as it can streamline development of mods (or, in the future, other kinds of Java projects using Mixin) since the JAR attribute is the standard location to declare the Mixin config.

Disclaimers

  • Most of my thoughts in this initial issue description are of my (Jonathing) opinions. I am a member of the Forge team and am (currently) the sole developer of ForgeGradle 7 and our new Gradle ecosystem, but each team member has their own opinions and we work together to make a cohesive system with those through productive arguments and compromise. Don't take my word as gospel or as opinion from the other two core team members.
  • I will not hesitate to lock this issue if the discussion regarding this becomes too heated. I am happy to entertain ideas, even ones that the other team members might not agree with, but that doesn't mean anything is set in stone.
  • This issue will be moved to MixinGradle if I am given the ability to work on it.

cc @LexManos, in the long haul I will need your help with the potential Mixin processor tool that this would require.
cc @Tslat, as they requested this feature to me.

Metadata

Metadata

Labels

enhancementEnhances an existing feature in the codebasefeature requestRequests a new feature to be addedplannedFeature or enhancement is planned

Type

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions