Compile Java into a Minecraft datapack
- Create a Java project and include the latest version's jar file on the buildpath
- Write your code, making sure to avoid anything in the standard library, including the
java.langpackage (unless you provide your own@MCJNativeImplusing@MCJImplForto specify the target class) - Export your code as a jar file, making sure to include the MCJ library; the API package it provides will get compiled along with your code
- Call
java -jar MCJ.jar file/to/compile.jar path/to/world/datapacks/datapack namespace [-delete] [-expandedPaths] [-sysout], where-deletecauses the output folder to get deleted prior to compilation (if the output folder exists and-deleteisn't provided, then the compiler may fail),-expandedPathsexports with full paths rather than an md5 hash for non-entrypoint functions, and-sysoutprints progress updates to the console - Launch 23w31a or later (macros are not yet in a release, and they are used extensively to make this possible)
- Use
/reloadand/function namespace:main
Use @MCJEntrypoint to provide and customize additional entrypoints instead of just namespace:main
Use the EventManager to call code when something happens, like a server tick
- Some bytecode instructions are only partially or not at all implemented, so these things aren't currently possible:
- some duplicate instructions (DUP_X2, DUP2, DUP2_X1, DUP2_X2); if it fails to compile, try to rearrange the code :/
- some primitive type casting instructions
- floats and doubles (longs untested and not to Java spec)
- binary math (like bit-shifting and xor)
- invokedynamic (used in lambdas)
- using arrays as
Iterable - instanceof for arrays
- There are no exceptions and no runtime checks, meaning that there is no type safety and you can attempt to create negative length arrays (which is undefined behavior)
- You can't use anything in the standard library, including
java.lang; as mentioned above, use@MCJNativeImpland@MCJImplForto provide your own implementation for a class, allowing you to use it again (refer tocom.luneruniverse.minecraft.mcj.api.java.lang.StringBuilderfor an example
The com.luneruniverse.minecraft.mcj.api package provides useful methods and standard library replacements. Refer to the MinecraftServer class for useful methods, such as exec(String) and getPlayers(). Use Array, CompoundMap, and IterableMap for more advanced data handling.
When working with field and method inheritance, everything is resolved at MCJ compile time, with the exception of polymorphic methods. The polymorphic methods also refer to vtables, which are generated at MCJ compile time. This means that you cannot "merge" two parts of a datapack that were compiled separately. If you would like to have a separate piece of code (eg. a library), make sure to use and distribute the Java bytecode (.class and .jar) files, NOT the .mcfunction files.
Refer to src/test/java/com/luneruniverse/minecraft/mcj/test for more examples
public class Example {
public static void main(String[] args) {
// Prints out all online players
Player[] players = MinecraftServer.getPlayers();
for (int i = 0; i < players.length; i++) {
MinecraftServer.broadcast(players[i].getName());
}
}
}