User Tools

Site Tools


tutorial:crops

Differences

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

Link to this comparison view

Next revision
Previous revision
tutorial:crops [2021/06/24 21:10] – created crop block page (feel free to make changes) safrotutorial:crops [2025/04/01 12:05] (current) – fix typo solidblock
Line 10: Line 10:
 ===== Creating the Crop Block Class ===== ===== Creating the Crop Block Class =====
  
-In order to create a crop we need a class for the block. You will need to make a class with your crop name and make it extend ''CropBlock''. You'll want to add your ''AbstractBlock.Settings'' and create a shape for the crop. Each ''Block.createCubiodShape'' defines the hitbox size for each growth stage of the crop. You can configure the values to your liking.  +In order to create a crop we need a class for the block. You will need to make a class with your crop name and make it extend ''CropBlock''. You'll want to add your ''AbstractBlock.Settings'' and create a shape for the crop.
  
 <code java [enable_line_numbers="true"]> <code java [enable_line_numbers="true"]>
 public class CustomCropBlock extends CropBlock { public class CustomCropBlock extends CropBlock {
-    private static final VoxelShape[] AGE_TO_SHAPE = new VoxelShape[]{Block.createCuboidShape(0.0D, 0.0D, 0.0D, 16.0D, 2.0D, 16.0D), 
-            Block.createCuboidShape(0.0D, 0.0D, 0.0D, 16.0D, 3.0D, 16.0D), 
-            Block.createCuboidShape(0.0D, 0.0D, 0.0D, 16.0D, 4.0D, 16.0D), 
-            Block.createCuboidShape(0.0D, 0.0D, 0.0D, 16.0D, 5.0D, 16.0D), 
-            Block.createCuboidShape(0.0D, 0.0D, 0.0D, 16.0D, 6.0D, 16.0D), 
-            Block.createCuboidShape(0.0D, 0.0D, 0.0D, 16.0D, 7.0D, 16.0D), 
-            Block.createCuboidShape(0.0D, 0.0D, 0.0D, 16.0D, 8.0D, 16.0D), 
-            Block.createCuboidShape(0.0D, 0.0D, 0.0D, 16.0D, 9.0D, 16.0D) 
-    }; 
- 
     public CustomCropBlock(AbstractBlock.Settings settings) {     public CustomCropBlock(AbstractBlock.Settings settings) {
         super(settings);         super(settings);
Line 31: Line 21:
 </code> </code>
  
-Once you've configured that, you need to define your seed item and add an outline shape. We haven't added our seed item yet so you can use something else temporarily. Here is what the code should look like with your cuboid shape, seed item, and outline shape:+Once you've configured that, you can define your seed item and add an outline shape. Each ''Block.createCubiodShape'' defines the hitbox size for each growth stage of the crop. You can configure the values to your liking, or do nothing while directly using the vanilla one inherited from ''CropBlock'', which will be identical to the shape for wheat. 
 + 
 +We haven't added our seed item yet so you can use something else temporarily. Here is what the code should look like with your cuboid shape, seed item, and outline shape:
  
 <code java [enable_line_numbers="true"]> <code java [enable_line_numbers="true"]>
Line 49: Line 41:
     }     }
  
-    public ItemConvertible getSeedsItem() { +    @Override 
-        return TutorialMod.CUSTOM_SEEDS;+    protected ItemConvertible getSeedsItem() { 
 +        return TutorialItems.CUSTOM_SEEDS;
     }     }
          
-    public VoxelShape getOutlineShape(BlockState state, BlockView world, BlockPos pos, ShapeContext context) { +    @Override 
-        return AGE_TO_SHAPE[(Integer)state.get(this.getAgeProperty())];+    protected VoxelShape getOutlineShape(BlockState state, BlockView world, BlockPos pos, ShapeContext context) { 
 +        return AGE_TO_SHAPE[getAge(state)];
     }     }
 } }
Line 61: Line 55:
 ===== Registering your Crop and Seed Item ===== ===== Registering your Crop and Seed Item =====
  
-Now we need to register our crop and the item to use for our seed. The seed model and class will not be covered in this tutorial but you can refer to the [[tutorial:items|Item]] page. It is important you add ''AlisasedBockItem'' to make sure your seed item is bound to your crop blockYou also probably want the ''BlockRenderMapLayer'' to make your crop a transparent cutout+Now we need to register our crop and the item to use for our seed. The seed model and class (including the static ''register'' method we use for convenience) will not be covered in this tutorial but you can refer to the [[items]] and [[blocks]] page. What you need to note is, although seeds are the corresponding item of the crop, its name does not directly use the crop's name, but use a specific name. Therefore for versions before 1.21.2, please use ''AliasedBlockItem'' instead of ''BlockItem'', and in version 1.21.2 and later, please use ''useItemPrefixedTranslationKey()''.
  
-<code java [enable_line_numbers="true"]> +<code java [enable_line_numbers="true"TutorialBlocks.java
-public class TutorialMod implements ModInitializer {+    // For versions before 1.21.2: 
 +    public static final CropBlock CUSTOM_CROP = register("custom_crop", new CustomCropBlock(AbstractBlock.Settings.create().nonOpaque().noCollision().ticksRandomly().breakInstantly().sounds(BlockSoundGroup.CROP))); 
 +     
 +    // For version 1.21.2 and later: 
 +    public static final Block CUSTOM_CROP = register("custom_crop", CustomCropBlock::new, AbstractBlock.Settings.create().nonOpaque().noCollision().ticksRandomly().breakInstantly().sounds(BlockSoundGroup.CROP)); 
 +</code>
  
- public static final CropBlock CUSTOM_CROP_BLOCK = new CustomCropBlock(AbstractBlock.Settings.of(Material.PLANT).nonOpaque().noCollision().ticksRandomly().breakInstantly().sounds(BlockSoundGroup.CROP));+<code java [enable_line_numbers="true"] TutorialItems.java> 
 +    // For version before 1.21.2: 
 +    public static final Item CUSTOM_SEEDS register("custom_seeds", new AliasedBlockItem(TutorialBlocks.CUSTOM_CROP, new Item.Settings()))
 +     
 +    // For version 1.21.2 and later: 
 +    public static final Item CUSTOM_SEEDS = register("custom_seeds", settings -> new BlockItem(TutorialBlocks.CUSTOM_CROP, settings), new Item.Settings().useItemPrefixedTranslationKey()); 
 +</code>
  
- public static final Item CUSTOM_SEEDS new AliasedBlockItem(TutorialMod.CUSTOM_CROP_BLOCK, new Item.Settings().group(ItemGroup.MISC));+> In the [[blocks]] tutorial, we wrote the ''register'' method which creates a corresponding item for each block, therefore here while we create ''custom_seeds'', we will also create an item named ''custom_crop''. If you do not need this item, you can create a method named ''registerBlockOnly'' which does not register the item, or add a parameter for ''register'' method which decides whether the item should be registered. 
 +> <code java TutorialBlocks.java> 
 +  // ... 
 +  public static final Block CUSTOM_CROP registerBlockOnly("custom_crop"CustomCropBlock::new, AbstractBlock.Settings.create().nonOpaque().noCollision().ticksRandomly().breakInstantly().sounds(BlockSoundGroup.CROP)); 
 +   
 +  // ... 
 +   
 +  private static Block registerBlockOnly(String path, Function<AbstractBlock.Settings, Block> factory, AbstractBlock.Settings settings) { 
 +    final Identifier identifier = Identifier.of("tutorial", path); 
 +    final RegistryKey<Block> registryKey = RegistryKey.of(RegistryKeys.BLOCK, identifier);
  
- @Override +    return Blocks.register(registryKeyfactory, settings); 
- public void onInitialize() { +  } 
- BlockRenderLayerMap.INSTANCE.putBlocks(RenderLayer.getCutout()CUSTOM_CROP_BLOCK);+</code>
  
- Registry.register(Registry.BLOCK, new Identifier("tutorial","custom_crop_block"), CUSTOM_CROP_BLOCK); +You also probably want the ''BlockRenderMapLayer'' to give your crop a transparent cutout (see [[blockappearance]]). Do that in your client initializer:
- Registry.register(Registry.ITEM, new Identifier("tutorial","custom_seeds"), CUSTOM_SEEDS);+
  
- }+<code java [enable_line_numbers="true"] TutorialModClient.class> 
 +@Environment(EnvType.CLIENT) 
 +public class ExampleModClient implements ClientModInitializer { 
 +    // ... 
 +     
 +    @Override 
 +    public void onInitializeClient() { 
 +        // ... 
 +        BlockRenderLayerMap.INSTANCE.putBlocks(RenderLayer.getCutout(), TutorialBlocks.CUSTOM_CROP); 
 +    }
 } }
 </code> </code>
  
 ===== Creating our Blockstate and Models ===== ===== Creating our Blockstate and Models =====
-Now that we have finished the registry and code, we can add our models. The example below shows a simple growth stage model that uses the ''minecraft:block/crop'' format. You may also use ''minecraft:block/cross'' for a cross model shape. You **must** have a seperate model for each growth stage you will have. This example shows a singular stage but you can copy it and replace the "0" with your growth stage number. +Now that we have finished the registry and code, we can add our models. The example below shows a simple growth stage model that uses the ''minecraft:block/crop'' format. You may also use ''minecraft:block/cross'' for a cross model shape. You **must** have a separate model for each growth stage you will have. This example shows a singular stage but you can copy it and replace the "0" with your growth stage number. 
  
 <code JavaScript src/main/resources/assets/tutorial/models/block/custom_crop_stage0.json> <code JavaScript src/main/resources/assets/tutorial/models/block/custom_crop_stage0.json>
Line 88: Line 110:
   "parent": "minecraft:block/crop",   "parent": "minecraft:block/crop",
   "textures": {   "textures": {
-    "crop": "minecraft:block/custom_crop_block_stage0"+    "crop": "tutorial:block/custom_crop_stage0"
   }   }
 } }
 </code> </code>
  
-Lastly you will want to create a blockstate for your crop which registers your model for each age of your crop:+Lastly you will want to create a blockstates definition for your crop which dispatches a specific model for each age of your crop:
  
-<code JavaScript src/main/resources/assets/tutorial/blockstates/custom_crop_block.json>+<code JavaScript src/main/resources/assets/tutorial/blockstates/custom_crop.json>
 { {
   "variants": {   "variants": {
     "age=0": {     "age=0": {
-      "model": "tutorial:block/custom_crop_block_stage0"+      "model": "tutorial:block/custom_crop_stage0"
     },     },
     "age=1": {     "age=1": {
-      "model": "tutorial:block/custom_crop_block_stage0"+      "model": "tutorial:block/custom_crop_stage0"
     },     },
     "age=2": {     "age=2": {
-      "model": "tutorial:block/custom_crop_block_stage1"+      "model": "tutorial:block/custom_crop_stage1"
     },     },
     "age=3": {     "age=3": {
-      "model": "tutorial:block/custom_crop_block_stage1"+      "model": "tutorial:block/custom_crop_stage1"
     },     },
     "age=4": {     "age=4": {
-      "model": "tutorial:block/custom_crop_block_stage2"+      "model": "tutorial:block/custom_crop_stage2"
     },     },
     "age=5": {     "age=5": {
-      "model": "tutorial:block/custom_crop_block_stage2"+      "model": "tutorial:block/custom_crop_stage2"
     },     },
     "age=6": {     "age=6": {
-      "model": "tutorial:block/custom_crop_block_stage3"+      "model": "tutorial:block/custom_crop_stage3"
     },     },
     "age=7": {     "age=7": {
-      "model": "tutorial:block/custom_crop_block_stage3"+      "model": "tutorial:block/custom_crop_stage3"
     }     }
   }   }
 } }
 </code> </code>
 +
 +> The seeds item also need a corresponding item model and item models definition (for version 1.21.4 an later), which will not be explained in length here.
 +
 +===== Loot Table =====
 +The block also needs a loot table, or it will drop nothing when mined. However, you can directly imitate vanillas. For example, copy vanilla's ''data/minecraft/loot_table/blocks/wheat.json'' into your mod's ''src/main/resources/data/tutorial/loot_table/blocks/custom_crop.json'', and replace related IDs. You can also use [[datagen loot|data generators]] to generate loot tables.
  
 ===== Crop Block Finished! ===== ===== Crop Block Finished! =====
  
-If you completely all parts of this tutorial correctly, you should now having work crop! Your crop will be usable with bone meal and can only be placed on farmland with your seed item. +If you completed all parts of this tutorial correctly, you should now have working crop! Your crop will be usable with bone meal and can only be placed on farmland with your seed item. You can also add other interesting funcionalities for the crops!
tutorial/crops.1624569036.txt.gz · Last modified: 2021/06/24 21:10 by safro