User Tools

Site Tools


tutorial:mixin_export

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revisionPrevious revision
tutorial:mixin_export [2023/03/15 17:52] – Add instructions for use @Debug to only export certain mixins mattidragontutorial:mixin_export [2025/12/21 23:19] (current) – Expanded to describe dumping targets on failure and navigating an exported Mixin class gauntrecluse
Line 1: Line 1:
-====== Exporting Mixin Classes ======+====== Exporting and Dumping Mixin Targets ====== 
 + 
 +===== Exporting a Transformed Class =====
 When debugging mixins, it's useful to be able to see the finalized classes with your changes and injects inserted. Mixin provides a flag that allows for this: When debugging mixins, it's useful to be able to see the finalized classes with your changes and injects inserted. Mixin provides a flag that allows for this:
  
Line 17: Line 19:
   }   }
  
-=== Notes ==== 
  
-Some classes may not appear until the game is running (or a world is loading)+===== Dumping on Failure ===== 
 +In some cases, you may want to be able to inspect a target class upon Mixin failing and likely throwing a crash. Mixin provides an additional flag for this: 
 + 
 +''-Dmixin.dumpTargetOnFailure=true'' 
 + 
 +Adding this to your VM options similarly to the export flag will dump the class as it was just as Mixin failed the injection. This can be particularly useful if the cause of the error cannot be understood from the errors, target code and Mixin as they are in the development environment. 
 + 
 +Dumping will place the dumped classes to the same filepath as it would for a regular export. 
 + 
 + 
 +===== Navigating an Exported Class ===== 
 + 
 +Once you have an exported Mixin class, you should look for ''@MixinMerged'' annotated members, which represent the members added by Mixins. Injector handlers, the methods annotated by injector annotations, are generally at the very bottom of the exported class, and have "mangled" names. Meaning that, to ensure their names do not clash with any other injector, their names are procedurally modified by Mixin to be unique. 
 + 
 +==== Reading Mangled Names ==== 
 + 
 +The mangled names, on Fabric Mixin, follow the structure of ''<injector type>$<session id>$<modid>$<original handler method name>(<parameters>)''.\\ 
 +The following table can be used to match the injector type prefix to the corresponding annotation: 
 + 
 +^ Injector Annotation    ^ Mangled Prefix        ^ 
 +| Base Mixin             || 
 +| @Inject                | handler               | 
 +| @ModifyArg             | modify                | 
 +| @ModifyArgs            | args                  | 
 +| @ModifyConstant        | constant              | 
 +| @ModifyVariable        | localvar              | 
 +| @Redirect              | redirect              | 
 +| MixinExtras            || 
 +| @ModifyExpressionValue | modifyExpressionValue | 
 +| @ModifyReceiver        | modifyReceiver        | 
 +| @ModifyReturnValue     | modifyReturnValue     | 
 +| @WrapWithCondition     | wrapWithCondition     | 
 +| @WrapOperation         | wrapOperation         | 
 + 
 + 
 +==== Annotations on Merged Members ==== 
 +On top of being mangled, the handler is also annotated to provide additional information about the injector used. The handler will keep all of its ''@Expression'' and ''@Definition'' annotations if it used [[https://github.com/LlamaLad7/MixinExtras/wiki/Expressions|MixinExtras Expressions]]. When not using the Mixin Annotation Processor (off by default in latest Loom versions), the ''@Definition''s will be remapped rather than using refmap. This could be used to detect Loom failing to remap certain elements in the target method when dumping on failure. 
 + 
 +Outside of expression annotations, the handler will be decorated with ''@MixinMerged'', which is formatted as follows: 
 + 
 +<code java> 
 +@MixinMerged( 
 +    mixin = "<path to Mixin class>", 
 +    priority = <Mixin class priority>, 
 +    sessionId = "<session ID>" 
 +
 +</code> 
 +(Formatting not necessarily consistent between decompilers) 
 + 
 +This also applies to most merged members, though other annotations may be present depending on the member, such as ''@Unique'' for unique fields. 
 + 
 +An example ''@MixinMerged'' could look like: 
 +<code java> 
 +@MixinMerged( 
 +    mixin = "net.fabricmc.fabric.mixin.resource.loader.MinecraftServerMixin", 
 +    priority = 1000, 
 +    sessionId = "f0f95788-8e61-4d03-8398-87e419457a83" 
 +
 +</code> 
 + 
 +Using the mangled name and the ''@MixinMerged'' annotation's information, it is possible to distinguish which injector you wish to debug, and then look for usages of the mangled handler name in the class. 
 + 
 + 
 +===== Notes ===== 
 + 
 +==== At what point are classes exported ==== 
 +Mixins are applied relative to when the target class is loaded. As such, classes may be transformed and exported at any point between the game starting and an in-game world loading. If a class is not being exported at all without errors, make sure your test run goes as far as world loading
 + 
 +==== ''@Debug'' persists in production environments ==== 
 +When using the ''@Debug'' annotation, remember that if you keep its ''export'' value to ''true'', it will still export even when the mod is built into a ''jar'' to potentially be published. This could cause unintended and unnecessary behavior for your players, so remember to turn the ''@Debug'' annotation's exporting to ''false'' before any player-oriented jar is made.
tutorial/mixin_export.txt · Last modified: 2025/12/21 23:19 by gauntrecluse