API Variant System - MarkusBordihn/BOs-Easy-NPC GitHub Wiki
Variant System API 🎨
Easy NPC exposes its variant system for external entities and renderers.
Back to API.
Overview
The variant system stores the selected variant name in synched entity data and resolves it back to
an enum through getSkinVariantType(String name).
Relevant types:
de.markusbordihn.easynpc.api.skin.VariantTexturede.markusbordihn.easynpc.entity.easynpc.data.VariantDataCapablede.markusbordihn.easynpc.client.renderer.entity.EasyNPCEntityRenderer
Variant Enum
Implement VariantTexture on the enum:
public enum PigCompanionVariant implements VariantTexture {
WHITE("white"),
BROWN("brown"),
BLACK("black");
private final ResourceLocation textureLocation;
PigCompanionVariant(String name) {
this.textureLocation =
new ResourceLocation("yourmod", "textures/entity/pig_companion/" + name + ".png");
}
@Override
public ResourceLocation getTextureLocation() {
return textureLocation;
}
}
Entity Implementation
VariantDataCapable is parameterized with the entity type:
public class PigCompanion extends Pig
implements EasyNPC<PigCompanion>, VariantDataCapable<PigCompanion> {
@Override
public void defineSynchedData() {
super.defineSynchedData();
defineSynchedVariantData();
}
@Override
public PigCompanionVariant[] getSkinVariantTypes() {
return PigCompanionVariant.values();
}
@Override
public PigCompanionVariant getDefaultSkinVariantType() {
return PigCompanionVariant.WHITE;
}
@Override
public PigCompanionVariant getSkinVariantType(String name) {
try {
return PigCompanionVariant.valueOf(name);
} catch (IllegalArgumentException exception) {
return getDefaultSkinVariantType();
}
}
}
Renderer Implementation
Use EasyNPCEntityRenderer to reuse the built-in texture handling:
public class PigCompanionRenderer extends PigRenderer implements EasyNPCEntityRenderer {
public PigCompanionRenderer(EntityRendererProvider.Context context) {
super(context);
}
@Override
public ResourceLocation getTextureLocation(Pig entity) {
return getTextureLocationWithConfig(entity);
}
@Override
public ResourceLocation getDefaultTexture() {
return PigCompanionVariant.WHITE.getTextureLocation();
}
}
Custom Models with Variant Textures
If you combine variants with custom geometry, the useful part is usually the texture mode selection.
Example:
public class ArmoredPigRenderer extends PigRawRenderer {
public ArmoredPigRenderer(EntityRendererProvider.Context context) {
super(
context,
OriginalModelConfig.withHidden(),
CustomModelConfig.replacementUseVariantTexture(MyModModelLayers.ARMORED_PIG));
}
}
This setup:
- hides the original model
- uses a custom baked model layer
- resolves textures from the current variant only
Texture Selection Helpers
EasyNPCEntityRenderer currently provides:
getEntityTexture(easyNPC)getVariantTexture(easyNPC)getTextureByVariant(variant)getTextureLocationWithConfig(entity)
getEntityTexture(...) respects skin types such as custom and remote textures.
getVariantTexture(...) uses only the current variant texture.
Original Model Configuration
Use OriginalModelConfig when you want to change how the original model resolves its texture:
OriginalModelConfig.DEFAULT
OriginalModelConfig.withHidden()
OriginalModelConfig.withTexture(texture)
OriginalModelConfig.withVariantTexture()
OriginalModelConfig.withEntityTexture()
Custom Model Configuration
Use CustomModelConfig when you add a custom model layer:
CustomModelConfig.overlay(layer, texture)
CustomModelConfig.overlayUseEntityTexture(layer)
CustomModelConfig.overlayUseVariantTexture(layer)
CustomModelConfig.replacement(layer, texture)
CustomModelConfig.replacementUseEntityTexture(layer)
CustomModelConfig.replacementUseVariantTexture(layer)
Each of these factory methods requires a ModelLayerLocation.
Useful helpers on CustomModelConfig:
config.hasCustomModel()
config.shouldUseEntityTexture()
config.shouldUseVariantTexture()
config.shouldHideOriginal()
Sync Behavior
defineSynchedVariantData() registers the variant string in the Easy NPC synched data system.
Saved data is also written to and read from the VariantType NBT tag through:
addAdditionalVariantData(...)readAdditionalVariantData(...)
In practice this means:
- the selected variant is synced as a string
- your entity resolves that string back to an enum
- renderers can then use either full skin lookup or variant-only texture lookup
Notes
- The default built-in fallback variant is
HumanoidSkinVariant.STEVE. - Helper methods such as
hasVariantTypeCrossedArms()andhasVariantTypeSaddled()are available onVariantDataCapable. - Villager-related helpers are also exposed through
getVillagerProfession(...)andgetVillagerType(...).