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:

crafting.mod.jsonJSON
{
  "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:

crafting.mod.jsonJSON
{ "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:

BrandEngine.ktKotlin
@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:

ServerBrandMixin.javaJava
@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:

brandengine.mixins.jsonJSON
{ "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.