User Tools

Site Tools


← Go back to the homepage

Fabric Tutorials



These pages are essential must-reads when modding with Fabric, and modding Minecraft in general, if you are new to modding, it is recommended you read the following.


Blocks and Block Entities

Data Generation

World Generation


These pages will guide you through Mojang's Brigadier library which allows you to create commands with complex arguments and actions.


These pages will guide you through using the many events included in Fabric API, and how to create your own events for you or other mods to use.



Mixins & ASM

These pages will guide you through the usage of SpongePowered's Mixin library, which is a highly complex topic. We recommend you read these pages thoroughly.



Contribute to Fabric


Model Predicate Providers


Model providers are used to dynamically change the model of items based on data from ItemStacks. A common example is the bow, which has different textures based on how long the bow has been pulled. All providers are then used in the model file for the item, in the overrides section.

Practical Example

For this example, let's say we have we have a custom bow item called EXAMPLE_BOW.

Inside a method, we register a ModelPredicateProvider with our item and an Identifier. For the Identifiers use, you do not need to provide a namespace, as none of these should conflict with Minecraft's providers. This must be done in the onInitializeClient method of your ClientModInitializer. If you do not have a ClientModInitializer, look at the entrypoints tutorial on how to add one.

  1. ModelPredicateProviderRegistry.register(EXAMPLE_BOW, new Identifier("pull"), (itemStack, clientWorld, livingEntity) -> {
  2. if (livingEntity == null) {
  3. return 0.0F;
  4. }
  5. return livingEntity.getActiveItem() != itemStack ? 0.0F : (itemStack.getMaxUseTime() - livingEntity.getItemUseTimeLeft()) / 20.0F;
  6. });
  8. ModelPredicateProviderRegistry.register(EXAMPLE_BOW, new Identifier("pulling"), (itemStack, clientWorld, livingEntity) -> {
  9. if (livingEntity == null) {
  10. return 0.0F;
  11. }
  12. return livingEntity.isUsingItem() && livingEntity.getActiveItem() == itemStack ? 1.0F : 0.0F;
  13. });

If the ModelPredicateProviderRegistry does not exist in some versions, you may use FabricModelPredicateProviderRegistry.

The ModelPredicateProvider is a Functional Interface that takes in an ItemStack for the current stack that is being rendered, a ClientWorld for the current world that the client is in, and a LivingEntity as the user of the item (In 1.17+, it also takes in an int).

All ModelPredicateProvider returns a float, which can be used to represent different states for the model, or a true/false value by returning 1.0f and 0f respectively. The float value will be clamped between 0.0f and 1.0f.

Taking a closer look at the pull predicate, we see that we first check if the entity is null, as items can be rendered outside of a context where they are being used (i.e. dropped on the ground). We then make sure that the entity is using our item, otherwise the item could have the model predicate apply when not being used. Finally, we subtract the livingEntity.getItemUseTimeLeft() from the itemStack.getMaxUseTime() which tells us how many ticks the item has been held for. Because it takes 20 ticks or one second to fully charge a bow, we then divide this number by 20.0f to normalize it to between 0f and 1.0f for the normal pull progress.

All of this is useful, but is only half of the features we need to implement in order to have our item change its model.

  1. "overrides": [
  2. {
  3. "predicate": {
  4. "pulling": 1
  5. },
  6. "model": "tutorial:item/example_bow_pulling_0"
  7. },
  8. {
  9. "predicate": {
  10. "pulling": 1,
  11. "pull": 0.65
  12. },
  13. "model": "tutorial:item/example_bow_pulling_1"
  14. },
  15. {
  16. "predicate": {
  17. "pulling": 1,
  18. "pull": 0.9
  19. },
  20. "model": "tutorial:item/example_bow_pulling_2"
  21. }
  22. ]

The way that Minecraft works is that it checks to see which model is last in the list that either matches or has values greater than specified. so with a pull value of 0.8, we would use model tutorial:item/example_bow_pulling_1. 0.5 would be tutorial:item/example_bow_pulling_0.

tutorial/model_predicate_providers.txt · Last modified: 2022/06/01 11:48 (external edit)