User Tools

Site Tools


tutorial:items

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:items [2024/07/02 23:50] solidblocktutorial:items [2024/10/27 14:45] (current) – [Item components] solidblock
Line 1: Line 1:
 +~~REDIRECT>https://docs.fabricmc.net/develop/items/first-item~~
 +
 ====== Adding an Item ====== ====== Adding an Item ======
  
Line 6: Line 8:
  
 ===== Create an Item instance ===== ===== Create an Item instance =====
 +
 +:!: If you're in version 1.21.2 or above, please directly read [[#Creating Items in 1.21.2+]].
  
 First, create an instance of ''<yarn class_1792>''. The constructor takes in an ''<yarn class_1792>.<yarn class_1793>'' (or a ''FabricItemSettings'' unless versions since 1.20.5) instance, which is used to set item properties such as the durability, and stack count. For simplicity, we just do it in ''ExampleMod'' class, and store them in static fields. First, create an instance of ''<yarn class_1792>''. The constructor takes in an ''<yarn class_1792>.<yarn class_1793>'' (or a ''FabricItemSettings'' unless versions since 1.20.5) instance, which is used to set item properties such as the durability, and stack count. For simplicity, we just do it in ''ExampleMod'' class, and store them in static fields.
Line 15: Line 19:
     // for versions below 1.20.4     // for versions below 1.20.4
     public static final class_1792 CUSTOM_ITEM = new class_1792(new FabricItemSettings());     public static final class_1792 CUSTOM_ITEM = new class_1792(new FabricItemSettings());
-    // for versions since 1.20.5+    // for versions since 1.20.5, below 1.21.2
     public static final class_1792 CUSTOM_ITEM = new class_1792(new class_1792.class_1793());     public static final class_1792 CUSTOM_ITEM = new class_1792(new class_1792.class_1793());
     [...]     [...]
Line 25: Line 29:
 We've create a basic item, but it still does not exist in Minecraft, because it has not been registered. In Minecraft, almost everything has an registry, and items are no exceptions. We've create a basic item, but it still does not exist in Minecraft, because it has not been registered. In Minecraft, almost everything has an registry, and items are no exceptions.
  
-You'll use the vanilla registry system for registering new content. The basic syntax is ''<yarn class_2378>#<yarn method_10230>(Registry Type, <yarn class_2960>, Content)''. Registry types are stored as static fields in the ''<yarn class_7923>'' or ''<yarn class_2378>'' class, and the identifier is what labels your content. Content is an instance of whatever you're adding. Specifically for item, the syntax is ''<yarn class_2378>#<yarn method_10230>(class_7923.field_41178, <yarn class_2960>, class_1792)''. This can be called anywhere as long as it occurs during initialization. The method itself also returns the registered content itself.+You'll use the vanilla registry system for registering new content. The basic syntax is ''<yarn class_2378>.<yarn method_10230>(Registry Type, <yarn class_2960>, Content)''. Registry types are stored as static fields in the ''<yarn class_7923>'' or ''<yarn class_2378>'' class, and the identifier is what labels your content. Content is an instance of whatever you're adding. Specifically for item, the syntax is ''<yarn class_2378>#<yarn method_10230>(<yarn class_7923>.<yarn field_41178>, <yarn class_2960>, <yarn class_1792>)''. This can be called anywhere as long as it occurs during initialization. The method itself also returns the registered content itself.
  
-For versions since 1.21, an ''Identifier'' is created through ''Identifier.of("namespace", "path")''. For versions below 1.21, it is created through ''new Identifier("namespace", "path")'' or ''new Identifier("namespace:path")''. It will fail if the namespace or path contains illegal characters.+For versions since 1.21, an ''Identifier'' is created through ''%%Identifier.of("namespace", "path")%%''. For versions below 1.21, it is created through ''%%new Identifier("namespace", "path")%%'' or ''%%new Identifier("namespace:path")%%''. It will fail if the namespace or path contains illegal characters.
  
 <yarncode java [enable_line_numbers="true"]> <yarncode java [enable_line_numbers="true"]>
Line 43: Line 47:
 </yarncode> </yarncode>
 Your new item has now been added to Minecraft. Run the run config ''Minecraft Client'' or ''runClient'' Gradle task to see it in action, execute the command ''/give @s tutorial:custom_item'' in game. Your new item has now been added to Minecraft. Run the run config ''Minecraft Client'' or ''runClient'' Gradle task to see it in action, execute the command ''/give @s tutorial:custom_item'' in game.
- 
-{{:tutorial:2019-02-17_16.50.44.png?400|}} 
  
 For more simplicity, you can simplify your code by directly registering them when assigning the fields, as ''Register.register'' will also return the registered object: For more simplicity, you can simplify your code by directly registering them when assigning the fields, as ''Register.register'' will also return the registered object:
Line 73: Line 75:
          
     // an instance of our new item     // an instance of our new item
-    public static final class_1792 CUSTOM_ITEM = register(new class_1792(new class_1792.class_1793()), "custom_item");+    public static final class_1792 CUSTOM_ITEM = register("custom_item", new class_1792(new class_1792.class_1793()));
  
-    public static Item register(Item instance, String path) {+    public static <T extends Item> T register(String path, T item) {
         // For versions below 1.21, please replace ''Identifier.of'' with ''new Identifier''         // For versions below 1.21, please replace ''Identifier.of'' with ''new Identifier''
         return class_2378.method_10230(class_7923.field_41178, Identifier.of("tutorial", path), item);         return class_2378.method_10230(class_7923.field_41178, Identifier.of("tutorial", path), item);
Line 85: Line 87:
 </yarncode> </yarncode>
  
-Remember to refer to some method methods or fields in the mods initializes so as to statically load the class ''TutorialItems''.+Remember to refer to some methods or fields in the mods initializer so as to statically load the class ''TutorialItems''.
 <yarncode java [enable_line_numbers="true"]> <yarncode java [enable_line_numbers="true"]>
 public class ExampleMod implements ModInitializer { public class ExampleMod implements ModInitializer {
Line 95: Line 97:
 </yarncode> </yarncode>
  
-> **Note:** Some experienced users may decide to use reflection to automatically all static fields of a class. This is also a preferable way, but should be used with caution.+> **Note:** Some experienced users may decide to use reflection to automatically register all static fields of a class. This is also a preferable way, but should be used with caution. 
 + 
 +===== Creating Items in 1.21.2+ ===== 
 + 
 +Since 1.21.2, the item registration is tutally rewrited. You have to store a ''RegistryKey'' in your ''Item.Settings'', so the models and translation keys will be correctly stored in item components. Otherwise, you may see the following exceptions and Minecraft does not run: 
 + 
 +<code> 
 +java.lang.NullPointerException: Item id not set 
 +</code> 
 + 
 +To make it run correctly, you should write like below: 
 + 
 +<code java> 
 +public final class TutorialItems { 
 +  private TutorialItems() { 
 +  } 
 + 
 +  public static final Item CUSTOM_ITEM = register("custom_item", Item::new, new Item.Settings()); 
 + 
 +  public static Item register(String path, Function<Item.Settings, Item> factory, Item.Settings settings) { 
 +    final RegistryKey<Item> registryKey = RegistryKey.of(RegistryKeys.ITEM, Identifier.of("tutorial", path)); 
 +    return Items.register(registryKey, factory, settings); 
 +  } 
 + 
 +  public static void initialize() { 
 +  } 
 +
 +</code> 
 + 
 +In the method ''Items.register'', the registry key will be written in the ''settings'' first, and then use that ''settings'' to create the item. 
 ===== Adding model and textures ===== ===== Adding model and textures =====
  
Line 119: Line 151:
 </code> </code>
 The ''parent'' of your item model changes how it's rendered in the hand and comes in useful for things like block items in the inventory. ''item/generated'' is used for many simple items. ''item/handheld'' is used for tools that are held from the bottom left of the texture. In the json, ''textures/layer0'' is the location of your image file. The ''parent'' of your item model changes how it's rendered in the hand and comes in useful for things like block items in the inventory. ''item/generated'' is used for many simple items. ''item/handheld'' is used for tools that are held from the bottom left of the texture. In the json, ''textures/layer0'' is the location of your image file.
- 
-Final textured result: 
- 
-{{:tutorial:item_texture.png?400|}} 
  
 ===== Creating an Item class ===== ===== Creating an Item class =====
  
-To add additional behavior to the item you will need to create an item class. The default constructor requires an ''Item.Settings'' object.+You have created a simple item, and learned how to change some basic properties. But maybe you want it to have more behaviors. Therefore, you will need to create an item class. The default constructor requires an ''Item.Settings'' object.
 <yarncode java [enable_line_numbers="true"]> <yarncode java [enable_line_numbers="true"]>
 public class CustomItem extends class_1792 { public class CustomItem extends class_1792 {
- 
     public CustomItem(class_1793 settings) {     public CustomItem(class_1793 settings) {
         super(settings);         super(settings);
Line 139: Line 166:
 <yarncode java [enable_line_numbers="true"]> <yarncode java [enable_line_numbers="true"]>
 public class CustomItem extends class_1792 { public class CustomItem extends class_1792 {
- 
     public CustomItem(class_1793 settings) {     public CustomItem(class_1793 settings) {
         super(settings);         super(settings);
     }     }
  
 +    // write this if the version is below 1.21.2:
     @Override     @Override
     public class_1271<class_1799> method_7836(class_1937 world, class_1657 user, class_1268 hand) {     public class_1271<class_1799> method_7836(class_1937 world, class_1657 user, class_1268 hand) {
         user.method_5783(class_3417.field_14983, 1.0F, 1.0F);         user.method_5783(class_3417.field_14983, 1.0F, 1.0F);
         return class_1271.method_22427(user.method_5998(hand));         return class_1271.method_22427(user.method_5998(hand));
 +    }
 +    
 +    // write this if the version is 1.21.2 or higher:
 +    @Override
 +    public ActionResult use(World world, PlayerEntity user, Hand hand) {
 +        user.playSound(SoundEvents.BLOCK_WOOL_BREAK, 1.0F, 1.0F);
 +        return ActionResult.SUCCESS;
     }     }
 } }
Line 155: Line 189:
 <yarncode java [enable_line_numbers="true"]> <yarncode java [enable_line_numbers="true"]>
 public final class TutorialItems { public final class TutorialItems {
- 
     [...]     [...]
  
     // an instance of our new item     // an instance of our new item
-    public static final CustomItem CUSTOM_ITEM = new CustomItem(new class_1792.class_1793());+     
 +    // For versions below 1.21.2: 
 +    public static final CustomItem CUSTOM_ITEM = register("custom_item", new CustomItem(new class_1792.class_1793())); 
 +     
 +    // For versions since 1.21.2: 
 +    public static final CustomItem CUSTOM_ITEM = register("custom_item", CustomItem::new, new class_1792.class_1793());
     [...]     [...]
 } }
 </yarncode> </yarncode>
-If you did everything correctly, using the item should now play a sound.+If you did everything correctly, using the item should now play a sound. You can also [[tooltip|add some tooltips]] for the item based on your item class.
  
-===== What if I want to change the stack size of my item? =====+===== Item components ===== 
 +Sometimes you may need to add some default components for the item, such as max stack size or fire durability. This can be done by calling ''component'' method in ''Item.Settings''. Detailed information about item components can be found in [[https://docs.fabricmc.net/develop/items/custom-data-components|the tutorial in Fabric docs]]. 
 + 
 +In this example, the item will be unbreakable by default, while hiding tooltips about it. 
 +<yarncode java> 
 +    // For versions below 1.21.2: 
 +    public static final CustomItem CUSTOM_ITEM register("custom_item", new CustomItem(new class_1792.class_1793() 
 +        .component(DataComponentTypes.UNBREAKABLE, new UnbreakableComponent(true)))); 
 +    // For versions since 1.21.2: 
 +    public static final Item CUSTOM_ITEM register("custom_item", CustomItem::new, new Item.Settings() 
 +        .component(DataComponentTypes.UNBREAKABLE, new UnbreakableComponent(true))); 
 +</yarncode> 
 + 
 +Specifically, max stack size can be simply set by calling ''maxCount'' method (which is valid also before 1.20.5). Note that if your item is damageable you cannot specify a maximum stack size or the game will throw a ''RuntimeException''.
  
-For this you would use ''maxCount(int size)'' inside ''Item.Settings'' to specify the max stack size. Note that if your item is damageable you cannot specify a maximum stack size or the game will throw a RuntimeException. 
 <yarncode java [enable_line_numbers="true"]> <yarncode java [enable_line_numbers="true"]>
 public class ExampleMod implements ModInitializer { public class ExampleMod implements ModInitializer {
- 
     // An instance of our new item, where the maximum stack size is 16     // An instance of our new item, where the maximum stack size is 16
-    public static final CustomItem CUSTOM_ITEM = new CustomItem(new class_1792.class_1793().maxCount(16));+     
 +    // For versions below 1.21.2: 
 +    public static final CustomItem CUSTOM_ITEM = register("custom_item", new CustomItem(new class_1792.class_1793().maxCount(16))); 
 +    // For versions since 1.21.2: 
 +    public static final Item CUSTOM_ITEM = register("custom_item", CustomItem::new, new Item.Settings().maxCount(16));
     [...]     [...]
 } }
Line 180: Line 233:
  
 If you want to make it a fuel so that it can be used in a furnace, you can register in ''FuelRegistry'' when initializing the mod, for example: If you want to make it a fuel so that it can be used in a furnace, you can register in ''FuelRegistry'' when initializing the mod, for example:
 +<code java>
 +public class ExampleMod implements ModInitializer {
 +    [...]
 +    
 +    // For versions below 1.21.2
 +    @Override
 +    public void onInitialize() {
 +        [...]
 +        FuelRegistry.INSTANCE.add(TutorialItems.CUSTOM_ITEM, 300);
 +    }
 +}
 +</code>
 +
 +However, in practice, when you have many items to register, as registering quantities of items may be effort-consuming and messy, you can consider placing the codes in a separate method, instead of writing like above.
 +
 +In versions below 1.21.2, you need to use Fabric API's ''FuelRegistry.INSTANCE''.
 +<code java>
 +public final class TutorialItems {
 +    [...]
 +    
 +    // For versions below 1.21.2
 +    public static void registerFuels() {
 +        FuelRegistry.INSTANCE.add(CUSTOM_ITEM, 300);
 +    }
 +}
 +</code>
 +
 +In versions since 1.21.2, use Fabric API's ''FuelRegistryEvents'':
 +<code java>
 +public final class TutorialItems {
 +    [...]
 +    
 +    // For versions since 1.21.2
 +    public static void registerFuels() {
 +        FuelRegistryEvents.BUILD.register((builder, context) -> {
 +            // You can add multiple items at once in this lambda.
 +            builder.add(CUSTOM_ITEM, 300);
 +        });
 +    }
 +}
 +</code>
 +
 +And then refer to this method in your ''ModInitializer'':
 <code java> <code java>
 public class ExampleMod implements ModInitializer { public class ExampleMod implements ModInitializer {
Line 187: Line 283:
     public void onInitialize() {     public void onInitialize() {
         [...]         [...]
-        FuelRegistry.INSTANCE.add(TutorialItems.CUSTOM_ITEM, 300)+        TutorialItems.registerFuels();
     }     }
 } }
Line 193: Line 289:
  
 Similarly, you can use a ''CompostingChanceRegistry'' to make it compostable in a composter. Similarly, you can use a ''CompostingChanceRegistry'' to make it compostable in a composter.
-==== Next Steps ====+===== Next Steps =====
 [[tutorial:itemgroup|Add your item to your own ItemGroup]]. [[tutorial:itemgroup|Add your item to your own ItemGroup]].
tutorial/items.1719964235.txt.gz · Last modified: 2024/07/02 23:50 by solidblock