Table of Contents
Adding Tools
This tutorial may be outdated as since 1.20.5, item components are used. For latest tutorial see corresponding page on Fabric Docs.
Creating a Tool Material
Tools require a ToolMaterial
, which defines the following behavior:
- durability
- mining speed
- attack damage
- mining level
- enchantability
- repair ingredient
In other words, Tool Materials defines the base functionality for tools of that type, and tools can choose to use the values provided by the material, or roll with their own.
Vanilla Tool Materials can be found in ToolMaterials
. We will create a separate class for our material:
public class PotatoToolMaterial implements ToolMaterial { [...] }
ToolMaterial
has a number of methods you will need to implement:
Durability
getDurability
defines the base durability tools will have when they use this material. In vanilla, all tools of the same type have the same durability.
@Override public int getDurability() { return 500; }
Mining Speed
getMiningSpeedMultiplier
defines how fast tools are when mining blocks. For a general sense of scale, Wooden has a speed of 2.0F, and Diamond has a speed of 8.0F.
@Override public float getMiningSpeedMultiplier() { return 5.0F; }
Attack Damage
getAttackDamage
returns the base damage of the tool. Note that most tools ask for an integer damage amount in their constructor, which means the resulting damage is (float) materialDamage + (int) toolDamage + 1
. If you want your tool to entirely control its damage amount in its constructor, you can make your material return an attack damage of 0F.
@Override public float getAttackDamage() { return 3.0F; }
Mining Level
getMiningLevel
sets the mining level of a tool. Diamond has a mining level of 3, and a value of 3+ is required to mine Obsidian.
@Override public int getMiningLevel() { return 2; }
Enchantability
getEnchantability
defines how enchantable a tool is. Gold comes in at 22 Enchatability, while Diamond sits at 10. Higher enchantability means better (and higher-level) enchantments.
@Override public int getEnchantability() { return 15; }
Repair Ingredient
getRepairIngredient
returns the Ingredient
required to repair a tool in an anvil.
@Override public Ingredient getRepairIngredient() { return Ingredient.ofItems(Items.POTATO); }
ToolMaterial
s do not have to be registered. A good way to pass them out to tools that require them is by keeping an instance somewhere (and then referencing it when you need it). In this case, we will put our instance at the top of the class:
public class PotatoToolMaterial implements ToolMaterial { public static final PotatoToolMaterial INSTANCE = new PotatoToolMaterial(); [...] }
PotatoToolMaterial
can now be referenced with PotatoToolMaterial.INSTANCE
. Alternatively, you can implement an enum similar to vanilla's ToolMaterials
class that implements ToolMaterial
, which provides the instance and also allows easy creation of multiple tool materials.
Creating Tools Items
In newer versions, all base tool class constructors are public and can be used directly to register the item. This constructor lets you specify attack damage and attack speed of the tool. Remember they should be registered (see items tutorial).
public final class TutorialItems { public static ToolItem POTATO_PICKAXE = new PickaxeItem(PotatoToolMaterial.INSTANCE, 1, -2.8F, new FabricItemSettings()); public static ToolItem POTATO_AXE = new AxeItem(PotatoToolMaterial.INSTANCE, 7.0F, -3.2F, new FabricItemSettings()); public static ToolItem POTATO_HOE = new HoeItem(PotatoToolMaterial.INSTANCE, 7, -3.2F, new FabricItemSettings()); }
Creating Tool Subclasses
This section is not necessary in the current version of Fabric. This is a good way to implement special attributes or behaviors for your tool, however.
In older versions, all base tool classes (PickaxeItem
, ShovelItem
, HoeItem
, AxeItem
, SwordItem
) require a ToolMaterial
, an attack speed (float), an additional attack damage amount (float for AxeItem; int for the rest), and an Item.Settings
instance.
PickaxeItem
, HoeItem
and AxeItem
have protected constructors, which means you will need to create your own classes with public constructors:
public class CustomPickaxeItem extends PickaxeItem { public CustomPickaxeItem(ToolMaterial material, int attackDamage, float attackSpeed, Settings settings) { super(material, attackDamage, attackSpeed, settings); } }
Using the public classes:
public static ToolItem POTATO_PICKAXE = new CustomPickaxeItem(PotatoToolMaterial.INSTANCE, 1, -2.8F, new Item.Settings()); public static ToolItem POTATO_AXE = new CustomAxeItem(PotatoToolMaterial.INSTANCE, 7.0F, -3.2F, new Item.Settings()); public static ToolItem POTATO_HOE = new CustomHoeItem(PotatoToolMaterial.INSTANCE, 7, -3.2F, new Item.Settings());
Making your tool work with non-vanilla blocks
See mining_levels.