This is not meant to be a tutorial on writing ASM. If you need a tutorial on that, you shouldn’t be reading this.

This is mostly about how to update coremods from 1.12.2 to 1.14.4

This is just a draft of the tutorial, more details will be added soon™️

1) META-INF/coremods.json Example

{
	"Transformer 1 Name": "path/to/transformer-1.js",
	"Transformer 2 Name": "path/to/transformer-2.js"
}

2) transformer.js Examples:

3) Basic transformer.js: Target class (at time of writing only classes - not methods or fields - can be targeted) and return class node

function initializeCoreMod() {
	return {
		'coreModName': {
			'target': {
				'type': 'CLASS',
				'name': 'net.minecraft.client.renderer.chunk.ChunkRender'
			},
			'transformer': function(classNode) {
				// Do stuff with classNode
				return classNode;
			}
		}
	}
}

4) Using Java classes

var Opcodes = Java.type('org.objectweb.asm.Opcodes');
var ASMAPI = Java.type('net.minecraftforge.coremod.api.ASMAPI');

5) Looping over the methods

var methods = classNode.methods;

var targetMethodName = ASMAPI.mapMethod("func_178581_b");
var targetMethodDesc = "(FFFLnet/minecraft/client/renderer/chunk/ChunkRenderTask;)V";

for (var i in methods) {
	var method = methods[i];
	
	if (!method.name.equals(targetMethodName)) {
		print("Did not match method name " + targetMethodName + " - " + method.name);
		continue;
	} else if (!method.desc.equals(targetMethodDesc)) {
		print("Did not match method desc " + targetMethodDesc + " - " + method.desc);
		continue;
	}
	print("Matched method " + method.name + " " + method.desc);

	// Do stuff with method.instructions

	// Break because this particular coremod only targets one method
	break;
}

See allowed classes at net.minecraftforge.coremod.CoreModEngine#ALLOWED_CLASSES
6) Loop instructions

var arrayLength = instructions.size();
for (var i = 0; i < arrayLength; ++i) {
	var instruction = instructions.get(i);
	// Do stuff with instruction
}

7) Debugging
If the coremod has syntax errors or something check the very top of your log (before anything like Scanning Mod File: appears). This is at the very top and is usually to high up for IntelliJ’s console to catch it so use the log in /run/logs/.
If the coremod failed to transform properly search for <eval> and/or XFORM in the log. This will be wherever the class gets initialised so probably towards the end.