Registry API
Paper provides type-safe access to Minecraft’s data-driven registries, allowing you to work with enchantments, biomes, items, and other game content in a safe, version-independent way.
What are Registries?
Registries are collections of game content defined by Minecraft’s data-driven system. Examples include:
- Enchantments
- Biomes
- Items and blocks
- Entities
- Damage types
- Game events
- Structures
Registry Access
Basic Registry Access
import io.papermc.paper.registry.RegistryAccess;
import io.papermc.paper.registry.RegistryKey;
import org.bukkit.Registry;
import org.bukkit.enchantments.Enchantment;
import org.bukkit.NamespacedKey;
// Get a registry
Registry<Enchantment> enchantments = RegistryAccess.registryAccess()
.getRegistry(RegistryKey.ENCHANTMENT);
// Get specific entry by key
Enchantment sharpness = enchantments.get(NamespacedKey.minecraft("sharpness"));
// Iterate all entries
for (Enchantment ench : enchantments) {
String name = ench.getKey().getKey();
// Process enchantment
}
Registry Keys
Paper provides typed constants for registry entries:
import io.papermc.paper.registry.keys.EnchantmentKeys;
import io.papermc.paper.registry.keys.ItemTypeKeys;
import io.papermc.paper.registry.keys.BiomeKeys;
import io.papermc.paper.registry.keys.EntityTypeKeys;
// Use registry keys for type-safe access
Enchantment sharpness = enchantments.get(EnchantmentKeys.SHARPNESS);
Enchantment protection = enchantments.get(EnchantmentKeys.PROTECTION);
Enchantment fortune = enchantments.get(EnchantmentKeys.FORTUNE);
Enchantment mending = enchantments.get(EnchantmentKeys.MENDING);
Available Registries
Enchantments
import org.bukkit.enchantments.Enchantment;
import io.papermc.paper.registry.keys.EnchantmentKeys;
// Get enchantment registry
Registry<Enchantment> enchantments = RegistryAccess.registryAccess()
.getRegistry(RegistryKey.ENCHANTMENT);
// Common enchantments
Enchantment sharpness = enchantments.get(EnchantmentKeys.SHARPNESS);
Enchantment efficiency = enchantments.get(EnchantmentKeys.EFFICIENCY);
Enchantment unbreaking = enchantments.get(EnchantmentKeys.UNBREAKING);
Enchantment looting = enchantments.get(EnchantmentKeys.LOOTING);
Enchantment fortune = enchantments.get(EnchantmentKeys.FORTUNE);
Enchantment silkTouch = enchantments.get(EnchantmentKeys.SILK_TOUCH);
// Apply to item
ItemStack item = new ItemStack(Material.DIAMOND_SWORD);
ItemMeta meta = item.getItemMeta();
meta.addEnchant(sharpness, 5, true);
item.setItemMeta(meta);
Biomes
import org.bukkit.block.Biome;
import io.papermc.paper.registry.keys.BiomeKeys;
// Get biome registry
Registry<Biome> biomes = Registry.BIOME;
// Common biomes
Biome plains = biomes.get(BiomeKeys.PLAINS);
Biome desert = biomes.get(BiomeKeys.DESERT);
Biome forest = biomes.get(BiomeKeys.FOREST);
Biome ocean = biomes.get(BiomeKeys.OCEAN);
Biome mountains = biomes.get(BiomeKeys.MOUNTAINS);
// Get biome at location
Biome locationBiome = world.getBiome(x, y, z);
// Set biome
world.setBiome(x, y, z, plains);
Items and Blocks
import io.papermc.paper.registry.keys.ItemTypeKeys;
import io.papermc.paper.registry.keys.BlockTypeKeys;
import org.bukkit.Material;
// Material is already a registry
Material diamond = Material.DIAMOND;
Material stone = Material.STONE;
// Using registry keys
Material diamondSword = Registry.MATERIAL.get(ItemTypeKeys.DIAMOND_SWORD);
Material ironBlock = Registry.MATERIAL.get(BlockTypeKeys.IRON_BLOCK);
// Iterate all items
for (Material mat : Material.values()) {
if (mat.isItem()) {
// Process item
}
}
Entity Types
import org.bukkit.entity.EntityType;
import io.papermc.paper.registry.keys.EntityTypeKeys;
// EntityType is already a registry
EntityType zombie = EntityType.ZOMBIE;
EntityType creeper = EntityType.CREEPER;
// Using registry keys (when available)
// Note: Some registries have keys, others don't
Damage Types
import io.papermc.paper.registry.keys.DamageTypeKeys;
import org.bukkit.damage.DamageType;
// Get damage type registry
Registry<DamageType> damageTypes = RegistryAccess.registryAccess()
.getRegistry(RegistryKey.DAMAGE_TYPE);
// Common damage types
DamageType fall = damageTypes.get(DamageTypeKeys.FALL);
DamageType fire = damageTypes.get(DamageTypeKeys.IN_FIRE);
DamageType drowning = damageTypes.get(DamageTypeKeys.DROWN);
Game Events
import io.papermc.paper.registry.keys.GameEventKeys;
import org.bukkit.GameEvent;
// Get game event registry
Registry<GameEvent> gameEvents = RegistryAccess.registryAccess()
.getRegistry(RegistryKey.GAME_EVENT);
// Common game events
GameEvent blockPlace = gameEvents.get(GameEventKeys.BLOCK_PLACE);
GameEvent blockDestroy = gameEvents.get(GameEventKeys.BLOCK_DESTROY);
GameEvent entityPlace = gameEvents.get(GameEventKeys.ENTITY_PLACE);
GameEvent step = gameEvents.get(GameEventKeys.STEP);
Instruments
import io.papermc.paper.registry.keys.InstrumentKeys;
import org.bukkit.MusicInstrument;
// Get instrument registry
Registry<MusicInstrument> instruments = RegistryAccess.registryAccess()
.getRegistry(RegistryKey.INSTRUMENT);
// Note block instruments
MusicInstrument harp = instruments.get(InstrumentKeys.PONDER_GOAT_HORN);
Jukebox Songs
import io.papermc.paper.registry.keys.JukeboxSongKeys;
import org.bukkit.JukeboxSong;
// Get jukebox song registry
Registry<JukeboxSong> songs = RegistryAccess.registryAccess()
.getRegistry(RegistryKey.JUKEBOX_SONG);
// Music discs
JukeboxSong cat = songs.get(JukeboxSongKeys.CAT);
JukeboxSong pigstep = songs.get(JukeboxSongKeys.PIGSTEP);
Registry Keys
All available registry key classes:
import io.papermc.paper.registry.keys.*;
// Entity and item related
AttributeKeys
BannerPatternKeys
BlockTypeKeys
ItemTypeKeys
EntityTypeKeys
// World related
BiomeKeys
StructureKeys
FluidKeys
// Gameplay
EnchantmentKeys
GameEventKeys
DamageTypeKeys
// Customization
InstrumentKeys
JukeboxSongKeys
CatVariantKeys
WolfVariantKeys
FrogVariantKeys
// Data components
DataComponentTypeKeys
NamespacedKey
All registry entries are identified by NamespacedKeys:
import org.bukkit.NamespacedKey;
// Minecraft namespace (vanilla content)
NamespacedKey vanillaKey = NamespacedKey.minecraft("diamond_sword");
// Plugin namespace (custom content)
NamespacedKey pluginKey = new NamespacedKey(plugin, "custom_item");
// From string
NamespacedKey key = NamespacedKey.fromString("minecraft:stone");
// Get parts
String namespace = key.getNamespace(); // "minecraft"
String value = key.getKey(); // "diamond_sword"
String full = key.toString(); // "minecraft:diamond_sword"
Custom Registry Content
While you can’t add new registry entries at runtime (they’re defined by datapacks), you can:
- Use datapacks to add custom content
- Check if content exists before using it
- Iterate available content from mods/datapacks
// Check if custom enchantment exists
NamespacedKey customKey = NamespacedKey.fromString("mypack:custom_enchant");
Enchantment custom = enchantments.get(customKey);
if (custom != null) {
// Custom enchantment is available
meta.addEnchant(custom, 1, true);
}
// List all enchantments (including custom from datapacks)
for (Enchantment ench : enchantments) {
NamespacedKey key = ench.getKey();
if (!key.getNamespace().equals("minecraft")) {
// Custom enchantment from datapack or mod
logger.info("Found custom enchantment: " + key);
}
}
Datapack Integration
Manage datapacks that provide registry content:
import io.papermc.paper.datapack.Datapack;
import io.papermc.paper.datapack.DatapackManager;
DatapackManager manager = Bukkit.getDatapackManager();
// Get all datapacks
Collection<Datapack> packs = manager.getPacks();
// Enable datapack
Datapack customPack = manager.getPack("my_custom_pack");
if (customPack != null) {
customPack.setEnabled(true);
// Refresh to apply changes
manager.refreshPacks();
}
Registry Best Practices
Use registry keys (e.g., EnchantmentKeys.SHARPNESS) instead of string-based lookups for type safety and better IDE support.
Registry content is loaded from datapacks and cannot be modified at runtime. Use datapacks to add custom content.
Always null-check when getting registry entries by key, especially for custom content that may not be present.
Common Patterns
Safe Registry Access
public Enchantment getEnchantment(String name) {
NamespacedKey key = NamespacedKey.minecraft(name);
Enchantment ench = Registry.ENCHANTMENT.get(key);
if (ench == null) {
throw new IllegalArgumentException("Unknown enchantment: " + name);
}
return ench;
}
Registry Iteration
public void listAllEnchantments() {
Registry<Enchantment> registry = RegistryAccess.registryAccess()
.getRegistry(RegistryKey.ENCHANTMENT);
for (Enchantment ench : registry) {
NamespacedKey key = ench.getKey();
String name = key.getKey();
int maxLevel = ench.getMaxLevel();
logger.info(String.format("%s (max level: %d)", name, maxLevel));
}
}
Resources
Next Steps
Datapack Management
Manage datapacks at runtime
Events API
Handle registry-related events