Mixins
Mixins are a powerful way to modify existing code of the Minecraft server. Nova uses Mixin + MixinExtras and Origami as mixin loader.
For an improved development experience when creating Mixins, we recommend installing the Minecraft Development IntelliJ plugin.
Additionally, you can enable mixin debug output by setting the mixin.debug
system property to true
(-Dmixin.debug=true
).
Getting started
To get started, create a <addon_id>.mixins.json
file in src/main/resources
:
{
"required": true,
"minVersion": "0.8",
"package": "org.example.mixin", // (1)!
"mixins": [], // (2)!
"mixinextras": {
"minVersion": "0.5.0"
}
}
- Path to the package containing your mixin classes. This package should not contain any other non-mixin classes.
- List of relative paths to mixin classes inside your mixin package. The Minecraft Development plugin can populate this list for you.
Then, you can start creating mixins. Note that mixins should be written in Java, so you'll need to place them in src/main/java
instead of src/main/kotlin
, or make src/main/kotlin
a Java sources root.
The following example mixin injects a call to System.out.println("Hello world!")
at the start of the tickServer
method in MinecraftServer
:
package org.example.mixin;
import net.minecraft.server.MinecraftServer;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
@Mixin(MinecraftServer.class)
abstract class ExampleMixin {
@Inject(method = "tickServer", at = @At("HEAD"))
private void onTickServer(CallbackInfo ci) {
System.out.println("Hello world!");
}
}
{
"required": true,
"minVersion": "0.8",
"package": "org.example.mixin",
- "mixins": []
+ "mixins": ["ExampleMixin"],
"mixinextras": {
"minVersion": "0.5.0"
}
}
Limitations
Since your addon's classes and the Minecraft server's classes are not loaded by the same classloader, Mixins cannot directly reference addon classes. Origami solves this problem by replacing calls to your addon's classes with invokedynamic instructions that will then link to the correct class at runtime. Because of this, some Mixin features are currently not supported or may not work correctly. Most notably, injecting interfaces will not work.
Further reading
You can refer to the following sources for a more in-depth Mixin tutorial: