-
Notifications
You must be signed in to change notification settings - Fork 0
Custom Effect Component Integration
While Enchantment Core provides a vast library of effects natively, your mod will likely require registering custom EnchantmentEntityEffect payloads or Item DataComponentType definitions.
Because you are using Enchantment Core, you want your custom effects to be fully configurable. To achieve this, you must seamlessly integrate your standard Vanilla registry calls with the DataTransformerRegistry.
To maintain a clean architecture, define your registry KEY and your JSON keys as public static final Strings directly within your effect record.
If your effect contains any LevelBasedValue properties, you must also provide a LevelBasedKeyProvider. This explicitly lists which properties need dynamic configuration wrappers.
import com.mojang.serialization.Codec;
import com.mojang.serialization.codecs.RecordCodecBuilder;
import java.util.Set;
import johnsmith.enchantmentcore.api.registry.LevelBasedKeyProvider;
import net.minecraft.world.item.enchantment.LevelBasedValue;
public record AutoSmeltEffect(
LevelBasedValue additionalToolUsage,
boolean dropXp
) {
// 1. Define JSON property keys
public static final String ADDITIONAL_TOOL_USAGE = "additional_tool_usage";
public static final String DROP_XP = "drop_xp";
// 2. Define the Registry Identifier Key
public static final String KEY = "auto_smelt";
// 3. Provide the keys mapping to your LevelBasedValues
public static final LevelBasedKeyProvider KEY_PROVIDER = () -> Set.of(ADDITIONAL_TOOL_USAGE);
// 4. Build the Codec
public static final Codec<AutoSmeltEffect> CODEC = RecordCodecBuilder.create(instance ->
instance.group(
LevelBasedValue.CODEC.optionalFieldOf(ADDITIONAL_TOOL_USAGE, LevelBasedValue.constant(0)).forGetter(AutoSmeltEffect::additionalToolUsage),
Codec.BOOL.optionalFieldOf(DROP_XP, true).forGetter(AutoSmeltEffect::dropXp)
).apply(instance, AutoSmeltEffect::new)
);
}Instead of calling the standard Registry.register directly, create a static helper method in your central registry class. This helper intercepts the LevelBasedKeyProvider and pushes its keys to the DataTransformerRegistry before registering the component to Minecraft.
import com.mojang.serialization.MapCodec;
import johnsmith.enchantmentcore.api.registry.LevelBasedKeyProvider;
import johnsmith.enchantmentcore.registry.DataTransformerRegistry;
import net.minecraft.core.Registry;
import net.minecraft.core.registries.BuiltInRegistries;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.item.enchantment.effects.EnchantmentEntityEffect;
public class MyModEffectRegistry {
// Centralized helper method
private static <T extends EnchantmentEntityEffect> MapCodec<T> register(
String name,
LevelBasedKeyProvider keyProvider,
MapCodec<T> codec
) {
// Push keys to the transformer automatically!
for (String key : keyProvider.getLevelBasedKeys()) {
DataTransformerRegistry.registerEffectProperty(key);
}
// Register to Vanilla natively
return Registry.register(
BuiltInRegistries.ENCHANTMENT_ENTITY_EFFECT_TYPE,
ResourceLocation.fromNamespaceAndPath("my_mod", name),
codec
);
}
// Now, registering your effect is completely clean and inherently safe:
public static final MapCodec<AutoSmeltEffect> AUTO_SMELT = register(
AutoSmeltEffect.KEY,
AutoSmeltEffect.KEY_PROVIDER,
AutoSmeltEffect.CODEC
);
public static void initialize() {}
}This structural pattern ensures that whenever you create a new effect, you never accidentally forget to register its properties for data-driven configuration!
Want to learn more about the configuration engine powering Enchantment Core?
Check out Config Understood, the official wiki for Config Overhauled, for a deep dive into dynamic property generation and state synchronization!