- JVM bytecode is the compact instruction set the Java Virtual Machine executes.
- The Java compiler produces bytecode in
.classfiles, not native machine code. - The same
.classfile runs on any platform with a Java runtime, which is the point of the format. - Mods rewrite bytecode to change the compiled game without ever having its source.
JVM bytecode is the instruction set the Java Virtual Machine executes. When you compile Java source, the compiler does not produce machine code for your CPU. It produces bytecode, a compact, portable format stored in .class files. The JVM reads those instructions at runtime and turns them into native code as it goes.
Where Opal fits
Opal is a Fabric mod, and the modding tools it builds on do the bytecode work for you, so you do not have to touch opcodes by hand. If you want to add behavior in plain JavaScript instead, see the scripting introduction.
How source becomes bytecode
A .java file is text a person writes. A .class file is the compiled output the JVM runs. The compiler reads your source, checks it, and writes one .class file per class, each holding bytecode instructions plus a constant pool, method tables, and other metadata.
Bytecode is not tied to any one processor. The same .class file runs on Windows, macOS, Linux, or anything with a Java runtime, because the JVM is the layer that knows how to execute the instructions on the local machine. That portability is the whole point of the format.
What the instructions look like
Bytecode is a stack-based instruction set. Most operations push values onto an operand stack, pop them off, and push a result. There is no register allocation to reason about; the model is deliberately simple so the JVM can verify and execute it quickly.
A few example opcodes give the flavor:
| Opcode | What it does |
|---|---|
iload | Push an int local variable onto the stack |
iadd | Pop two ints, push their sum |
invokevirtual | Call an instance method |
getfield | Read an instance field |
return | Return from a method |
You rarely read or write these by hand. Tools generate and consume them, which is where a library like ASM comes in.
Why bytecode matters for mods
Bytecode matters because it lets you change behavior without the original source. A Minecraft mod almost never has the game's source code. What it has is the compiled game on disk. To add or alter a feature, a mod reads the existing bytecode, rewrites it, and feeds the result back to the JVM as the classes load.
This is how patching frameworks insert hooks into methods they do not own. They find the right spot in a compiled method and splice in a call to the mod's code. Working at the bytecode level means a mod can attach to the game even though it never sees a line of the original Java.
Where ASM fits
ASM is a Java library for reading, writing, and transforming bytecode. It parses a .class file into events or a tree, lets code modify the instructions, and emits a valid .class file back out. It is small, fast, and works close to the raw format, which is why higher-level modding tools build on top of it rather than parsing class files themselves.
Most modders never call ASM directly. They use a higher-level layer that hides the opcodes and exposes a friendlier way to say "run my code at the start of this method." Underneath, that layer is editing bytecode, often through ASM.
FAQ
No. Machine code is native instructions for a specific CPU. Bytecode is the JVM's own instruction set, which the JVM translates to machine code at runtime. That extra layer is what makes a .class file run on any platform.
Partly. Decompilers reconstruct readable Java from bytecode, and they get close for ordinary code. The result is not always identical to the original, and comments and some local names are gone, but it is usually enough to follow.
Because mods usually do not have the source. They ship against the compiled game. Rewriting bytecode lets a mod change behavior without ever touching, or even having, the original Java files.
Usually not. Modding frameworks and scripting layers handle the bytecode work for you. Knowing how it works helps when you debug a tricky patch or build tooling.