Skip to content

[1.21.1] Top level NeoForge model data is passed to MultiPartBakedModel submodels #3203

@SuperMartijn642

Description

@SuperMartijn642

Bug Description

Sodium intercepts rendering of blocks to go through BlockRenderer#renderModel. BlockRenderer#renderModel then obtains the model data for the given model and stores it in AbstractBlockRenderContext#modelData. The model is then rendered through FabricBakedModel#emitBlockQuads from Forgified Fabric API.
Sodium overwrites the default implementation of FabricBakedModel#emitBlockQuads for BakedModels to redirect to AbstractBlockRenderContext#bufferDefaultModel. AbstractBlockRenderContext#bufferDefaultModel then obtains quads from the model through NeoForge's IBakedModelExtension#getQuads, passing AbstractBlockRenderContext#modelData for the model data argument.

Some models like WeightedBakedModel, MultiPartBakedModel, and NeoForge's CompositeModel consist of multiple submodels. These models collect model data for all submodels and store it in a special format which is then returned as the model data.
When #getQuads is called, these models then obtain the correct model data for each submodel and in turn call #getQuads on the submodels.

For most cases, this works fine.
However, Forgified Fabric API overwrites MultiPartBakedModel#emitQuads to directly call #emitQuads on all the submodels. The default implementation #emitQuads for these submodels then ends up calling AbstractBlockRenderContext#bufferDefaultModel. #bufferDefaultModel then calls #getQuads on the submodel with the model data from the MultiPartBakedModel model. This means each submodel gets MultiPartBakedModel's special model data rather than its own model data.

As far as I can tell MultiPartBakedModel is the only model where this goes wrong as it is the only model where Forgified Fabric API overwrites #emitQuads to directly emit the submodels.

Reproduction Steps

Create a BakedModel which overwrites NeoForge's IBakedModelExtension#getModelData and IBakedModelExtension#getQuads.
Use a multipart blockstate file for some block.
Overwrite one of the submodels of the multipart blockstate model to use the custom baked model.
Observer that the custom baked model's #getQuads receives the MultiPartBakedModel's model data rather the data from its own #getModelData.

Log File

latest.log

Crash Report

crash-2025-07-25_00.05.52-client.txt

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-modsArea: Mod compatibilityT-bugType: Bug

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions