User Tools

Site Tools


Sidebar

Setup

Basics

Advanced

Items

Blocks and Block Entities

Fluids

Entities

World Generation

Recipe Types

Miscellaneous

Events

Mixins

Dynamic Data Generation

Tutorials for Minecraft 1.15

Tutorials for Minecraft 1.14

Contribute to Fabric

Extremely Strange People

tutorial:shield

Making a Custom Shield in Minecraft [1.18-1.14]

Congrats! You just learned how to create your custom sword in the last tutorial! Now imagine you want to shield yourself from that sword if your friend got it. If you made it too op, a regular shield won't do. So we will see how to make a custom shield.
Luckily, CrimsonDawn45 has already made a library to help with this! If he didn't, you probably would be sitting here for the next hour to follow this tutorial, so thanks CrimsonDawn45!

Library source is available at https://github.com/CrimsonDawn45/Fabric-Shield-Lib

Library compiled as a jar is available at https://www.curseforge.com/minecraft/mc-mods/fabric-shield-lib

Adding the library to your project

Add the following code to the files mentioned:

gradle.properties

fabric_shield_lib_version=1.5.3-1.18


build.gradle (under dependencies)

modImplementation "com.github.CrimsonDawn45:Fabric-Shield-Lib:v${project.fabric_shield_lib_version}"


At the time of writing, latest project.fabric_shield_lib_version should be 1.5.3-1.18. This page will be updated whenever a new update comes out.

build.gradle (under repositories)

allprojects { repositories { maven { url 'https://jitpack.io' } } }


Adding a custom shield

If you want your shield to support banner decoration, there are extra steps that will be covered after the main creation.
On to the non-boring steps! We will now make a custom shield!

If you have followed the above steps correctly and refreshed the project, then you will have the fabric shield api installed.
If so, the first step to do is create a new instance of an Item like:

public static final Item NETHERITE_SHIELD = new FabricShieldItem(new FabricItemSettings().maxDamage(2500).group(ItemGroup.COMBAT), 10, 13, Items.NETHERITE_INGOT); // FabricShieldItem(settings.maxDamage(durability), cooldownTicks, enchantability, repairItem)

Then, we have to register it, like so:

Registry.register(Registry.ITEM, new Identifier("examplemod", "netherite_shield"), NETHERITE_SHIELD)

And our shield is done!
Now, we have to create the textures and models of the shield.
For the texture, you can use anything. A good place to start is looking at mojang's shield image and changing it. Put it in resources/textures/item/<filename>.png
Now, for the models, we have to write a few .json files.
For the model file without blocking, we use:

{
    "parent":"fabricshieldlib:item/fabric_shield",
    "textures":{
        "shield":"examplemod:item/netherite_shield"
    },
    "overrides": [
        {
            "predicate": {
                "blocking": 1
            },
            "model": "examplemod:item/netherite_shield_blocking"
        }
    ]
}


Put it in resources/models/item/netherite_shield.json
For the blocking model, use this:

{
  "parent": "fabricshieldlib:item/fabric_shield_blocking"
}


Plop it in resources/models/item/netherite_shield_blocking.json

Don't forget to add it to en_us.json

{
  "item.examplemod.netherite_shield": "Netherite Shield"
}


And with that, your shield is done!

Adding banner support to your shield (1.17+)

If you are using 1.17 instead of 1.18, please change the fabric_shield_lib_version in gradle.properties to:

fabric_shield_lib_version=1.4.5-1.17

This is where mixins get involved.

First thing you will want to do is to change FabricShieldItem to FabricBannerShieldItem so that it will be able to be crafted with banners.

public static final Item NETHERITE_SHIELD = new FabricBannerShieldItem(new FabricItemSettings().maxDamage(2500).group(ItemGroup.COMBAT), 10, 13, Items.NETHERITE_INGOT); // FabricBannerShieldItem(settings.maxDamage(durability), cooldownTicks, enchantability, repairItem)

Now, we have to register a few things in our ClientModInitalizer.

To create our ClientModInitalizer, we will make a new class called ExampleModClient and implement ClientModInitializer. We will also implement and override the method onInitializeClient (If you already have a client initializer, you can skip these next 2 steps.)

public class ExampleModClient implements ClientModInitializer {
    @Override
    public void onInitializeClient() {
 
    }
}

Before we do any work in our client mod initializer, we need to register its entrypoint in fabric.mod.json.

{
  [...]
  "entrypoints": {
    "main": [
      "net.fabricmc.ExampleMod"
    ],
    "client": [
      "net.fabricmc.ExampleModClient"
    ]
  }
  [...]
}

Ok, so now that is done, we can work in our client initializer.

First, we will need to create an EntityModelLayer to use later.

public class ExampleModClient implements ClientModInitializer {
 
    public static final EntityModelLayer NETHERITE_SHIELD_MODEL_LAYER = new EntityModelLayer(new Identifier("examplemod", "netherite_shield"),"main"); ​
 
    @Override
    public void onInitializeClient() {
 
    }
}

Next, we will register out EntityModelLayer that we made previously.

public class ExampleModClient implements ClientModInitializer {
 
    public static final EntityModelLayer NETHERITE_SHIELD_MODEL_LAYER = new EntityModelLayer(new Identifier("examplemod", "netherite_shield"),"main"); ​
 
    @Override
    public void onInitializeClient() {
        EntityModelLayerRegistry.registerModelLayer(NETHERITE_SHIELD_MODEL_LAYER, ShieldEntityModel::getTexturedModelData);
    }
}

Then we will register our 2 SpriteIdentifiers.

public class ExampleModClient implements ClientModInitializer {
 
    public static final EntityModelLayer NETHERITE_SHIELD_MODEL_LAYER = new EntityModelLayer(new Identifier("examplemod", "netherite_shield"),"main"); ​
 
    @Override
    public void onInitializeClient() {
        EntityModelLayerRegistry.registerModelLayer(NETHERITE_SHIELD_MODEL_LAYER, ShieldEntityModel::getTexturedModelData);
        ClientSpriteRegistryCallback.event(SpriteAtlasTexture.BLOCK_ATLAS_TEXTURE).register((atlasTexture, registry) -> {
            registry.register(new Identifier("examplemod", "entity/netherite_shield_base"));
            registry.register(new Identifier("examplemod", "entity/netherite_shield_base_nopattern"));
        });
    }
}

And now we get to the mixin. Don't worry, its an easy one.

If this is your first time, here's how to register mixins on your fabric.mod.json (Make sure to make a client mixin)

We will make a class called RendererMixin and write:

@Mixin (BuiltinModelItemRenderer.class)
public class RendererMixin {
 
}

Then we will make the necessary Spriteidentifiers and a ShieldEntityModel. The Spriteidentifiers will be the same as in your ClientModInitializer.

@Mixin (BuiltinModelItemRenderer.class)
public class RendererMixin {
    private ShieldEntityModel modelNetheriteShield;
    private static final SpriteIdentifier NETHERITE_SHIELD_BASE = new SpriteIdentifier(SpriteAtlasTexture.BLOCK_ATLAS_TEXTURE, new Identifier("examplemod","entity/netherite_shield_base"));
    private static final SpriteIdentifier NETHERITE_SHIELD_BASE_NO_PATTERN = new SpriteIdentifier(SpriteAtlasTexture.BLOCK_ATLAS_TEXTURE, new Identifier("examplemod","entity/netherite_shield_base_nopattern"));
}

Next, we need to @Shadow the entityModelLoader so that we can use it to initialize our model.

@Mixin (BuiltinModelItemRenderer.class)
public class RendererMixin {
    private ShieldEntityModel modelNetheriteShield;
    private static final SpriteIdentifier NETHERITE_SHIELD_BASE = new SpriteIdentifier(SpriteAtlasTexture.BLOCK_ATLAS_TEXTURE, new Identifier("examplemod","entity/netherite_shield_base"));
    private static final SpriteIdentifier NETHERITE_SHIELD_BASE_NO_PATTERN = new SpriteIdentifier(SpriteAtlasTexture.BLOCK_ATLAS_TEXTURE, new Identifier("examplemod","entity/netherite_shield_base_nopattern"));
 
    @Final
    @Shadow
    private EntityModelLoader entityModelLoader;
}    

Now we will inject into the reload method to initialize our model.

@Mixin (BuiltinModelItemRenderer.class)
public class RendererMixin {
   private ShieldEntityModel modelNetheriteShield;
    private static final SpriteIdentifier NETHERITE_SHIELD_BASE = new SpriteIdentifier(SpriteAtlasTexture.BLOCK_ATLAS_TEXTURE, new Identifier("examplemod","entity/netherite_shield_base"));
    private static final SpriteIdentifier NETHERITE_SHIELD_BASE_NO_PATTERN = new SpriteIdentifier(SpriteAtlasTexture.BLOCK_ATLAS_TEXTURE, new Identifier("examplemod","entity/netherite_shield_base_nopattern"));
 
    @Final
    @Shadow
    private EntityModelLoader entityModelLoader;
 
 
    @Inject(method = "reload", at = @At("HEAD"))
    private void setModelNetheriteShield(CallbackInfo ci){
        modelNetheriteShield = new ShieldEntityModel(this.entityModelLoader.getModelPart(ExampleModClient.NETHERITE_SHIELD_MODEL_LAYER));
    }
}

Now we get to the most important part of the mixin. We will inject a method to render a banner on our shield.

@Mixin (BuiltinModelItemRenderer.class)
public class RendererMixin {
   private ShieldEntityModel modelNetheriteShield;
    private static final SpriteIdentifier NETHERITE_SHIELD_BASE = new SpriteIdentifier(SpriteAtlasTexture.BLOCK_ATLAS_TEXTURE, new Identifier("examplemod","entity/netherite_shield_base"));
    private static final SpriteIdentifier NETHERITE_SHIELD_BASE_NO_PATTERN = new SpriteIdentifier(SpriteAtlasTexture.BLOCK_ATLAS_TEXTURE, new Identifier("examplemod","entity/netherite_shield_base_nopattern"));
 
    @Final
    @Shadow
    private EntityModelLoader entityModelLoader;
 
 
    @Inject(method = "reload", at = @At("HEAD"))
    private void setModelNetheriteShield(CallbackInfo ci){
        this.modelNetheriteShield = new ShieldEntityModel(this.entityModelLoader.getModelPart(ExampleModClient.NETHERITE_SHIELD_MODEL_LAYER));
    }
 
    @Inject(method = "render", at = @At("HEAD"))
    private void mainRender(ItemStack stack, ModelTransformation.Mode mode, MatrixStack matrices, VertexConsumerProvider vertexConsumers, int light, int overlay, CallbackInfo ci) {
        if (stack.isOf(ExampleMod.NETHERITE_SHIELD)) {
            FabricShieldLibClient.renderBanner(stack, matrices, vertexConsumers, light, overlay, modelNetheriteShield, NETHERITE_SHIELD_BASE, NETHERITE_SHIELD_BASE_NO_PATTERN); 
            //The first five parameters are taken from the method, while the last 3 you provide yourself. You will provide the model, and then your 2 sprite identifiers in the order of ''//SHIELD_NAME//_BASE'' and then ''//SHIELD_NAME//_BASE_NOPATTERN.
''
        }
    }
 
 
}

That is now all of the complicated things done! We now only need to change our existing model, add a nopattern texture, and move our textures to the locations we identified earlier.

In your shield model, netherite_shield.json for us, we need to change the parent and remove the texture.

{
  "parent":"fabricshieldlib:item/fabric_banner_shield",
    "overrides": [
        {
            "predicate": {
                "blocking": 1
            },
            "model": "examplemod:item/netherite_shield_blocking"
        }
    ]
}

You also have to change your blocking model for your shield, netherite_shield_blocking.json for us, to:

{
  "parent":"fabricshieldlib:item/fabric_banner_shield_blocking"
}

For this next step, you will add _base to your current shield texture, so netherite_shield to netherite_shield_base. Then, you will need to make a nopattern version for your shield texture, so netherite_shield_base_nopattern. I recommend looking at the vanilla shield's nopattern texture.

Then, you will move both of these textures into resources/assets/<modid>/textures/entity.

For one last thing, you will need to add names for each of your shield color variants in en_us.json.

{
    "item.examplemod.netherite_shield": "Netherite Shield",
    "item.examplemod.netherite_shield.red": "Red Netherite Shield",
    "item.examplemod.netherite_shield.orange": "Orange Netherite Shield",
    "item.examplemod.netherite_shield.yellow": "Yellow Netherite Shield",
    "item.examplemod.netherite_shield.lime": "Lime Netherite Shield",
    "item.examplemod.netherite_shield.green": "Green Netherite Shield",
    "item.examplemod.netherite_shield.light_blue": "Light Blue Netherite Shield",
    "item.examplemod.netherite_shield.cyan": "Cyan Netherite Shield",
    "item.examplemod.netherite_shield.blue": "Blue Netherite Shield",
    "item.examplemod.netherite_shield.purple": "Purple Netherite Shield",
    "item.examplemod.netherite_shield.magenta": "Magenta Netherite Shield",
    "item.examplemod.netherite_shield.pink": "Pink Netherite Shield",
    "item.examplemod.netherite_shield.brown": "Brown Netherite Shield",
    "item.examplemod.netherite_shield.white": "White Netherite Shield",
    "item.examplemod.netherite_shield.light_gray": "Light Gray Netherite Shield",
    "item.examplemod.netherite_shield.gray": "Gray Netherite Shield",
    "item.examplemod.netherite_shield.dark_gray": "Dark Gray Netherite Shield",
    "item.examplemod.netherite_shield.black": "Black Netherite Shield"
}

Adding banner support to your shield (1.16)

This is where mixins get involved.

First, change the fabric_shield_lib in gradle.properties

fabric_shield_lib_version=1.4.5-1.16


Next thing you will want to do is to change FabricShieldItem to FabricBannerShieldItem so that it will be able to be crafted with banners.

public static final Item NETHERITE_SHIELD = new FabricBannerShieldItem(new FabricItemSettings().maxDamage(2500).group(ItemGroup.COMBAT), 10, 13, Items.NETHERITE_INGOT); // FabricBannerShieldItem(settings.maxDamage(durability), cooldownTicks, enchantability, repairItem)

Now, we have to register a few things in our ClientModInitalizer.

To create our ClientModInitalizer, we will make a new class called ExampleModClient and implement ClientModInitializer. We will also implement and override the method onInitializeClient (If you already have a client initializer, you can skip these next 2 steps.)

public class ExampleModClient implements ClientModInitializer {
    @Override
    public void onInitializeClient() {
 
    }
}

Before we do any work in our client mod initializer, we need to register its entrypoint in fabric.mod.json.

{
  [...]
  "entrypoints": {
    "main": [
      "net.fabricmc.ExampleMod"
    ],
    "client": [
      "net.fabricmc.ExampleModClient"
    ]
  }
  [...]
}

Ok, so now that is done, we can work in our client initializer.

The only thing that we will need to do is register our 2 SpriteIdentifiers.

public class ExampleModClient implements ClientModInitializer {
 
    @Override
    public void onInitializeClient() {
        ClientSpriteRegistryCallback.event(SpriteAtlasTexture.BLOCK_ATLAS_TEXTURE).register((atlasTexture, registry) -> {
            registry.register(new Identifier("examplemod", "entity/netherite_shield_base"));
            registry.register(new Identifier("examplemod", "entity/netherite_shield_base_nopattern"));
        });
    }
}

And now we get to the mixin. Don't worry, its an easy one.

If this is your first time, here's how to register mixins on your fabric.mod.json (Make sure to make a client mixin)

We will make a class called RendererMixin and write:

@Mixin (BuiltinModelItemRenderer.class)
public class RendererMixin {
 
}

Then we will make the necessary Spriteidentifiers and a ShieldEntityModel. The Spriteidentifiers will be the same as in your ClientModInitializer.

@Mixin (BuiltinModelItemRenderer.class)
public class RendererMixin {
    private ShieldEntityModel modelNetheriteShield = new ShieldEntityModel;
    private static final SpriteIdentifier NETHERITE_SHIELD_BASE = new SpriteIdentifier(SpriteAtlasTexture.BLOCK_ATLAS_TEXTURE, new Identifier("examplemod","entity/netherite_shield_base"));
    private static final SpriteIdentifier NETHERITE_SHIELD_BASE_NO_PATTERN = new SpriteIdentifier(SpriteAtlasTexture.BLOCK_ATLAS_TEXTURE, new Identifier("examplemod","entity/netherite_shield_base_nopattern"));
}

Now we get to the most important part of the mixin. We will inject a method to render a banner on our shield.

@Mixin (BuiltinModelItemRenderer.class)
public class RendererMixin {
    private ShieldEntityModel modelNetheriteShield = new ShieldEntityModel;
    private static final SpriteIdentifier NETHERITE_SHIELD_BASE = new SpriteIdentifier(SpriteAtlasTexture.BLOCK_ATLAS_TEXTURE, new Identifier("examplemod","entity/netherite_shield_base"));
    private static final SpriteIdentifier NETHERITE_SHIELD_BASE_NO_PATTERN = new SpriteIdentifier(SpriteAtlasTexture.BLOCK_ATLAS_TEXTURE, new Identifier("examplemod","entity/netherite_shield_base_nopattern"));
 
    @Inject(method = "render", at = @At("HEAD"))
    private void mainRender(ItemStack stack, MatrixStack matrix, VertexConsumerProvider vertexConsumerProvider, int light, int overlay, CallbackInfo ci) {
        if (stack.getItem() == ExampleMod.NETHERITE_SHIELD)) {
            FabricShieldLibClient.renderBanner(stack, matrix, vertexConsumerProvider, light, overlay, modelFabricShield, NETHERITE_SHIELD_BASE, NETHERITE_SHIELD_BASE_NO_PATTERN); 
            //The first five parameters are taken from the method, while the last 3 you provide yourself. You will provide the model, and then your 2 sprite identifiers in the order of ''//SHIELD_NAME//_BASE'' and then ''//SHIELD_NAME//_BASE_NOPATTERN.
''
        }
    }
 
 
}

That is now all of the complicated things done! We now only need to change our existing model, add a nopattern texture, and move our textures to the locations we identified earlier.

In your shield model, netherite_shield.json for us, we need to change the parent and remove the texture.

{
  "parent":"fabricshieldlib:item/fabric_banner_shield",
    "overrides": [
        {
            "predicate": {
                "blocking": 1
            },
            "model": "examplemod:item/netherite_shield_blocking"
        }
    ]
}

You also have to change your blocking model for your shield, netherite_shield_blocking.json for us, to:

{
  "parent":"fabricshieldlib:item/fabric_banner_shield_blocking"
}

For this next step, you will add _base to your current shield texture, so netherite_shield to netherite_shield_base. Then, you will need to make a nopattern version for your shield texture, so netherite_shield_base_nopattern. I recommend looking at the vanilla shield's nopattern texture.

Then, you will move both of these textures into resources/assets/<modid>/textures/entity.

For one last thing, you will need to add names for each of your shield color variants in en_us.json.

{
    "item.examplemod.netherite_shield": "Netherite Shield",
    "item.examplemod.netherite_shield.red": "Red Netherite Shield",
    "item.examplemod.netherite_shield.orange": "Orange Netherite Shield",
    "item.examplemod.netherite_shield.yellow": "Yellow Netherite Shield",
    "item.examplemod.netherite_shield.lime": "Lime Netherite Shield",
    "item.examplemod.netherite_shield.green": "Green Netherite Shield",
    "item.examplemod.netherite_shield.light_blue": "Light Blue Netherite Shield",
    "item.examplemod.netherite_shield.cyan": "Cyan Netherite Shield",
    "item.examplemod.netherite_shield.blue": "Blue Netherite Shield",
    "item.examplemod.netherite_shield.purple": "Purple Netherite Shield",
    "item.examplemod.netherite_shield.magenta": "Magenta Netherite Shield",
    "item.examplemod.netherite_shield.pink": "Pink Netherite Shield",
    "item.examplemod.netherite_shield.brown": "Brown Netherite Shield",
    "item.examplemod.netherite_shield.white": "White Netherite Shield",
    "item.examplemod.netherite_shield.light_gray": "Light Gray Netherite Shield",
    "item.examplemod.netherite_shield.gray": "Gray Netherite Shield",
    "item.examplemod.netherite_shield.dark_gray": "Dark Gray Netherite Shield",
    "item.examplemod.netherite_shield.black": "Black Netherite Shield"
}

Adding banner support to your shield (1.15)

This is where mixins get involved.

First, change the fabric_shield_lib in gradle.properties

fabric_shield_lib_version=1.4.5-1.15


Next thing you will want to do is to change FabricShieldItem to FabricBannerShieldItem so that it will be able to be crafted with banners.

public static final Item NETHERITE_SHIELD = new FabricBannerShieldItem(new FabricItemSettings().maxDamage(2500).group(ItemGroup.COMBAT), 10, 13, Items.NETHERITE_INGOT); // FabricBannerShieldItem(settings.maxDamage(durability), cooldownTicks, enchantability, repairItem)

Now, we have to register a few things in our ClientModInitalizer.

To create our ClientModInitalizer, we will make a new class called ExampleModClient and implement ClientModInitializer. We will also implement and override the method onInitializeClient (If you already have a client initializer, you can skip these next 2 steps.)

public class ExampleModClient implements ClientModInitializer {
    @Override
    public void onInitializeClient() {
 
    }
}

Before we do any work in our client mod initializer, we need to register its entrypoint in fabric.mod.json.

{
  [...]
  "entrypoints": {
    "main": [
      "net.fabricmc.ExampleMod"
    ],
    "client": [
      "net.fabricmc.ExampleModClient"
    ]
  }
  [...]
}

Ok, so now that is done, we can work in our client initializer.

The only thing that we will need to do is register our 2 SpriteIdentifiers.

public class ExampleModClient implements ClientModInitializer {
 
    @Override
    public void onInitializeClient() {
        ClientSpriteRegistryCallback.event(SpriteAtlasTexture.BLOCK_ATLAS_TEX).register((atlasTexture, registry) -> {
            registry.register(new Identifier("examplemod", "entity/netherite_shield_base"));
            registry.register(new Identifier("examplemod", "entity/netherite_shield_base_nopattern"));
        });
    }
}

And now we get to the mixin. Don't worry, its an easy one.

If this is your first time, here's how to register mixins on your fabric.mod.json (Make sure to make a client mixin)

We will make a class called RendererMixin and write:

@Mixin (BuiltinModelItemRenderer.class)
public class RendererMixin {
 
}

Then we will make the necessary Spriteidentifiers and a ShieldEntityModel. The Spriteidentifiers will be the same as in your ClientModInitializer.

@Mixin (BuiltinModelItemRenderer.class)
public class RendererMixin {
    private ShieldEntityModel modelNetheriteShield = new ShieldEntityModel;
    private static final SpriteIdentifier NETHERITE_SHIELD_BASE = new SpriteIdentifier(SpriteAtlasTexture.BLOCK_ATLAS_TEX, new Identifier("examplemod","entity/netherite_shield_base"));
    private static final SpriteIdentifier NETHERITE_SHIELD_BASE_NO_PATTERN = new SpriteIdentifier(SpriteAtlasTexture.BLOCK_ATLAS_TEX, new Identifier("examplemod","entity/netherite_shield_base_nopattern"));
}

Now we get to the most important part of the mixin. We will inject a method to render a banner on our shield.

@Mixin (BuiltinModelItemRenderer.class)
public class RendererMixin {
    private ShieldEntityModel modelNetheriteShield = new ShieldEntityModel;
    private static final SpriteIdentifier NETHERITE_SHIELD_BASE = new SpriteIdentifier(SpriteAtlasTexture.BLOCK_ATLAS_TEX, new Identifier("examplemod","entity/netherite_shield_base"));
    private static final SpriteIdentifier NETHERITE_SHIELD_BASE_NO_PATTERN = new SpriteIdentifier(SpriteAtlasTexture.BLOCK_ATLAS_TEX, new Identifier("examplemod","entity/netherite_shield_base_nopattern"));
 
    @Inject(method = "render", at = @At("HEAD"))
    private void mainRender(ItemStack stack, ModelTransformation.Mode mode, MatrixStack matrices, VertexConsumerProvider vertexConsumers, int light, int overlay, CallbackInfo ci) {
        if (stack.getItem() == ExampleMod.NETHERITE_SHIELD)) {
            FabricShieldLibClient.renderBanner(stack, matrices, vertexConsumers, light, overlay, modelNetheriteShield, NETHERITE_SHIELD_BASE, NETHERITE_SHIELD_BASE_NO_PATTERN); 
            //The first five parameters are taken from the method, while the last 3 you provide yourself. You will provide the model, and then your 2 sprite identifiers in the order of ''//SHIELD_NAME//_BASE'' and then ''//SHIELD_NAME//_BASE_NOPATTERN.
''
        }
    }
 
 
}

That is now all of the complicated things done! We now only need to change our existing model, add a nopattern texture, and move our textures to the locations we identified earlier.

In your shield model, netherite_shield.json for us, we need to change the parent and remove the texture.

{
  "parent":"fabricshieldlib:item/fabric_banner_shield",
    "overrides": [
        {
            "predicate": {
                "blocking": 1
            },
            "model": "examplemod:item/netherite_shield_blocking"
        }
    ]
}

You also have to change your blocking model for your shield, netherite_shield_blocking.json for us, to:

{
  "parent":"fabricshieldlib:item/fabric_banner_shield_blocking"
}

For this next step, you will add _base to your current shield texture, so netherite_shield to netherite_shield_base. Then, you will need to make a nopattern version for your shield texture, so netherite_shield_base_nopattern. I recommend looking at the vanilla shield's nopattern texture.

Then, you will move both of these textures into resources/assets/<modid>/textures/entity.

For one last thing, you will need to add names for each of your shield color variants in en_us.json.

{
    "item.examplemod.netherite_shield": "Netherite Shield",
    "item.examplemod.netherite_shield.red": "Red Netherite Shield",
    "item.examplemod.netherite_shield.orange": "Orange Netherite Shield",
    "item.examplemod.netherite_shield.yellow": "Yellow Netherite Shield",
    "item.examplemod.netherite_shield.lime": "Lime Netherite Shield",
    "item.examplemod.netherite_shield.green": "Green Netherite Shield",
    "item.examplemod.netherite_shield.light_blue": "Light Blue Netherite Shield",
    "item.examplemod.netherite_shield.cyan": "Cyan Netherite Shield",
    "item.examplemod.netherite_shield.blue": "Blue Netherite Shield",
    "item.examplemod.netherite_shield.purple": "Purple Netherite Shield",
    "item.examplemod.netherite_shield.magenta": "Magenta Netherite Shield",
    "item.examplemod.netherite_shield.pink": "Pink Netherite Shield",
    "item.examplemod.netherite_shield.brown": "Brown Netherite Shield",
    "item.examplemod.netherite_shield.white": "White Netherite Shield",
    "item.examplemod.netherite_shield.light_gray": "Light Gray Netherite Shield",
    "item.examplemod.netherite_shield.gray": "Gray Netherite Shield",
    "item.examplemod.netherite_shield.dark_gray": "Dark Gray Netherite Shield",
    "item.examplemod.netherite_shield.black": "Black Netherite Shield"
}

Adding banner support to your shield (1.14)

This is where mixins get involved.

First, change the fabric_shield_lib in gradle.properties

fabric_shield_lib_version=1.4.5-1.14


Next thing you will want to do is to change FabricShieldItem to FabricBannerShieldItem so that it will be able to be crafted with banners.

public static final Item NETHERITE_SHIELD = new FabricBannerShieldItem(new FabricItemSettings().maxDamage(2500).group(ItemGroup.COMBAT), 10, 13, Items.NETHERITE_INGOT); // FabricBannerShieldItem(settings.maxDamage(durability), cooldownTicks, enchantability, repairItem)

The only thing we will need to do now is to add a simple mixin.

If this is your first time, here's how to register mixins on your fabric.mod.json (Make sure to make a client mixin)

We will make a class called RendererMixin and write:

@Mixin (BuiltinModelItemRenderer.class)
public class RendererMixin {
 
}

Then we will make the necessary Identifiers. They will be the path to your textures and the second one will have an additional _nopattern added to the file name.

@Mixin (BuiltinModelItemRenderer.class)
public class RendererMixin {
    private static final Identifier NETHERITE_SHIELD_BASE = new Identifier("examplemod","entity/netherite_shield_base");
    private static final Identifier NETHERITE_SHIELD_BASE_NO_PATTERN = new Identifier("examplemod","entity/netherite_shield_base_nopattern");
}

Now we get to the most important part of the mixin. We will inject a method to render a banner on our shield. Do not forget to mark the inject with cancellable = true

@Mixin (BuiltinModelItemRenderer.class)
public class RendererMixin {
    private static final Identifier NETHERITE_SHIELD_BASE = new Identifier("examplemod","entity/netherite_shield_base");
    private static final Identifier NETHERITE_SHIELD_BASE_NO_PATTERN = new Identifier("examplemod","entity/netherite_shield_base_nopattern");
 
    @Inject(method = "render", at = @At("HEAD"), cancellable = true)
    private void mainRender(ItemStack stack, CallbackInfo callbackInfo) {
        if (stack.getItem() == ExampleMod.NETHERITE_SHIELD)) {
            //The first parameter is taken from the method, while you will provide your 2 identifiers in the order of ''//SHIELD_NAME//_BASE_NOPATTERN'' and then ''//SHIELD_NAME//_BASE''.
            FabricShieldBannerRendering.render(stack, NETHERITE_SHIELD_BASE_NO_PATTERN, NETHERITE_SHIELD_BASE);
            callbackInfo.cancel();
        }
    }
 
 
}

That is now all of the complicated things done! We now only need to change our existing model, add a nopattern texture, and move our textures to the locations we identified earlier.

In your shield model, netherite_shield.json for us, we need to change the parent and remove the texture.

{
  "parent":"fabricshieldlib:item/fabric_banner_shield",
    "overrides": [
        {
            "predicate": {
                "blocking": 1
            },
            "model": "examplemod:item/netherite_shield_blocking"
        }
    ]
}

You also have to change your blocking model for your shield, netherite_shield_blocking.json for us, to:

{
  "parent":"fabricshieldlib:item/fabric_banner_shield_blocking"
}

For this next step, you will add _base to your current shield texture, so netherite_shield to netherite_shield_base. Then, you will need to make a nopattern version for your shield texture, so netherite_shield_base_nopattern. I recommend looking at the vanilla shield's nopattern texture.

Then, you will move both of these textures into resources/assets/<modid>/textures/entity.

For one last thing, you will need to add names for each of your shield color variants in en_us.json.

{
    "item.examplemod.netherite_shield": "Netherite Shield",
    "item.examplemod.netherite_shield.red": "Red Netherite Shield",
    "item.examplemod.netherite_shield.orange": "Orange Netherite Shield",
    "item.examplemod.netherite_shield.yellow": "Yellow Netherite Shield",
    "item.examplemod.netherite_shield.lime": "Lime Netherite Shield",
    "item.examplemod.netherite_shield.green": "Green Netherite Shield",
    "item.examplemod.netherite_shield.light_blue": "Light Blue Netherite Shield",
    "item.examplemod.netherite_shield.cyan": "Cyan Netherite Shield",
    "item.examplemod.netherite_shield.blue": "Blue Netherite Shield",
    "item.examplemod.netherite_shield.purple": "Purple Netherite Shield",
    "item.examplemod.netherite_shield.magenta": "Magenta Netherite Shield",
    "item.examplemod.netherite_shield.pink": "Pink Netherite Shield",
    "item.examplemod.netherite_shield.brown": "Brown Netherite Shield",
    "item.examplemod.netherite_shield.white": "White Netherite Shield",
    "item.examplemod.netherite_shield.light_gray": "Light Gray Netherite Shield",
    "item.examplemod.netherite_shield.gray": "Gray Netherite Shield",
    "item.examplemod.netherite_shield.dark_gray": "Dark Gray Netherite Shield",
    "item.examplemod.netherite_shield.black": "Black Netherite Shield"
}

Now your shield is done and has banner support!

tutorial/shield.txt · Last modified: 2022/03/26 19:43 by furnygo