Skip to content

Spell Field Anchor & Custom Rendering

JohnSmith474 edited this page Sep 21, 2026 · 1 revision

The SpellFieldAnchorEntity is the invisible backbone of all lingering, cyclical, or delayed Spell Field operations. When the summon_spell_field_anchor effect is executed, this non-tickable (from a physics perspective), un-targetable entity is spawned into the world to manage a nested SpellFieldComponent over time.

While an anchor is inherently invisible, EnchantmentCore provides a robust, data-driven pipeline to attach 2D animated sprites to it, as well as a developer-facing registry for attaching completely custom 3D rendering logic.

Default Visual Rendering (2D Sprites)

By default, passing an AnchorVisualConfig into your summon_spell_field_anchor effect payload allows you to render a 2D quad at the anchor's location. This quad is dynamically rendered at full brightness (ignoring block light) to ensure spell effects look vibrant even inside blocks or entities.

The visual config handles UV manipulation automatically based on the frame_count and ticks_per_frame properties, allowing you to easily animate your spell fields using a standard vertical sprite sheet.

AnchorVisualConfig Properties

Property Type Description
texture ResourceLocation The path to the texture sprite sheet (e.g., my_mod:textures/entity/spell/magic_circle.png).
scale Float The visual scaling multiplier for the quad.
frame_count Integer The total number of animation frames in the vertical sprite sheet.
ticks_per_frame Integer The duration each frame is displayed before advancing.
tint Integer An RGB color tint applied across the entire quad (e.g., 0xFF0000 for red).

Custom Model Rendering (3D Geometry)

If a simple 2D animated quad is insufficient for your spell (e.g., you want to render a complex rotating 3D crystal or a localized black hole shader), you can bypass the default renderer entirely using the AnchorRendererRegistry.

1. Defining the Target

In your enchantment's JSON (or Datagen), supply a custom identifier to the model_id property of the AnchorVisualConfig:

"visual_config": {
  "model_id": "my_mod:crystal_anchor",
  "scale": 2.0
}

2. Implementing the Renderer

Create a class that implements the AnchorModelRenderer functional interface. This interface exposes the raw parameters from Minecraft's EntityRenderer pipeline.

import johnsmith.enchantmentcore.api.client.render.AnchorModelRenderer;
import com.mojang.blaze3d.vertex.PoseStack;
import net.minecraft.client.renderer.MultiBufferSource;
import net.minecraft.world.entity.Entity;

public class CrystalAnchorRenderer implements AnchorModelRenderer {
    @Override
    public void render(Entity entity, float entityYaw, float partialTicks, PoseStack poseStack, MultiBufferSource bufferSource, int packedLight) {
        // Retrieve standard parameters (scale, frames) if you want to utilize them
        float scale = ((SpellFieldAnchor) entity).getVisualScale();

        poseStack.pushPose();
        
        // Apply your custom transformations, rotations, and rendering logic here.
        // e.g., Rendering a BlockState, a custom GeoModel, or raw Vertex buffers.
        
        poseStack.popPose();
    }
}

3. Registering the Renderer

Register your custom renderer during your client-side setup phase, binding it to the model_id you defined in your JSON data.

import johnsmith.enchantmentcore.api.client.render.AnchorRendererRegistry;
import net.minecraft.resources.ResourceLocation;

public class MyModClient {
    public static void init() {
        AnchorRendererRegistry.register(
            ResourceLocation.fromNamespaceAndPath("my_mod", "crystal_anchor"), 
            new CrystalAnchorRenderer()
        );
    }
}

When the SpellFieldAnchorRenderer processes an entity with your mapped model_id, it will immediately delegate the rendering matrix to your custom logic.

Clone this wiki locally