Custom Model Loaders
A model is simply a shape. It can be a cube, a collection of cubes, a collection of triangles, or any other geometrical shape (or collection of geometrical shape). For most contexts, it is not relevant how a model is defined, as everything will end up as a BakedModel
in memory anyway. As such, NeoForge adds the ability to register custom model loaders that can transform any model you want into a BakedModel
for the game to use.
The entry point for a block model remains the model JSON file. However, you can specify a loader
field in the root of the JSON that will swap out the default loader for your own loader. A custom model loader may ignore all fields the default loader requires.
Builtin Model Loaders
Besides the default model loader, NeoForge offers several builtin loaders, each serving a different purpose.
Composite Model
A composite model can be used to specify different model parts in the parent and only apply some of them in a child. This is best illustrated by an example. Consider the following parent model at examplemod:example_composite_model
:
{
"loader": "neoforge:composite",
// Specify model parts.
"children": {
"part_1": {
"parent": "examplemod:some_model_1"
},
"part_2": {
"parent": "examplemod:some_model_2"
}
},
"visibility": {
// Disable part 2 by default.
"part_2": false
}
}
Then, we can disable and enable individual parts in a child model of examplemod:example_composite_model
:
{
"parent": "examplemod:example_composite_model",
// Override visibility. If a part is missing, it will use the parent model's visibility value.
"visibility": {
"part_1": false,
"part_2": true
}
}
To datagen this model, use the custom loader class CompositeModelBuilder
.
Dynamic Fluid Container Model
The dynamic fluid container model, also called dynamic bucket model after its most common use case, is used for items that represent a fluid container (such as a bucket or a tank) and want to show the fluid within the model. This only works if there is a fixed amount of fluids (e.g. only lava and powder snow) that can be used, use a BlockEntityWithoutLevelRenderer
instead if the fluid is arbitrary.
{
"loader": "neoforge:fluid_container",
// Required. Must be a valid fluid id.
"fluid": "minecraft:water",
// The loader generally expects two textures: base and fluid.
"textures": {
// The base container texture, i.e. the equivalent of an empty bucket.
"base": "examplemod:item/custom_container",
// The fluid texture, i.e. the equivalent of water in a bucket.
"fluid": "examplemod:item/custom_container_fluid"
},
// Optional, defaults to false. Whether to flip the model upside down, for gaseous fluids.
"flip_gas": true,
// Optional, defaults to true. Whether to have the cover act as the mask.
"cover_is_mask": false,
// Optional, defaults to true. Whether to apply the fluid's luminosity to the item model.
"apply_fluid_luminosity": false,
}
Very often, dynamic fluid container models will directly use the bucket model. This is done by specifying the neoforge:item_bucket
parent model, like so:
{
"loader": "neoforge:fluid_container",
"parent": "neoforge:item/bucket",
// Replace with your own fluid.
"fluid": "minecraft:water"
// Optional properties here. Note that the textures are handled by the parent.
}
To datagen this model, use the custom loader class DynamicFluidContainerModelBuilder
. Be aware that for legacy support reasons, this class also provides a method to set the apply_tint
property, which is no longer used.
Elements Model
An elements model consists of block model elements and an optional root transform. Intended mainly for usage outside regular model rendering, for example within a BER.
{
"loader": "neoforge:elements",
"elements": [...],
"transform": {...}
}
Empty Model
An empty model just renders nothing at all.
{
"loader": "neoforge:empty"
}
Item Layer Model
Item layer models are a variant of the standard item/generated
model that offer the following additional features:
- Unlimited amount of layers (instead of the default 5)
- Per-layer render types
{
"loader": "neoforge:item_layers",
"textures": {
"layer0": "...",
"layer1": "...",
"layer2": "...",
"layer3": "...",
"layer4": "...",
"layer5": "...",
},
"render_types": {
// Map render types to layer numbers. For example, layers 0, 2 and 4 will use cutout.
"minecraft:cutout": [0, 2, 4],
"minecraft:cutout_mipped": [1, 3],
"minecraft:translucent": [5]
},
// other stuff the default loader allows here
}