Project
Engine mods
An advanced, exceptional level: a mod that replaces a part of the game itself. Almost no mod needs it.
Do you need this?
Almost certainly not. Mods written with CraftScript or Kotlin on the Crafting API cover blocks, items, creatures, worlds, interface and events, and they keep working when Minecraft updates. An engine mod is only for replacing a part of the game itself, such as a faster chunk renderer or a new lighting engine. If your idea fits the normal API, use it.
What it gives, and what it costs
The mod's code can use the game's own classes and patch them with mixins. The price: it is made for one exact Minecraft version, runs only on it, and its author has to update it for every game version. Nothing it uses has a compatibility promise.
Declaring it
Add an engine section to crafting.mod.json, listing the mixin configs:
{
"id": "brandengine",
"name": "Brand Engine",
"version": "1.0.0",
"game": "26.3",
"entrypoints": ["com.example.engine.BrandEngine"],
"engine": { "mixins": ["brandengine.mixins.json"] }
}game must be the exact version, for example 26.3, not a range. On any other version the mod does not load, and the game says why.
Exclusive parts
Some parts of the game can only have one replacement. A mod claims them with slots:
{ "engine": { "slots": ["chunk_renderer"] } }| Slot | The part it replaces |
|---|---|
chunk_renderer |
the chunk renderer |
lighting |
the lighting engine |
shaders |
the shader pipeline |
Only one mod can replace each part. If two try, the second one does not load and the Mods screen says which mod has it. A mod that takes shaders turns shader packs off.
In code
Engine features need an explicit opt-in, so nobody uses them by accident:
@OptIn(CraftingInternal::class)
class BrandEngine : CraftingMod {
override fun onLoad(ctx: ModContext) {
Crafting.events.on<ServerStartedEvent> { e ->
val server = Engine.handle(e.server) as MinecraftServer
ctx.logger.info("Server brand: ${server.serverModName}")
}
}
}Engine.handle(view) gives the game's own object behind a Crafting player, world, entity or server.
A mixin
A mixin is written in Java and patches a game class:
@Mixin(MinecraftServer.class)
public abstract class ServerBrandMixin {
@Inject(method = "getServerModName", at = @At("RETURN"), cancellable = true)
private void brand(CallbackInfoReturnable<String> cir) {
cir.setReturnValue(cir.getReturnValue() + "+brandengine");
}
}Its config, brandengine.mixins.json, lists the mixins:
{ "required": true, "package": "com.example.engine.mixin", "compatibilityLevel": "JAVA_25",
"mixins": ["ServerBrandMixin"], "injectors": { "defaultRequire": 1 } }Building
Compile against the game jar and the Mixin library, both as compile-only. Java and Kotlin target version 25.
What players see
The Mods screen marks engine mods: "uses the game directly, made for Minecraft 26.3 only: a game update can break it", and shows which part each one replaces.