Minestom’s registry system manages both static (vanilla) and dynamic (custom) game content like biomes, dimensions, enchantments, and more. Registries provide a centralized way to store and reference game data.
Overview
Registries in Minestom come in two flavors:
Static Registries Immutable registries for vanilla content (blocks, items, entities, fluids)
Dynamic Registries Mutable registries for custom content (biomes, dimensions, enchantments)
Use RegistryKey<T> to reference registry entries rather than storing the objects directly. This ensures proper network synchronization and serialization.
Accessing Registries
All registries are accessed through the Registries interface, typically from MinecraftServer or ServerProcess.
Static Registries
Static registries contain vanilla Minecraft content and cannot be modified.
From MinecraftServer
From Registries Interface
import net.minestom.server.MinecraftServer;
import net.minestom.server.instance.block.Block;
import net.minestom.server.item.Material;
// Get static registries
Registry < Block > blocks = MinecraftServer . getBlockRegistry ();
Registry < Material > materials = MinecraftServer . getMaterialRegistry ();
Registry < EntityType > entityTypes = MinecraftServer . getEntityTypeRegistry ();
Registry < Fluid > fluids = MinecraftServer . getFluidRegistry ();
Dynamic Registries
Dynamic registries allow registration of custom content.
Common Dynamic Registries
Other Dynamic Registries
Registries registries = MinecraftServer . process ();
// World registries
DynamicRegistry < Biome > biomes = registries . biome ();
DynamicRegistry < DimensionType > dimensions = registries . dimensionType ();
// Item registries
DynamicRegistry < Enchantment > enchantments = registries . enchantment ();
DynamicRegistry < TrimMaterial > trimMaterials = registries . trimMaterial ();
DynamicRegistry < TrimPattern > trimPatterns = registries . trimPattern ();
RegistryKey
A RegistryKey<T> is a reference to a registry entry, containing the entry’s namespaced key.
Creating Registry Keys
From Registration
Unsafe Creation
// Register returns a RegistryKey
Biome customBiome = Biome . builder ()
. temperature ( 0.8f )
. downfall ( 0.4f )
. build ();
RegistryKey < Biome > biomeKey =
MinecraftServer . getBiomeRegistry (). register ( "myplugin:desert" , customBiome);
Using Registry Keys
Gets the namespaced key Key key = registryKey . key ();
String namespace = key . namespace (); // "minecraft" or "myplugin"
String value = key . value (); // "plains", "desert", etc.
Gets the full key as a string String name = biomeKey . name (); // "myplugin:desert"
DynamicRegistry
Dynamic registries support registration, modification, and removal of entries.
Registration
Registers a new entry with a string ID DynamicRegistry < Biome > biomes = MinecraftServer . getBiomeRegistry ();
Biome customBiome = Biome . builder ()
. temperature ( 0.5f )
. downfall ( 0.5f )
. build ();
RegistryKey < Biome > key = biomes . register ( "myplugin:custom" , customBiome);
Registers a new entry with a Key import net.kyori.adventure.key.Key;
RegistryKey < Biome > key = biomes . register (
Key . key ( "myplugin" , "custom" ),
customBiome
);
Overwriting entries is unsafe and disabled by default. To enable, set the system property minestom.registry.unsafe-ops=true. Overwriting can cause desync with existing structures.
Removal
Removes an entry from the registry boolean removed = biomes . remove ( Key . key ( "myplugin:custom" ));
Removal is dangerous! It remaps all subsequent IDs, which can corrupt existing worlds. Requires minestom.registry.unsafe-ops=true.
Querying
Gets an entry by key Biome plains = biomes . get ( Key . key ( "minecraft:plains" ));
Gets the protocol ID for an entry int id = biomes . getId (biomeKey);
Gets the key for a protocol ID Key key = biomes . getKey ( 10 ); // Returns key for ID 10
Gets all registered entries for ( Biome biome : biomes . values ()) {
// Process each biome
}
Registry Operations
Both static and dynamic registries support these operations:
Gets entry by namespaced key Block stone = blocks . get ( Key . key ( "minecraft:stone" ));
Gets entry by namespace and value Block stone = blocks . get ( "minecraft" , "stone" );
Gets protocol ID for a key
Gets namespaced name for an ID String name = blocks . getName ( 1 ); // "minecraft:stone"
Gets all entries in the registry
Gets the number of registered entries int count = biomes . size ();
Practical Examples
Custom Biome
Custom Dimension
Custom Enchantment
Registry Lookup Utility
Configuration Phase Registry Updates
import net.minestom.server.MinecraftServer;
import net.minestom.server.registry.DynamicRegistry;
import net.minestom.server.registry.RegistryKey;
import net.minestom.server.world.biome.Biome;
import net.kyori.adventure.key.Key;
public class CustomBiomes {
public static final RegistryKey < Biome > VOLCANIC ;
static {
DynamicRegistry < Biome > registry = MinecraftServer . getBiomeRegistry ();
Biome volcanic = Biome . builder ()
. temperature ( 2.0f ) // Very hot
. downfall ( 0.0f ) // No rain
. effects ( Biome . BiomeEffects . builder ()
. fogColor ( 0x603020 )
. skyColor ( 0x800000 )
. waterColor ( 0xFF3300 )
. build ())
. build ();
VOLCANIC = registry . register ( "myplugin:volcanic" , volcanic);
}
public static void applyToChunk ( Instance instance , int chunkX , int chunkZ ) {
Chunk chunk = instance . getChunk (chunkX, chunkZ);
if (chunk != null ) {
// Set biome for entire chunk
chunk . setBiome ( 0 , 0 , 0 , VOLCANIC);
}
}
}
Static Registry Reference
Available Static Registries
All block types (stone, dirt, etc.)
All item materials (diamond_sword, apple, etc.)
All potion effects (speed, strength, etc.)
All entity types (zombie, creeper, etc.)
All fluid types (water, lava)
All game events for sculk sensors
Dynamic Registry Reference
Available Dynamic Registries
World biomes (plains, desert, etc.)
dimensionType()
DynamicRegistry<DimensionType>
Dimension configurations (overworld, nether, end)
enchantment()
DynamicRegistry<Enchantment>
Item enchantments
damageType()
DynamicRegistry<DamageType>
Damage source types
trimMaterial()
DynamicRegistry<TrimMaterial>
Armor trim materials
trimPattern()
DynamicRegistry<TrimPattern>
Armor trim patterns
bannerPattern()
DynamicRegistry<BannerPattern>
Banner patterns
paintingVariant()
DynamicRegistry<PaintingVariant>
Painting variants
jukeboxSong()
DynamicRegistry<JukeboxSong>
Music disc songs
chatType()
DynamicRegistry<ChatType>
Chat message formatting
Best Practices
Store RegistryKeys, not objects : Always store RegistryKey<T> instead of the actual object. This ensures proper serialization and network sync.// Good
private RegistryKey < Biome > biomeKey ;
// Bad
private Biome biome ;
Register early : Register all custom content during server initialization, before any instances are created.public class MyPlugin {
public void onEnable () {
// Register custom content first
CustomBiomes . init ();
CustomDimensions . init ();
// Then create instances
createGameWorld ();
}
}
Use namespaced keys : Always prefix custom content with your plugin/mod namespace to avoid conflicts.// Good
registry . register ( "myplugin:custom_biome" , biome);
// Bad (might conflict with other plugins)
registry . register ( "custom_biome" , biome);
Avoid runtime modifications : Modifying registries after server start requires sending players to configuration phase. This interrupts gameplay and should be avoided.
Don’t enable unsafe operations : The minestom.registry.unsafe-ops flag is dangerous and can corrupt worlds. Only use it in development environments.