libjf-unsafe-v0

libjf-unsafe-v0 provides an entrypoint which is called extremely early and ASM modification. It also ensures dependency libraries are on the classpath during both. Due to the fact that it accesses several internal components of fabric loader, it is probably incompatible with versions of fabric loader it was not explicitly developed for.

UltraEarlyInit

Implement UltraEarlyInit on your entrypoint and add it as a libjf:early entrypoint Please be aware that using any non-jdk classes during the ultra early init stage prevents them from being modified by Mixin/ASM.

ASM

Implement AsmConfig on a class and add it to your fabric.mod.json as a libjf:asm entrypoint. Use skipClasses to prevent a class from being modified by any ASM patches. getPatches should return a Set of patches that should be applied to classes (more on that later). skipClasses and getPatches will only be called once during the initialization process. Please be aware that using un-excluded classes during ASM modification can cause infinite loops. Please also note that during runtime, class names may be in intermediary, yarn or other mappings. You can use AsmTransformer.MAPPING_RESOLVER to resolve intermediary names to their runtime counterparts

Creating an ASM patch

The current ClassNode will be passed to the apply method of every registered Patch instance. You may modify it as you like, but some default things are provided to make this easier:

  • InterfaceImplTargetPatch will apply a Patch only on classes implementing or extending the interface or class specified as the first parameter
  • MethodModificationPatch allows applying MethodPatches only to specific methods on specific classes
  • MethodReplacementPatch is a MethodPatch which replaces the content of its target method with a predefined InsnList

Of course, you can (and should) implement your own patches in addition to these, Examples can be found in libjf-data-manipulation-v0 and GWWHIT

Debugging ASM

Debugging ASM is difficult, but you can use the asm.log/asm.export flags to get additional output. You can do so either by adding -Plibjf.asm.log -Plibjf.asm.export to your JVM args or the following to your fabric.mod.json:

{
  "custom": {
    "libjf": {
      "asm.log": true,
      "asm.export": true
    }
  }
}

I also recommend using IDEAs bytecode viewer on resulting classes to understand the bytecode