User Tools

Site Tools


tutorial:blockstate

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:blockstate [2024/08/24 14:13] solidblocktutorial:blockstate [2025/04/01 09:21] (current) – [Adding models and blockstates definitions for your blockstates] solidblock
Line 2: Line 2:
  
 ====== Giving a block state ====== ====== Giving a block state ======
-Every type of block in Minecraft is represented by a singular ''Block'' instance. This makes it impossible to change a specific block's state by simply changing the ''Block'' instance's state, as every other block of that type will be affected! But, what if you //do// want to give a singular block state, so it can change based on some condition?+Every type of block in Minecraft is represented by a singular ''Block'' instance. This makes it impossible to change a specific block's state by simply changing the ''Block'' instance's state, as every other block of that type will be affected! But, what if you //do// want to give a singular block state, so it can change based on some condition? This is what ''BlockState''s are for.
  
-This is what ''BlockState''are for. Say we wanted a block that can summon lightning, but only when charged up.   +===== Block state properties ===== 
 + 
 +Each block can have zero, one or multiple **block state properties**. Each block state property can have at lease two values. Vanilla properties, can be found in ''Properties'' (''net.minecraft.state.property.Properties''). Obviously, many blocks are simple and they do not have block state properties, so their block states are sole. 
 + 
 +Several examples: 
 +  * [[directionalblock|Directional block]], the block state property used is ''Properties.HORIZONTAL_FACING'', whose value can be four horizontal directions 
 +  * [[waterloggable|Waterloggable block]], the block state property used is ''Properties.WATERLOGGED'', whose value can be true and false 
 + 
 +===== Custom block state property: a chargeable block as an example ===== 
 + 
 +Say we wanted a block that can summon lightning, but only when charged up.   
      
 First we define the boolean property of the block - whether or not it is charged (careful not to import the wrong ''BooleanProperty''), and register the block within the mod initializer. (If you directly register the block in the static field in the ''ChargeableBlock'' class, the mod initializer may totally ignore it if the class is not initialized.) First we define the boolean property of the block - whether or not it is charged (careful not to import the wrong ''BooleanProperty''), and register the block within the mod initializer. (If you directly register the block in the static field in the ''ChargeableBlock'' class, the mod initializer may totally ignore it if the class is not initialized.)
  
-In fact, you can also use existing properties defined in vanilla, which can be found in ''Properties'' (''net.minecraft.state.property.Properties''). If you intend to define other types of properties, you may use ''IntProperty'' or ''EnumProperty''.+If you intend to define other types of properties, you may use ''IntProperty'' or ''EnumProperty''. 
 + 
 +Create the class first:
 <code java> <code java>
 public class ChargeableBlock extends Block { public class ChargeableBlock extends Block {
Line 16: Line 28:
       super(settings);       super(settings);
     }     }
-   
-    // The block instance. You can place it anywhere. Make the class is initialized. 
-    public static final ChargeableBlock CHARGEABLE_BLOCK = new ChargeableBlock(FabricBlockSettings.copyOf(Blocks.STONE)); 
 } }
 </code> </code>
Line 25: Line 34:
 <code java> <code java>
 public final class TutorialBlocks { public final class TutorialBlocks {
-    public static final Chargeable CHARGEABLE_BLOCK = register(new ChargeableBlock(Block.Settings.copy(Blocks.STONE))"chargeable_block");+    // For versions below 1.21.2: 
 +    public static final ChargeableBlock CHARGEABLE_BLOCK = register("chargeable_block", new ChargeableBlock(Block.Settings.copy(Blocks.STONE))); 
 +     
 +    // For versions since 1.21.2: 
 +    public static final Block CHARGEABLE_BLOCK = register("chargeable_block", ChargeableBlock::new, Block.Settings.copy(Blocks.STONE));
          
     // [...]     // [...]
Line 73: Line 86:
         if (world.getBlockState(pos).get(CHARGED)){         if (world.getBlockState(pos).get(CHARGED)){
             // Summoning the Lighting Bolt at the block             // Summoning the Lighting Bolt at the block
-            LightningEntity lightningEntity = EntityType.LIGHTNING_BOLT.create(world);+            LightningEntity lightningEntity = EntityType.LIGHTNING_BOLT.create(world, SpawnReason.MOB_SUMMONED);
             lightningEntity.refreshPositionAfterTeleport(Vec3d.ofBottomCenter(pos));             lightningEntity.refreshPositionAfterTeleport(Vec3d.ofBottomCenter(pos));
             world.spawnEntity(lightningEntity);             world.spawnEntity(lightningEntity);
Line 84: Line 97:
 </code> </code>
  
-==== Adding models for your blockstates ====+==== Adding models and blockstates definitions for your blockstates ====
  
-You can also make the texture and model of your block change based on the state. This is done through a JSON file called a "blockstate JSON". All blocks need a blockstate JSON, whether they have multiple states or not, but the contents of the JSON can be as simple or complex as you like. If you want to change the textures of your block based on the state, you //will// need multiple models.+You can also make the texture and model of your block change based on the state. This is done through a JSON file called a "**block states definition**". All blocks need a blockstates definition, whether they have multiple states or not, but the contents of it can be as simple or complex as you like. If you want to change the textures of your block based on the state, you //will// need multiple models.
  
-Let's say you register an instance of ''Chargeable'' to the ID ''tutorial:chargeable_block''. Minecraft would look for a file at the location ''src/main/resources/assets/tutorial/blockstates/chargeable_block.json'' to load the state from. If you don't want your block to change models between states, the blockstate JSON can be very simple. It would look something like this:+Let's say you register an instance of ''Chargeable'' to the ID ''tutorial:chargeable_block''. Minecraft would look for a file at the location ''src/main/resources/assets/tutorial/blockstates/chargeable_block.json'' to load the state from. If you don't want your block to change models between states, the blockstates definition can be very simple. It would look something like this:
  
 <code JavaScript resources/assets/tutorial/blockstates/chargeable_block.json> <code JavaScript resources/assets/tutorial/blockstates/chargeable_block.json>
Line 116: Line 129:
 </code> </code>
  
-In this JSON, there are two variants, one for each possibility of the ''CHARGED'' property we defined above. Since we gave the property the string name of ''charged'' in the Java, that's what we use here. Booleans only have two states, but if you use properties based on integers or enums, you'll have more variants. +In this blockstates definition, there are two variants, one for each possibility of the ''CHARGED'' property we defined above. Since we gave the property the string name of ''charged'' in the Java, that's what we use here. Booleans only have two states, but if you use properties based on integers or enums, you'll have more variants. 
  
 Variants are based on possible permutations of the properties added to your block. A property can be totally ignored in the blockstate JSON if you want, like in the first blockstate JSON where we ignored the ''charged'' property, but if you want to include a property in one variant, it must be included in //all// variants. If ''tutorial:chargeable_block'' also had a boolean property called ''glowing'', and you wanted to change the model based on whether it was glowing and based on whether it was charged, you would need four variants: charged off and glowing off, charged on and glowing off, charged off and glowing on, and charged on and glowing on. The same model can be assigned to multiple variants if you need it to be. Variants are based on possible permutations of the properties added to your block. A property can be totally ignored in the blockstate JSON if you want, like in the first blockstate JSON where we ignored the ''charged'' property, but if you want to include a property in one variant, it must be included in //all// variants. If ''tutorial:chargeable_block'' also had a boolean property called ''glowing'', and you wanted to change the model based on whether it was glowing and based on whether it was charged, you would need four variants: charged off and glowing off, charged on and glowing off, charged off and glowing on, and charged on and glowing on. The same model can be assigned to multiple variants if you need it to be.
  
-This is only a simple introduction to blockstate JSONsAll of the tricks you can do with blockstate and model JSONs are documented on the [[https://minecraft.wiki/Model|Minecraft wiki page]], along with examples of how the features are used in vanilla. Best of luck!+This is only a simple introduction to blockstates definitionsYou can visit Minecraft Wiki for all of the tricks you can do with [[https://minecraft.wiki/Model|models]] and [[https://minecraft.wiki/Blockstates_definition|blockstates definitions]], along with examples of how the features are used in vanilla. You can also [[datagen_model|generate models with data generator]]. Best of luck!
  
 ==== A note about performance ==== ==== A note about performance ====
tutorial/blockstate.1724508802.txt.gz · Last modified: 2024/08/24 14:13 by solidblock