Skip to content

Custom Models

MehVahdJukaar edited this page Jul 25, 2026 · 1 revision

Custom Models

Cross loader custom baked models, model loaders and per block model data.

Forge and Fabric have completely different model APIs. CustomBakedModel is one interface that works on both: you return quads for a state, a direction and a render type, and you get extra model data so a block entity can feed information into its own model.

CustomModelLoader registers a json loader for your own model format, and NestedModelLoader lets your format contain other models.

Getting Started

Register the loader on client init:

ClientHelper.addModelLoaderRegistration(event ->
        event.register(MyMod.res("custom_loader"), new MyModelLoader()));
public class MyModelLoader implements CustomModelLoader {
    @Override
    public CustomGeometry deserialize(JsonObject json, JsonDeserializationContext context) {
        JsonElement inner = json.get("inner_model");
        boolean translated = json.get("is_translated").getAsBoolean();

        return (modelBaker, spriteGetter, transform) -> {
            var innerModel = CustomModelLoader.parseModel(inner, modelBaker, spriteGetter, transform);
            return new MyBakedModel(innerModel, translated, transform);
        };
    }
}

The model itself:

@Override
public List<BakedQuad> getBlockQuads(BlockState state, Direction dir, RandomSource random,
                                     RenderType renderType, ExtraModelData data) {
    List<BakedQuad> quads = new ArrayList<>();

    // per render type, so one model can draw into several layers
    if (renderType == RenderType.translucent()) {
        quads.add(...);
    }

    // data pushed in by the block entity
    Block mimic = data.get(MIMIC_BLOCK_KEY);
    if (mimic != null) {
        quads.addAll(Minecraft.getInstance().getBlockRenderer()
                .getBlockModel(mimic.defaultBlockState())
                .getQuads(mimic.defaultBlockState(), dir, random));
    }
    return quads;
}

To feed data in, implement IExtraModelDataProvider on the block entity and declare a ModelDataKey for each value.

Building and editing quads is BakedQuadBuilder and BakedQuadsTransformer.

Examples: CustomModelLoaderExample, QuadUtilsExample

Clone this wiki locally