User Tools

Site Tools


tutorial:shield

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revisionPrevious revision
Next revision
Previous revision
tutorial:shield [2024/07/03 07:08] solidblocktutorial:shield [2025/06/21 18:39] (current) – updated to 1.21.4 cringestar_boi
Line 1: Line 1:
-====== Making a Custom Shield in Minecraft [1.19-1.20] ======+====== Making a Custom Shield in Minecraft [1.19-1.21.4] ======
 :!: The tutorial depends on third-party libraries. :!: The tutorial depends on third-party libraries.
  
 Congrats! You just learned how to create your custom tools 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. Congrats! You just learned how to create your custom tools 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, StellarWind22 has already made a library to help with this! If she didn't, you probably would be sitting here for the next hour following this tutorial, so thanks StellarWind22!+Luckily, StellarWind22 has already made a library to help with this! If she didn't, you probably would be sitting here for the next hour following this tutorial, so thanksStellarWind22!
  
-The library source is available at https://github.com/CrimsonDawn45/Fabric-Shield-Lib+The library source is available at https://github.com/StellarWind22/Fabric-Shield-Lib
  
 Library compiled as a jar is available at https://www.curseforge.com/minecraft/mc-mods/fabric-shield-lib Library compiled as a jar is available at https://www.curseforge.com/minecraft/mc-mods/fabric-shield-lib
Line 16: Line 16:
 **gradle.properties** **gradle.properties**
 <file properties gradle.properties> <file properties gradle.properties>
-fabric_shield_lib_version=1.7.2-1.20.4 +fabric_shield_lib_version=1.8.0-1.21.4 
-midnightlib_version=1.5.2-fabric +mod_menu_version=13.0.0 
-mod_menu_version=9.0.0-pre.1+midnightlib_version=1.6.6-fabric
 fabricasm_version=2.3 fabricasm_version=2.3
 </file> </file>
Line 24: Line 24:
 **build.gradle** (under ''dependencies'' block)  **build.gradle** (under ''dependencies'' block) 
 <file groovy build.gradle> <file groovy build.gradle>
- modImplementation "com.github.CrimsonDawn45:Fabric-Shield-Lib:v${project.fabric_shield_lib_version}"+ modImplementation "com.github.StellarWind:Fabric-Shield-Lib:v${project.fabric_shield_lib_version}"
  modImplementation "com.terraformersmc:modmenu:${project.mod_menu_version}"  modImplementation "com.terraformersmc:modmenu:${project.mod_menu_version}"
  modImplementation "maven.modrinth:midnightlib:${project.midnightlib_version}"  modImplementation "maven.modrinth:midnightlib:${project.midnightlib_version}"
Line 30: Line 30:
 </file> </file>
  
-At the time of writing, the latest project.fabric_shield_lib_version should be 1.7.2, which supports versions:+At the time of writing, these are the most up-to-date FabricShieldLib versions: 
 +  * **1.21.4** (''1.8.0-1.21.4''
 +  * **1.21.2** - **1.21.3** (''1.8.0-pre1-1.21.3''
 +  * **1.21** - **1.21.1** (''1.7.2-1.21.1''
 +  * **1.20.5** - **1.20.6** (''1.7.2-1.20.6'')
   * **1.20.2** - **1.20.4** (''1.7.2-1.20.4'')   * **1.20.2** - **1.20.4** (''1.7.2-1.20.4'')
   * **1.20** - **1.20.1** (''1.7.2-1.20.1'')   * **1.20** - **1.20.1** (''1.7.2-1.20.1'')
Line 53: Line 57:
 If you have followed the above steps correctly and refreshed the project, then you will have the FabricShieldLib installed. If you have followed the above steps correctly and refreshed the project, then you will have the FabricShieldLib installed.
  
-If so, the first step to do is create a new instance of an ''Item'' (see [[items]] tutorial), like:+If so, the first step to do is create a new instance of an ''Item'' (see [[https://docs.fabricmc.net/develop/items/first-item|items]] tutorial), like:
 <code java TutorialItems> <code java TutorialItems>
 public final class TutorialItems { public final class TutorialItems {
     // ...     // ...
-    public static final Item NETHERITE_SHIELD = register(new FabricShieldItem(new FabricItemSettings().maxDamage(2500), 10, 13, Items.NETHERITE_INGOT), "netherite_shield");+    public static final Item NETHERITE_SHIELD = register("netherite_shield", settings -> new FabricShieldItem(settings,10, 13, Items.NETHERITE_INGOT), new Item.Settings().maxDamage(2500)); 
 +    //The constructor for the item takes in the following values: FabricBannerShieldItem(settings.maxDamage(durability), cooldownTicks, enchantability, repairItems)
     // ...     // ...
 } }
Line 66: Line 71:
 <yarncode java ExampleMod> <yarncode java ExampleMod>
 public class ExampleMod implements ModInitializer { public class ExampleMod implements ModInitializer {
 +    ...
     @Override     @Override
     public void onInitialize() {     public void onInitialize() {
 +        ...
         ItemGroupEvents.modifyEntriesEvent(ItemGroups.COMBAT).register(entries -> {         ItemGroupEvents.modifyEntriesEvent(ItemGroups.COMBAT).register(entries -> {
             entries.add(NETHERITE_SHIELD);             entries.add(NETHERITE_SHIELD);
         });         });
 +        ...
     }     }
 +    ...
 } }
 </yarncode> </yarncode>
Line 87: Line 96:
 <file javascript resources/assets/tutorial/models/item/netherite_shield.json> <file javascript resources/assets/tutorial/models/item/netherite_shield.json>
 { {
-    "parent":"fabricshieldlib:item/fabric_shield", +  "parent":"fabricshieldlib:item/fabric_shield", 
-    "textures":+  "textures":
-        "shield":"tutorial:item/netherite_shield" +    "shield":"tutorial:item/netherite_shield" 
-    }+  }
-    "overrides":+
-        { +
-            "predicate":+
-                "blocking":+
-            }, +
-            "model": "tutorial:item/netherite_shield_blocking" +
-        } +
-    ]+
 } }
 </file>  </file> 
Line 112: Line 113:
 </file> </file>
  
-Lastly, as a [[tags|conventional tag]], create a ''shields.json'' file in ''resources/data/c/tags/item/shields.json'' (since 1.21) or ''resources/data/c/tags/items/shields.json'' (befire 1.21) and add your shield to it: +Then, as a [[tags|conventional tag]], create a ''shield.json'' file in ''resources/data/c/tags/item/tools/shield.json'' and add your shield to it: 
-<code javascript resources/data/c/tags/items/shields.json>+<code javascript resources/data/c/tags/item/shields.json
 +
 +  "replace": false, 
 +  "values":
 +    "tutorial:netherite_shield" 
 +  ] 
 +
 +</code> 
 + 
 +Lastly, to make it enchantable, create a ''durability.json'' file in ''resources/data/minecraft/tags/item/enchantable/durability.json'' and add your shield to it: 
 +<code javascript resources/data/minecraft/tags/item/enchantable/durability.json>
 { {
   "replace": false,   "replace": false,
Line 135: Line 146:
 We still make the item in the same way, just make it a ''FabricBannerShieldItem'': We still make the item in the same way, just make it a ''FabricBannerShieldItem'':
 <code java TutorialItems> <code java TutorialItems>
-    public static final Item NETHERITE_BANNER_SHIELD = register(new FabricBannerShieldItem(new FabricItemSettings().maxDamage(2500), 10, 13, Items.NETHERITE_INGOT), "netherite_banner_shield");+ public static final Item NETHERITE_BANNER_SHIELD = register("netherite_banner_shield", settings -> new FabricBannerShieldItem(settings, 10, 13, Items.NETHERITE_INGOT), new Item.Settings().maxDamage(2500));
 </code> </code>
- +If you want to add your shield to a [[itemgroup|item groups]], for example, the "Combat" group, use:   
-If you want to add your shield to a [[itemgroup|item groups]], for example, the "Combat" group, use: +  
- +<yarncode java ExampleMod>   
-<yarncode java ExampleMod> +public class ExampleMod implements ModInitializer {   
-public class ExampleMod implements ModInitializer { +    @Override   
-    @Override +    public void onInitialize() {   
-    public void onInitialize() { +        ItemGroupEvents.modifyEntriesEvent(ItemGroups.COMBAT).register(entries -> {   
-        ItemGroupEvents.modifyEntriesEvent(ItemGroups.COMBAT).register(entries -> { +            // ...   
-            // ... +            entries.add(NETHERITE_BANNER_SHIELD);   
-            entries.add(NETHERITE_BANNER_SHIELD); +        });   
-        }); +    }   
-    } +}  
-}+
 </yarncode> </yarncode>
  
Line 158: Line 168:
 @Environment(EnvType.CLIENT) @Environment(EnvType.CLIENT)
 public class ExampleModClient implements ClientModInitializer { public class ExampleModClient implements ClientModInitializer {
-    public static final EntityModelLayer NETHERITE_BANNER_SHIELD_MODEL_LAYER = new EntityModelLayer(new Identifier("tutorial", "netherite_banner_shield"),"main");+    public static final EntityModelLayer NETHERITE_BANNER_SHIELD_MODEL_LAYER = new EntityModelLayer(Identifier.of("tutorial", "netherite_banner_shield"),"main");
  
     @Override     @Override
Line 173: Line 183:
 public class ExampleModClient implements ClientModInitializer { public class ExampleModClient implements ClientModInitializer {
  
-    public static final EntityModelLayer NETHERITE_SHIELD_MODEL_LAYER = new EntityModelLayer(new Identifier("tutorial", "netherite_shield"),"main");+    public static final EntityModelLayer NETHERITE_SHIELD_MODEL_LAYER = new EntityModelLayer(Identifier.of("tutorial", "netherite_shield"),"main");
  
     @Override     @Override
Line 187: Line 197:
 @Environment(EnvType.CLIENT) @Environment(EnvType.CLIENT)
 public class ExampleModClient implements ClientModInitializer { public class ExampleModClient implements ClientModInitializer {
-    public static final EntityModelLayer NETHERITE_SHIELD_MODEL_LAYER = new EntityModelLayer(new Identifier("tutorial", "netherite_shield"), "main");+    public static final EntityModelLayer NETHERITE_SHIELD_MODEL_LAYER = new EntityModelLayer(Identifier.of("tutorial", "netherite_shield"), "main");
          
     public static ShieldEntityModel modelNetheriteShield;     public static ShieldEntityModel modelNetheriteShield;
Line 203: Line 213:
 @Environment(EnvType.CLIENT) @Environment(EnvType.CLIENT)
 public class ExampleModClient implements ClientModInitializer { public class ExampleModClient implements ClientModInitializer {
-    public static final EntityModelLayer NETHERITE_SHIELD_MODEL_LAYER = new EntityModelLayer(new Identifier("tutorial", "netherite_shield"),"main");+    public static final EntityModelLayer NETHERITE_SHIELD_MODEL_LAYER = new EntityModelLayer(Identifier.of("tutorial", "netherite_shield"),"main");
          
     public static ShieldEntityModel modelNetheriteShield;     public static ShieldEntityModel modelNetheriteShield;
Line 224: Line 234:
 public class ExampleModClient implements ClientModInitializer { public class ExampleModClient implements ClientModInitializer {
  
- public static final EntityModelLayer netherite_banner_shield_model_layer = new EntityModelLayer(new Identifier("tutorial", "netherite_banner_shield"), "main");+ public static final EntityModelLayer netherite_banner_shield_model_layer = new EntityModelLayer(Identifier.of("tutorial", "netherite_banner_shield"), "main");
  
  public static ShieldEntityModel modelNetheriteShield;  public static ShieldEntityModel modelNetheriteShield;
  
- public static final SpriteIdentifier NETHERITE_BANNER_SHIELD_BASE = new SpriteIdentifier(SpriteAtlasTexture.BLOCK_ATLAS_TEXTURE, new Identifier("tutorial", "entity/netherite_banner_shield_base")); + public static final SpriteIdentifier NETHERITE_BANNER_SHIELD_BASE = new SpriteIdentifier(SpriteAtlasTexture.BLOCK_ATLAS_TEXTURE, Identifier.of("tutorial", "entity/netherite_banner_shield_base")); 
- public static final SpriteIdentifier NETHERITE_BANNER_SHIELD_BASE_NO_PATTERN = new SpriteIdentifier(SpriteAtlasTexture.BLOCK_ATLAS_TEXTURE, new Identifier("tutorial", "entity/netherite_banner_shield_base_nopattern"));+ public static final SpriteIdentifier NETHERITE_BANNER_SHIELD_BASE_NO_PATTERN = new SpriteIdentifier(SpriteAtlasTexture.BLOCK_ATLAS_TEXTURE, Identifier.of("tutorial", "entity/netherite_banner_shield_base_nopattern"));
  
  @Override  @Override
Line 243: Line 253:
 </code> </code>
  
-Finally, we are going to register our shield with the ''BuiltinItemRendererRegistry'',+Finally, we will want to go back to our item and add a component to it to store its model information like so: 
 <code java> <code java>
-@Environment(EnvType.CLIENT) + public static final Item NETHERITE_BANNER_SHIELD register("netherite_banner_shield", 
-public class ExampleModClient implements ClientModInitializer { + settings -> new FabricBannerShieldItem(settings,10, 13, Items.NETHERITE_INGOT), // FabricBannerShieldItem(settings.maxDamage(durability), cooldownTicks, enchantability, repairItem) 
- public static final EntityModelLayer netherite_banner_shield_model_layer = new EntityModelLayer(new Identifier("tutorial""netherite_banner_shield"),"main");+ new Item.Settings().maxDamage(2500).component(FabricShieldLib.MODEL_COMPONENT, 
 + new FabricShieldModelComponent( 
 + ExampleModClient.NETHERITE_BANNER_SHIELD_BASE.getTextureId(), //Your base texture, from the client initializer 
 + ExampleModClient.NETHERITE_BANNER_SHIELD_BASE_NO_PATTERN.getTextureId(), //Your no-pattern texture, from the client initializer 
 + ExampleModClient.netherite_banner_shield_model_layer.toString() // Your model layer, from the client initializer 
 + )));
  
- public static ShieldEntityModel modelNetheriteShield;+</code>
  
- public static final SpriteIdentifier NETHERITE_BANNER_SHIELD_BASE = new SpriteIdentifier(SpriteAtlasTexture.BLOCK_ATLAS_TEXTURE, new Identifier("tutorial", "entity/netherite_banner_shield_base")); 
- public static final SpriteIdentifier NETHERITE_BANNER_SHIELD_BASE_NO_PATTERN = new SpriteIdentifier(SpriteAtlasTexture.BLOCK_ATLAS_TEXTURE, new Identifier("tutorial", "entity/netherite_banner_shield_base_nopattern")); 
- 
- @Override 
- public void onInitializeClient() { 
-            EntityModelLayerRegistry.registerModelLayer(NETHERITE_SHIELD_MODEL_LAYER, ShieldEntityModel::getTexturedModelData); 
-         
-            ShieldSetModelCallback.EVENT.register((loader) -> { 
-         modelNetheriteShield = new ShieldEntityModel(loader.getModelPart(netherite_banner_shield_model_layer)); 
-         return ActionResult.PASS; 
-     }); 
-  
-            BuiltinItemRendererRegistry.INSTANCE.register(ExampleMod.NETHERITE_BANNER_SHIELD, (stack, mode, matrices, vertexConsumers, light, overlay) -> { 
- renderBanner(stack, matrices, vertexConsumers, light, overlay, modelNetheriteShield, NETHERITE_BANNER_SHIELD_BASE, NETHERITE_BANNER_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. 
-     }); 
- } 
-} 
-</code> 
  
 That is all of our code done, we only have a few json files to make. That is all of our code done, we only have a few json files to make.
Line 289: Line 286:
 </code> </code>
  
-Next, inside ''resources/assets/tutorial/models/item/'', create a ''netherite_banner_shield.json'' file and put this inside it:+Next, inside ''resources/assets/tutorial/models/item/'', create a ''netherite_banner_shield.json'' file and put this inside it: 
- +<code javascript resources/assets/tutorial/models/item/netherite_banner_shield.json>
-<code javascript resources/assets/tutorial/models/item/etherite_banner_shield.json>+
 { {
-  "parent":"fabricshieldlib:item/fabric_banner_shield"+  "parent":"fabricshieldlib:item/fabric_banner_shield"
-  "overrides":+
-    { +
-      "predicate":+
-        "blocking":+
-      }, +
-      "model": "tutorial:item/netherite_banner_shield_blocking" +
-    } +
-  ]+
 } }
 </code> </code>
  
 In the same folder, create another file, ''netherite_banner_shield_blocking.json'', and put his inside it:  In the same folder, create another file, ''netherite_banner_shield_blocking.json'', and put his inside it: 
-<code javascript resources/assets/tutorial/models/item/etherite_banner_shield_blocking.json>+<code javascript resources/assets/tutorial/models/item/netherite_banner_shield_blocking.json>
 { {
-  "parent":"fabricshieldlib:item/fabric_banner_shield_blocking"+  "parent":"fabricshieldlib:item/fabric_banner_shield_blocking"
-  "textures":+
-    "shield":"tutorial:item/netherite_shield" +
-  }+
 } }
 </code> </code>
Line 319: Line 304:
 Then, you will move both of these textures into ''resources/assets/<modid>/textures/entity''. Then, you will move both of these textures into ''resources/assets/<modid>/textures/entity''.
  
-Lastly, create a ''shields.json'' file in ''resources/data/c/tags/items/shields.json'' and add your shield to it:+Next, create a ''shields.json'' file in ''resources/data/c/tags/items/shields.json'' and add your shield to it:
 <code javascript resources/data/c/tags/items/shields.json> <code javascript resources/data/c/tags/items/shields.json>
 +{
 +  "replace": false,
 +  "values": [
 +    "tutorial:netherite_banner_shield"
 +  ]
 +}
 +</code>
 +
 +Finally create a ''durability.json'' file in ''resources/data/minecraft/tags/item/enchantable/durability.json'' and add your shield to it:
 +<code javascript resources/data/minecraft/tags/item/enchantable/durability.json>
 { {
   "replace": false,   "replace": false,
Line 354: Line 349:
  
 And now your shield is fully completed and supports banner decoration! And now your shield is fully completed and supports banner decoration!
 +===== Changes for 1.21.3 =====
 +If you are working in 1.21.3, **follow the changes for all higher versions first**, then change the FabricShieldLib and FAPI versions accordingly and change your other dependencies to these versions:\\
 +
 +<file properties gradle.properties>
 +mod_menu_version=12.0.0-beta.1
 +midnightlib_version=1.6.4-fabric
 +</file>
 +
 +Next, remove the ''FabricShieldLib.MODEL_COMPONENT'' from your shields. Then, you will want to register your shield with the ''BuiltinItemRendererRegistry'':
 +
 +<code java>
 +...
 +import static com.github.crimsondawn45.fabricshieldlib.initializers.FabricShieldLibClient.renderBanner;
 +...
 +public class ExampleModClient implements ClientModInitializer {
 + ...
 + @Override
 + public void onInitializeClient() {
 +                ...
 + BuiltinItemRendererRegistry.INSTANCE.register(ExampleMod.NETHERITE_BANNER_SHIELD, (stack, mode, matrices, vertexConsumers, light, overlay) -> {
 + renderBanner(stack, matrices, vertexConsumers, light, overlay, modelNetheriteShield, NETHERITE_BANNER_SHIELD_BASE, NETHERITE_BANNER_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.
 + });
 + ...
 + }
 +        ...
 +}
 +</code>
 +
 +Finally, change the following models to these formats: (netherite_shield_blocking.json will be unchanged)
 +
 +<file javascript resources/assets/tutorial/models/item/netherite_shield.json>
 +{
 +    "parent":"fabricshieldlib:item/fabric_shield",
 +    "textures":{
 +        "shield":"tutorial:item/netherite_shield"
 +    },
 +    "overrides": [
 +        {
 +            "predicate": {
 +                "blocking": 1
 +            },
 +            "model": "tutorial:item/netherite_shield_blocking"
 +        }
 +    ]
 +}
 +</file> 
 +
 +<code javascript resources/assets/tutorial/models/item/etherite_banner_shield.json>
 +{
 +  "parent":"fabricshieldlib:item/fabric_banner_shield",
 +  "overrides": [
 +    {
 +      "predicate": {
 +        "blocking": 1
 +      },
 +      "model": "tutorial:item/netherite_banner_shield_blocking"
 +    }
 +  ]
 +}
 +</code>
 +
 +<code javascript resources/assets/tutorial/models/item/etherite_banner_shield_blocking.json>
 +{
 +  "parent":"fabricshieldlib:item/fabric_banner_shield_blocking",
 +  "textures":{
 +    "shield":"tutorial:item/netherite_banner_shield"
 +  }
 +}
 +</code>
 +
 +===== Changes for 1.21.1 =====
 +If you are working in 1.21.1, **follow the changes for all higher versions first**, then change the FabricShieldLib and FAPI versions accordingly and change your other dependencies to these versions:\\
 +
 +<file properties gradle.properties>
 +mod_menu_version=11.0.1
 +midnightlib_version=1.5.8-fabric
 +</file>
 +
 +Then, update your Item registries to match the old method at the [[items]] tutorial. Your item registry lines would look like this:
 +
 +<code java>
 +public static final Item NETHERITE_SHIELD = register(new FabricShieldItem(new Item.Settings().maxDamage(2500),10, 13, Items.NETHERITE_INGOT),"netherite_shield");
 +</code>
 +or
 +<code java>
 +public static final Item NETHERITE_BANNER_SHIELD = register(new FabricBannerShieldItem(new Item.Settings().maxDamage(2500), 10, 13, Items.NETHERITE_INGOT), "netherite_banner_shield");
 +</code>
 +
 +===== Changes for 1.20.6 =====
 +If you are working in 1.20.6, **follow the changes for all higher versions first**, then change the FabricShieldLib and FAPI versions accordingly and change your other dependencies to these versions:\\
 +
 +<file properties gradle.properties>
 +mod_menu_version=10.0.0-beta.1
 +midnightlib_version=1.5.5-fabric
 +</file>
 +
 +Next, change all instances of ''Identifier.of'' to ''new Identifier''; these are when you are registering your item, creating your ''EntityModelLayer'', and creating your ''SpriteIdentifiers''.
 +
 +Then, change your ''shield.json'' in ''resources/data/c/tags/item/tools/shield.json'' to ''shields.json'' file in ''resources/data/c/tags/items/shields.json'' 
 +
 +Finally, move your ''durability.json'' from ''resources/data/minecraft/tags/items/enchantable/durability.json'' to ''resources/data/minecraft/tags/item/enchantable/durability.json''
 +
 +===== Changes for 1.20.4 =====
 +If you are working in 1.20.4, **follow the changes for all higher versions first**, then change the FabricShieldLib and FAPI versions accordingly and change your other dependencies to these versions:\\
 +
 +**gradle.properties**
 +<file properties gradle.properties>
 +midnightlib_version=1.5.2-fabric
 +mod_menu_version=9.0.0-pre.1
 +</file>
 +
 +Additionally, **remove the** ''durability.json'' **file** completely.
 +
 +===== Changes for 1.20.1 =====
 +If you are working in 1.20.1, **follow the changes for all higher versions first**, then change the FabricShieldLib and FAPI versions accordingly and change your other dependencies to these versions:\\
 +
 +**gradle.properties**
 +<file properties gradle.properties>
 +midnightlib_version=1.4.1-fabric
 +mod_menu_version=7.1.0
 +</file>
  
 ===== Changes for 1.19 ===== ===== Changes for 1.19 =====
-If you are working in 1.19, make sure to change the FabricShieldLib and FAPI versions accordingly as well as changing your Midnight Lib and Mod Menu dependencies to these versions:\\+If you are working in 1.19, **follow the changes for all higher versions first**, then change the FabricShieldLib and FAPI versions accordingly and change your other dependencies to these versions:\\ 
 **gradle.properties** **gradle.properties**
-<code java>+<file properties gradle.properties>
 midnightlib_version=1.0.0-fabric midnightlib_version=1.0.0-fabric
 mod_menu_version=4.2.0-beta.2 mod_menu_version=4.2.0-beta.2
-</code>+</file> 
tutorial/shield.1719990499.txt.gz · Last modified: 2024/07/03 07:08 by solidblock