Skip to content

Minecraft internals

The code that runs Minecraft is not open source. Bukkit is an API that allows plugins to interact with the server. This is implemented by CraftBukkit and interacts with Minecraft’s code. You will often hear the terms NMS and CraftBukkit when talking about Minecraft internals.

NMS stands for net.minecraft.server and refers to a Java package that contains a lot of Mojang’s code. This code is proprietary and is not open source. This code is not guaranteed to be stable when invoked externally and may change at any time.

In order to use Mojang and CraftBukkit code, you may either use the paperweight-userdev Gradle plugin or use reflection. paperweight-userdev is the recommended way to access internal code as it is easier to use due to being able to have the remapped code in your IDE. You can find out more about this in the paperweight-userdev section.

However, if you are unable to use paperweight-userdev, you can use reflection.

Reflection is a way to access code at runtime. This allows you to access code that may not be available at compile time. Reflection is often used to access internal code across multiple versions. However, reflection does come with performance impacts if used improperly. For example, if you are accessing a method or field more than once, you should cache the Field/ Method to prevent the performance impact of looking up the field/method each time.

Minecraft’s code is obfuscated. This means that the names of classes and methods are changed to make them harder to understand. Paper deobfuscates these identifiers for development and since 1.20.5, also for runtime.

Running a Mojang-mapped (moj-map) server is an excellent way to streamline your processes because you can develop using the same mappings that will be present at runtime. This eliminates the need for remapping in your compilation, which in turn simplifies debugging and allows you to hotswap plugins.

As of 1.20.5, Paper ships with a Mojang-mapped runtime by default instead of reobfuscating the server to Spigot mappings. By adopting Mojang mappings, you ensure that your plugin won’t require internal remapping at runtime. For more information, see the plugin remapping section and userdev documentation covering these changes.

You can get the current Minecraft version to allow you to use the correct code for a specific version. This can be done with one of the following methods:

// Example value: 1.21.5
String minecraftVersion = Bukkit.getServer().getMinecraftVersion();
// Example value: 1.21.5-R0.1-SNAPSHOT
String bukkitVersion = Bukkit.getServer().getBukkitVersion();
// Example value for 1.20.1: 3465
int dataVersion = Bukkit.getUnsafe().getDataVersion();