Decompiled source from Mojang's unobfuscated JARs. No Loom, no Forge toolchains, just Vineflower and Gradle.
Starting with 1.21.11, Mojang ships unobfuscated JARs.
- JDK 21+
- GraalVM 21+ (native builds)
./gradlew setupDecompiles the client jar, splits into server/client sources, applies patches, done.
./gradlew :server:compileJava
./gradlew :client:compileJava./gradlew runServer
./gradlew runClientRun runClient/runServer once before opening.
Hot reload requires JetBrains Runtime in Project Structure, IDEA must run under it too:
export IDEA_JDK="/usr/lib/jvm/java-21-jetbrains"├── jars/ # vanilla jars
├── libs/ # decompiler linking libs
├── patches/ # decompiler fixes
├── mods/
│ ├── client/ # client patches (mymod.patch)
│ └── server/ # server patches (mymod.patch)
├── server/src/ # shared/server source
├── client/src/ # client-only source
├── native/ # GraalVM substitutions and configs
└── prism-instance/ # PrismLauncher instance template
Two-layer patch system:
patches/- fixes for decompiler output (don't touch)mods/client/andmods/server/- your named patches
Edit source, test, then generate a named patch:
./gradlew modGen -Pargs=client,mymod
./gradlew modGen -Pargs=server,mymodThis saves to mods/client/mymod.patch or mods/server/mymod.patch.
Apply named patches to the source:
./gradlew modApply -Pargs=client,mod1,mod2,mod3
./gradlew modApply -Pargs=server,mod1,mod2,mod3Patches are applied in order. If a patch fails:
- Already applied? Use
modRevertfirst - Conflicting mod? Revert the other mod first
Reverse patches (in reverse order):
./gradlew modRevert -Pargs=client,mod1,mod2,mod3
./gradlew modRevert -Pargs=server,mod1,mod2,mod3If revert fails, the patch was likely already reverted or never applied.
Pack changed classes into a zip for distribution:
./gradlew modPackClient
./gradlew modPackServerCompiles current source and outputs changed classes to mods/client.zip or mods/server.zip.
Old-school jar modding is back. To use your mods with PrismLauncher:
-
Copy the instance template:
cp -r prism-instance ~/.local/share/PrismLauncher/instances/my-modded-mc -
Add your mod classes:
cp mods/client.zip ~/.local/share/PrismLauncher/instances/my-modded-mc/jarmods/ -
Restart PrismLauncher:
- There should be a new instance
My Modded Minecraft - You can edit it to toggle
Unobfuscatedcomponent to disable unobfuscated client - Or you can toggle
Modscomponent to disable your mods
- There should be a new instance
The jarMods system merges your classes on top of the base jar at runtime.
prism-instance/
├── instance.cfg # instance name/type
├── mmc-pack.json # components list
├── jarmods/
│ └── client.zip # your compiled mod classes
└── patches/
├── custom.unobfuscated.json # unobfuscated jar override
└── custom.mods.json # jarMods component
Requires ./gradlew setup first.
./gradlew nativeServer
./gradlew nativeClient./gradlew runNativeServer
./gradlew runNativeClientRun the game, trigger as many code paths as possible, then quit. Agent merges into native/configs/, can be run multiple times.
./gradlew nativeServerAgent
./gradlew nativeClientAgentUses Vineflower with standard flags. Patches fix type inference issues, lambda captures, and other decompiler artifacts.
Mojang owns this code. See LICENSE.