User Tools

Site Tools


tutorial:blocks

Differences

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

Link to this comparison view

Both sides previous revision Previous revision
Next revision
Previous revision
tutorial:blocks [2020/06/14 01:02]
draylar more highlighting
tutorial:blocks [2022/04/29 09:57] (current)
solidblock [Custom VoxelShape]
Line 11: Line 11:
  
     /* Declare and initialize our custom block instance.     /* Declare and initialize our custom block instance.
-       We set out block material to METAL, which requires a pickaxe to efficiently break. +       We set our block material to `METAL`, which requires a pickaxe to efficiently break
-       ​Hardness ​represents ​how long the break takes to break. Stone has a hardness of 1.5f, while Obsidian has a hardness of 50.0f.+        
 +       ​`strength` sets both the hardness and the resistance of a block to the same value
 +       ​Hardness ​determines ​how long the block takes to break, and resistance determines how strong the block is against blast damage (e.g. explosions). 
 +       Stone has a hardness of 1.5f and a resistance of 6.0f, while Obsidian has a hardness of 50.0f and a resistance of 1200.0f. 
 +        
 +       You can find the stats of all vanilla blocks in the class `Blocks`, where you can also reference other blocks.
     */     */
-    public static final Block EXAMPLE_BLOCK = new Block(FabricBlockSettings.of(Material.METAL).hardness(4.0f));+    public static final Block EXAMPLE_BLOCK = new Block(FabricBlockSettings.of(Material.METAL).strength(4.0f));
     ​     ​
     @Override     @Override
Line 25: Line 30:
 ==== Registering your Block ==== ==== Registering your Block ====
  
-Blocks should be registered under the ''​Block.REGISTRY''​ registry. Call //Registry.register//​ and pass in the appropriate arguments.+Blocks should be registered under the ''​Registry.BLOCK''​ registry. Call ''​Registry.//register//'' ​and pass in the appropriate arguments. You can either register the block in ''​onInitialize''​ method or directly when creating the block instance in the static context, as the ''​register''​ method returns the block instance as well.
  
 <code java [enable_line_numbers="​true",​highlight_lines_extra="​11"​]>​ <code java [enable_line_numbers="​true",​highlight_lines_extra="​11"​]>​
 public class ExampleMod implements ModInitializer { public class ExampleMod implements ModInitializer {
  
-    ​/* Declare and initialize our custom block instance. +    public static final Block EXAMPLE_BLOCK = new Block(FabricBlockSettings.of(Material.METAL).strength(4.0f));
-       We set out block material to METAL, which requires a pickaxe to efficiently break. +
-       ​Hardness represents how long the break takes to break. Stone has a hardness of 1.5f, while Obsidian has a hardness of 50.0f. +
-    */ +
-    ​public static final Block EXAMPLE_BLOCK = new Block(FabricBlockSettings.of(Material.METAL).hardness(4.0f));+
     ​     ​
     @Override     @Override
Line 52: Line 53:
 public class ExampleMod implements ModInitializer { public class ExampleMod implements ModInitializer {
  
-    ​/* Declare and initialize our custom block instance. +    public static final Block EXAMPLE_BLOCK = new Block(FabricBlockSettings.of(Material.METAL).strength(4.0f));
-       We set out block material to METAL, which requires a pickaxe to efficiently break. +
-       ​Hardness represents how long the break takes to break. Stone has a hardness of 1.5f, while Obsidian has a hardness of 50.0f. +
-    */ +
-    ​public static final Block EXAMPLE_BLOCK = new Block(FabricBlockSettings.of(Material.METAL));​+
     ​     ​
     @Override     @Override
     public void onInitialize() {     public void onInitialize() {
         Registry.register(Registry.BLOCK,​ new Identifier("​tutorial",​ "​example_block"​),​ EXAMPLE_BLOCK);​         Registry.register(Registry.BLOCK,​ new Identifier("​tutorial",​ "​example_block"​),​ EXAMPLE_BLOCK);​
-        Registry.register(Registry.ITEM,​ new Identifier("​tutorial",​ "​example_block"​),​ new BlockItem(EXAMPLE_BLOCK,​ new Item.Settings().group(ItemGroup.MISC)));​+        Registry.register(Registry.ITEM,​ new Identifier("​tutorial",​ "​example_block"​),​ new BlockItem(EXAMPLE_BLOCK,​ new FabricItemSettings().group(ItemGroup.MISC)));​
     }     }
 } }
Line 91: Line 88:
 </​code>​ </​code>​
  
-The block model file defines the shape and texture of your block. Our model will parent ​''​block/​cube_all'',​ which applies the texture ​set as ''​all''​ to //all// sides of the block.+The block model file defines the shape and texture of your block. Our model will have ''​block/​cube_all''​as a parent, which applies the texture ''​all''​ to //all// sides of the block.
  
 <code JavaScript src/​main/​resources/​assets/​tutorial/​models/​block/​example_block.json>​ <code JavaScript src/​main/​resources/​assets/​tutorial/​models/​block/​example_block.json>​
Line 102: Line 99:
 </​code>​ </​code>​
  
-In most cases, you will want the block to look the same in item form. You can make an item model that parents ​the block model file, which makes it appear exactly like the block:+In most cases, you will want the block to look the same in item form. You can make an item model that has the block model file as a parent, which makes it appear exactly like the block:
  
 <code JavaScript src/​main/​resources/​assets/​tutorial/​models/​item/​example_block.json>​ <code JavaScript src/​main/​resources/​assets/​tutorial/​models/​item/​example_block.json>​
Line 136: Line 133:
   ]   ]
 } }
 +</​code>​
 +
 +In minecraft 1.17, there has been a change for breaking blocks. Now, to define harvest tools and harvest levels, we need to use tags. Read about tags at: [[tutorial:​tags|Tags Tutorial]]. The tags that we need to add the block to are:
 +
 +  Harvest tool: src/​main/​resources/​data/​minecraft/​tags/​blocks/​mineable/<​tooltype>​.json,​ Where '​tooltype'​ can be any of: '​axe',​ '​pickaxe',​ '​shovel'​ ore '​hoe'​
 +  Harvest level: src/​main/​resources/​data/​minecraft/​tags/​blocks/​needs_<​tier>​_tool.json,​ Where '​tier'​ can be any of: '​stone',​ '​iron'​ or '​diamond'​
 +
 +<code JavaScript src/​main/​resources/​data/​minecraft/​tags/​blocks/​mineable/​pickaxe.json>​
 +{
 +  "​replace":​ false,
 +  "​values":​ [
 +    "​tutorial:​example_block"​
 +  ]
 +}
 +</​code>​
 +
 +<code JavaScript src/​main/​resources/​data/​minecraft/​tags/​blocks/​needs_stone_tool.json>​
 +{
 +  "​replace":​ false,
 +  "​values":​ [
 +    "​tutorial:​example_block"​
 +  ]
 +}
 +</​code>​
 +
 +For the harvest level tags (needs_stone_tool,​ needs_iron_tool and needs_diamond_tool) to take effect, add requiresTool() to the FabricToolSettings in the block declaration:​
 +
 +
 +<code java [enable_line_numbers="​true"​]>​
 +    public static final Block EXAMPLE_BLOCK = new ExampleBlock(FabricBlockSettings.of(Material.METAL).strength(4.0f).requiresTool());​
 </​code>​ </​code>​
  
 ===== Creating a Custom Block Class ===== ===== Creating a Custom Block Class =====
  
-The above approach works well for simple ​items but falls short when you want a block with //unique// mechanics. We'll create a //​separate//​ class that extends ''​Block''​ to do this. The class needs a constructor that takes in an ''​AbstractBlock.Settings''​ argument:+The above approach works well for simple ​blocks ​but falls short when you want a block with //unique// mechanics. We'll create a //​separate//​ class that extends ''​Block''​ to do this. The class needs a constructor that takes in an ''​AbstractBlock.Settings''​ argument:
  
 <code java [enable_line_numbers="​true"​]>​ <code java [enable_line_numbers="​true"​]>​
Line 154: Line 181:
  
 <code java [enable_line_numbers="​true",​highlight_lines_extra="​8,​9,​10,​11,​12,​13,​14,​15"​]>​ <code java [enable_line_numbers="​true",​highlight_lines_extra="​8,​9,​10,​11,​12,​13,​14,​15"​]>​
-@Override 
 public class ExampleBlock extends Block { public class ExampleBlock extends Block {
  
Line 163: Line 189:
     @Override     @Override
     public ActionResult onUse(BlockState state, World world, BlockPos pos, PlayerEntity player, Hand hand, BlockHitResult hit) {     public ActionResult onUse(BlockState state, World world, BlockPos pos, PlayerEntity player, Hand hand, BlockHitResult hit) {
-        if(!world.isClient) {+        if (!world.isClient) {
             player.sendMessage(new LiteralText("​Hello,​ world!"​),​ false);             player.sendMessage(new LiteralText("​Hello,​ world!"​),​ false);
         }         }
Line 174: Line 200:
 To use your custom block class, replace //new Block// with //new ExampleBlock//:​ To use your custom block class, replace //new Block// with //new ExampleBlock//:​
  
-<code java [enable_line_numbers="​true",​highlight_lines_extra="​7"]>+<code java [enable_line_numbers="​true",​highlight_lines_extra="​3"]>
 public class ExampleMod implements ModInitializer { public class ExampleMod implements ModInitializer {
  
-    ​/* Declare and initialize our custom block instance using our new ExampleBlock class. +    public static final ExampleBlock EXAMPLE_BLOCK = new ExampleBlock(FabricBlockSettings.of(Material.STONE).hardness(4.0f));​
-       We set out block material to METAL, which requires a pickaxe to efficiently break. +
-       ​Hardness represents how long the break takes to break. Stone has a hardness of 1.5f, while Obsidian has a hardness of 50.0f. +
-    */ +
-    ​public static final ExampleBlock EXAMPLE_BLOCK = new ExampleBlock(Block.Settings.of(Material.STONE).hardness(4.0f));​+
     ​     ​
     @Override     @Override
Line 197: Line 219:
 {{:​tutorial:​voxelshape_wrong.png?​200|}} {{:​tutorial:​voxelshape_wrong.png?​200|}}
  
-To fix this, we have to define the //VoxelShape// of the new block:+To fix this, we have to define the ''​VoxelShape'' ​of the new block:
  
-<​code>​ +<​code ​java
-@Override +public class ExambleBlock extends Block { 
- ​public VoxelShape getOutlineShape(BlockState state, BlockView view, BlockPos pos, EntityContext ctx) { +    [...] 
-     ​return VoxelShapes.cuboid(0f,​ 0f, 0f, 1f, 1.0f, 0.5f); +    ​@Override 
- }+    public VoxelShape getOutlineShape(BlockState state, BlockView view, BlockPos pos, ShapeContext context) { 
 +        return VoxelShapes.cuboid(0f,​ 0f, 0f, 1f, 1.0f, 0.5f); 
 +    } 
 +}
 </​code>​ </​code>​
  
Line 214: Line 239:
  
 [[tutorial:​blockentity|Giving blocks a block entity so they can have advanced state like inventories]]. Also needed for many things like GUI and custom block rendering. [[tutorial:​blockentity|Giving blocks a block entity so they can have advanced state like inventories]]. Also needed for many things like GUI and custom block rendering.
 +
 +To make your block flammable (that is, can be burned in fire), you may use ''​FlammableBlockRegistry''​.
tutorial/blocks.1592096538.txt.gz · Last modified: 2020/06/14 01:02 by draylar