Skip to content

Custom Enchantments for PaperMC Plugins

Reedwork lets you define custom Minecraft enchantments as regular Java classes and automatically register them through Paper’s bootstrap lifecycle.

Instead of manually constructing registry entries, you define a CustomEnchantment, annotate it with @Enchantment, and let Reedwork discover and register it during the Paper bootstrap phase.

The process has three main parts:

  • @Enchantment defines the enchantment key.
  • CustomEnchantment defines the enchantment properties.
  • Reedwork.bootstrap(...).scan(...) discovers and registers the enchantment.

A custom enchantment is defined as a regular Java class.

The @Enchantment annotation defines the key used to identify the enchantment:

@Enchantment("reedworkpower")
public final class ReedworkEnchantment implements CustomEnchantment {
// ...
}

The key identifies the enchantment within the Minecraft registry system.

The CustomEnchantment implementation then provides the properties used to create the corresponding Paper enchantment registry entry.

CustomEnchantment provides the configuration used to create the enchantment.

Method Description
description() Defines the enchantment description.
supportedItems() Defines which item types support the enchantment.
anvilCost() Defines the anvil cost.
maxLevel() Defines the maximum enchantment level.
weight() Defines the enchantment weight.
minimumCost() Defines the minimum enchantment cost.
maximumCost() Defines the maximum enchantment cost.
activeSlots() Defines the equipment slots in which the enchantment is active.

For example, the example enchantment is restricted to the DIRT item tag:

@Override
public TagKey<ItemType> supportedItems() {
return ItemTypeTagKeys.DIRT;
}

Its maximum level is defined by maxLevel():

@Override
public int maxLevel() {
return 1;
}

The equipment slots in which the enchantment is active are defined by activeSlots():

@Override
public EquipmentSlotGroup activeSlots() {
return EquipmentSlotGroup.ANY;
}

The remaining methods work in the same way. Reedwork takes the values returned by the implementation and uses them when creating the corresponding Minecraft enchantment registry entry.

Register enchantments during Paper bootstrap

Section titled “Register enchantments during Paper bootstrap”

Custom enchantments are registry-backed Minecraft data and therefore need to be created during the appropriate Paper bootstrap lifecycle.

The example uses a PluginBootstrap implementation:

EnchantmentExampleBootstrap.java
package dev.reedworkmc.examples.enchantment;
import dev.reedworkmc.reedwork.Reedwork;
import io.papermc.paper.plugin.bootstrap.BootstrapContext;
import io.papermc.paper.plugin.bootstrap.PluginBootstrap;
class EnchantmentExampleBootstrap implements PluginBootstrap {
@Override
public void bootstrap(final BootstrapContext context) {
// Plugin bootstrap logic
Reedwork.bootstrap(context).scan("dev.reedworkmc.examples.enchantment");
}
}

The important part is the Reedwork bootstrap scan:

@Override
public void bootstrap(final BootstrapContext context) {
Reedwork.bootstrap(context)
.scan("dev.reedworkmc.examples.enchantment");
}

Reedwork.bootstrap(context) initializes Reedwork for the Paper bootstrap environment.

The scan call discovers Reedwork components in the specified package, including the @Enchantment component, and handles their registration with the Minecraft registry.

No manual registry construction or registration call is required.

Because the custom enchantment is registered during Paper’s bootstrap phase, the plugin declares its bootstrapper in paper-plugin.yml:

paper-plugin.yml
name: EnchantmentExample
version: '${version}'
main: dev.reedworkmc.examples.enchantment.EnchantmentExample
bootstrapper: dev.reedworkmc.examples.enchantment.EnchantmentExampleBootstrap
api-version: '26.2'
load: POSTWORLD

The bootstrapper entry points to the class implementing PluginBootstrap.

Paper can then invoke EnchantmentExampleBootstrap during the bootstrap phase, before the normal plugin lifecycle begins.

This is important for registry-backed content because the enchantment must be created at the appropriate point in the Paper lifecycle.

The complete flow is:

@Enchantment
CustomEnchantment
Reedwork.bootstrap(context)
Package scanning
Minecraft registry entry

The enchantment itself remains a regular Java class:

ReedworkEnchantment.java
package dev.reedworkmc.examples.enchantment;
import dev.reedworkmc.reedwork.annotation.Enchantment;
import dev.reedworkmc.reedwork.enchantment.CustomEnchantment;
import io.papermc.paper.registry.data.EnchantmentRegistryEntry;
import io.papermc.paper.registry.keys.tags.ItemTypeTagKeys;
import io.papermc.paper.registry.tag.TagKey;
import net.kyori.adventure.text.Component;
import org.bukkit.inventory.EquipmentSlotGroup;
import org.bukkit.inventory.ItemType;
@Enchantment("reedworkpower")
public final class ReedworkEnchantment implements CustomEnchantment {
@Override
public Component description() {
return Component.text("The power of Reedwork");
}
@Override
public TagKey<ItemType> supportedItems() {
return ItemTypeTagKeys.DIRT;
}
@Override
public int anvilCost() {
return 1;
}
@Override
public int maxLevel() {
return 1;
}
@Override
public int weight() {
return 5;
}
@Override
public EnchantmentRegistryEntry.EnchantmentCost minimumCost() {
return EnchantmentRegistryEntry.EnchantmentCost.of(1, 1);
}
@Override
public EnchantmentRegistryEntry.EnchantmentCost maximumCost() {
return EnchantmentRegistryEntry.EnchantmentCost.of(1, 5);
}
@Override
public EquipmentSlotGroup activeSlots() {
return EquipmentSlotGroup.ANY;
}
}

The bootstrapper initializes Reedwork and scans the package containing the enchantment.

Reedwork then discovers the annotated component and handles the registry integration.

You define the enchantment and its properties.

Reedwork handles the discovery and registry integration.

Registering custom Minecraft enchantments involves more than defining an enchantment class. The enchantment also has to be created at the appropriate point in Paper’s bootstrap lifecycle and integrated with Minecraft’s registry system.

Reedwork moves that infrastructure into a small, declarative API.

Your enchantment implementation describes:

  • its registry key
  • supported items
  • maximum level
  • anvil cost
  • weight
  • level costs
  • active equipment slots

The bootstrapper only needs to initialize Reedwork and scan the relevant package.

This keeps the enchantment definition separate from the registry and bootstrap infrastructure.

Custom enchantments are one of several Paper plugin systems supported by Reedwork.

You can combine them with dependency injection and other Reedwork-managed components when building a larger plugin.

Explore the other systems:

  • Commands — build PaperMC commands with Java annotations and automatic parameter resolution.
  • Events — automatically discover and register Bukkit and Paper event listeners.
  • Dependency Injection — resolve services and other dependencies through constructors.
  • Utilities — use reusable utilities for Paper plugin development.

The complete runnable custom enchantment example is available in the ReedworkExamples repository.