API Custom Models - MarkusBordihn/BOs-Easy-NPC GitHub Wiki

Custom Model Layer API 🎭

Easy NPC exposes renderer helpers for original-model overrides and additional custom model layers.

Back to API.

Overview

The current public entry points are:

  • OriginalModelConfig
  • CustomModelConfig
  • EasyNPCEntityRenderer
  • the built-in raw renderers under client/renderer/entity/raw

The built-in custom render layers currently include dedicated implementations for:

  • chicken
  • ghast
  • pig
  • slime

Original Model Configuration

Use OriginalModelConfig when you want to change the behavior of the original renderer without adding custom geometry:

OriginalModelConfig.DEFAULT
OriginalModelConfig.withHidden()
OriginalModelConfig.withTexture(texture)
OriginalModelConfig.withVariantTexture()
OriginalModelConfig.withEntityTexture()

Behavior:

  • DEFAULT uses the entity texture pipeline
  • withHidden() hides the original model
  • withTexture(...) forces a fixed texture
  • withVariantTexture() skips custom or remote skin lookup and uses only the variant texture
  • withEntityTexture() uses the full entity texture lookup

Custom Model Configuration

Use CustomModelConfig when you want to add or replace geometry:

CustomModelConfig.overlay(layer, texture)
CustomModelConfig.overlayUseEntityTexture(layer)
CustomModelConfig.overlayUseVariantTexture(layer)
CustomModelConfig.replacement(layer, texture)
CustomModelConfig.replacementUseEntityTexture(layer)
CustomModelConfig.replacementUseVariantTexture(layer)

All current factory methods require a ModelLayerLocation.

Behavior helpers:

config.hasCustomModel()
config.shouldUseEntityTexture()
config.shouldUseVariantTexture()
config.shouldHideOriginal()

Layer Registration Example

You still need to register your own ModelLayerLocation and layer definition on the client side.

Example:

public class MyModModelLayers {
  public static final ModelLayerLocation ARMORED_PIG =
      new ModelLayerLocation(new ResourceLocation("yourmod", "armored_pig"), "main");
}

Fabric example:

EntityModelLayerRegistry.registerModelLayer(
    MyModModelLayers.ARMORED_PIG,
    ArmoredPigModel::createBodyLayer);

Forge example:

event.registerLayerDefinition(
    MyModModelLayers.ARMORED_PIG,
    ArmoredPigModel::createBodyLayer);

Example with a Raw Renderer

Built-in raw renderers expose constructors that accept these config objects. For example, PigRawRenderer supports:

new PigRawRenderer(context)
new PigRawRenderer(context, originalConfig)
new PigRawRenderer(context, customConfig)
new PigRawRenderer(context, originalConfig, customConfig)

Example:

OriginalModelConfig originalConfig = OriginalModelConfig.DEFAULT;
CustomModelConfig customConfig =
    CustomModelConfig.overlayUseEntityTexture(MY_MODEL_LAYER);

EntityRendererProvider.Context context = ...;
PigRawRenderer renderer = new PigRawRenderer(context, originalConfig, customConfig);

If you want your own custom layer class instead of a built-in one, the relevant base class is CustomModelRenderLayer.

Minimal example:

public class ArmoredPigLayer extends CustomModelRenderLayer<Pig, PigModel<Pig>> {

  public ArmoredPigLayer(
      RenderLayerParent<Pig, PigModel<Pig>> renderer,
      EntityModelSet modelSet,
      CustomModelConfig config) {
    super(renderer, new PigModel<>(modelSet.bakeLayer(config.getModelLayer())), config);
  }
}

Texture Behavior

The texture pipeline is implemented in EasyNPCEntityRenderer.

Current helper methods include:

  • getTextureLocationWithConfig(entity)
  • getEntityTexture(easyNPC)
  • getVariantTexture(easyNPC)
  • getTextureByVariant(variant)

If the original model is hidden or a replacement model is active, the original renderer falls back to a transparent texture.

The current implementation copies parent model properties to the custom model and then runs the custom model animation setup before rendering. This is why overlay and replacement layers can track the parent model animation state.

Supported Raw Renderers

The codebase currently contains many raw renderers, not just pig support. The current list lives in:

core/Common/src/main/java/de/markusbordihn/easynpc/client/renderer/entity/raw

Examples currently present there include raw renderers for:

  • allay
  • cat
  • chicken
  • creeper
  • drowned
  • enderman
  • evoker
  • fox
  • ghast
  • horse
  • husk
  • illusioner
  • iron golem
  • pig
  • piglin
  • piglin brute
  • pillager
  • skeleton
  • slime
  • spider
  • vex
  • villager
  • vindicator
  • witch
  • wolf
  • wither skeleton
  • zombie
  • zombie villager
  • zombified piglin

This list should be treated as the source of truth for the currently available built-in raw renderer classes.

When in doubt, the actual classes in that directory are more reliable than older wiki statements.

Notes

  • Custom model rendering is client-side rendering logic. It does not change server hitboxes or entity logic.
  • For variant-only rendering without custom skins, prefer withVariantTexture() or the UseVariantTexture custom-model modes.
  • For the current variant API, see API-Variant-System.
⚠️ **GitHub.com Fallback** ⚠️