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
Next revisionBoth sides next revision
tutorial:blockstate [2020/03/19 10:10] – 1.15 juuztutorial:blockstate [2021/07/18 03:06] – The function which the old article was using, getHardness(), was incorrect. I changed what the blockstates did and how they did them. Instead of changing the hardness, I changed the "charge" value, which summons lightning. tsunaminal
Line 5: Line 5:
 But, what if you //do// want to give a singular block state, so it can change based on some condition? 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''s are for. 
-Say we wanted a block to have a hardness of ''0.5'' normally, but if we right click it before we try to break it, +Say we wanted a block that can summon lightning, but only when charged up.   
-it would become harder and gain a hardness of ''2''.   +
      
-First we define the boolean property of the block - whether or not it is hard (careful not to import the wrong BooleanProperty!):+First we define the boolean property of the block - whether or not it is charged (careful not to import the wrong BooleanProperty!):
 <code java> <code java>
 public class MyBlock extends Block { public class MyBlock extends Block {
-    public static final BooleanProperty HARDENED = BooleanProperty.of("hardened");+    public static final BooleanProperty CHARGED = BooleanProperty.of("charged");
 } }
 </code> </code>
-Then we need to register the property by overriding ''appendProperties'':+Then we need to register the properties of the block by overriding ''appendProperties'', and then add the ''CHARGED'' property:
 <code java> <code java>
 public class MyBlock extends Block { public class MyBlock extends Block {
Line 20: Line 19:
     @Override     @Override
     protected void appendProperties(StateManager.Builder<Block, BlockState> stateManager) {     protected void appendProperties(StateManager.Builder<Block, BlockState> stateManager) {
-        stateManager.add(HARDENED);+        stateManager.add(CHARGED);
     }     }
          
 } }
 </code> </code>
-Then we need to set the default state of our property in the block constructor:+Then we need to set the default state of our property in the block constructor (To set multiple properties, chain ''with()'' calls):
 <code java> <code java>
 public class MyBlock extends Block { public class MyBlock extends Block {
Line 31: Line 30:
     public MyBlock(Settings settings) {     public MyBlock(Settings settings) {
         super(settings);         super(settings);
-        setDefaultState(getStateManager().getDefaultState().with(HARDENED, false));+        setDefaultState(getStateManager().getDefaultState().with(CHARGED, false));
     }     }
          
 } }
 </code> </code>
-(To set multiple propertieschain ''with()'' calls) +Nowwe need to be able to charge the block, through the ''onUse'' functionwith the ''world.setBlockState()'' function inside of it (The ''playSound'' is completely optional, but it helps us know that the block is charged).
- +
-Nowto set the property we need to call  ''world.setBlockState()'':   +
-      +
-(Replace ''MyBlocks.MY_BLOCK_INSTANCE'' with your block's instance)+
 <code java> <code java>
 public class MyBlock extends Block { public class MyBlock extends Block {
Line 46: Line 41:
     @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) {
-        world.setBlockState(pos, MyBlocks.MY_BLOCK_INSTANCE.getDefaultState().with(HARDENED, true));+        player.playSound(SoundEvents.BLOCK_RESPAWN_ANCHOR_CHARGE, 1, 1); 
 +        world.setBlockState(pos, state.with(ACTIVATED, true));
         return ActionResult.SUCCESS;         return ActionResult.SUCCESS;
     }     }
 } }
 </code> </code>
-And to use the property we call ''blockState.get(<our-property-name>)'':+ 
 + 
 + 
 + 
 + 
 + 
 + 
 + 
 + 
 + 
 + 
 + 
 + 
 +And Finally, to use the ''CHARGED'' propertywe call ''onSteppedOn'', with ''world.getBlockState(pos).get(ACTIVATED)'' inside of it:
 <code java> <code java>
 public class MyBlock extends Block { public class MyBlock extends Block {
     [...]     [...]
     @Override     @Override
-    public float getHardness(BlockState blockState, BlockView blockView, BlockPos pos) { +    public void onSteppedOn(World world, BlockPos pos, BlockState state, Entity entity) { 
-        boolean hardened = blockState.get(HARDENED); +        if (world.getBlockState(pos).get(ACTIVATED)){ 
-        if(hardenedreturn 2.0f+            //Summoning the Lighting Bolt at the block 
-        else return 0.5f;+            LightningEntity lightningEntity = (LightningEntity) EntityType.LIGHTNING_BOLT.create(world); 
 +            lightningEntity.refreshPositionAfterTeleport(Vec3d.ofBottomCenter(pos)); 
 +            world.spawnEntity(lightningEntity)
 +        
 + 
 +        world.setBlockState(pos, state.with(ACTIVATED, false)); 
 +        super.onSteppedOn(world, pos, state, entity);
     }     }
 } }
Line 85: Line 100:
 - The ''"model"'' property is always passed an ID of a model. In this case, the game will look at the location ''src/main/resources/assets/mymod/models/block/my_block.json''. The ID here can be anything. It doesn't //need// to be the same as your block's ID, but if you only have one variant, it probably should. Block models have their own setup, which is documented very well on the Minecraft wiki page linked below. You can either write the JSON by hand or use a program like [[https://blockbench.net|Blockbench]] to generate it more easily. - The ''"model"'' property is always passed an ID of a model. In this case, the game will look at the location ''src/main/resources/assets/mymod/models/block/my_block.json''. The ID here can be anything. It doesn't //need// to be the same as your block's ID, but if you only have one variant, it probably should. Block models have their own setup, which is documented very well on the Minecraft wiki page linked below. You can either write the JSON by hand or use a program like [[https://blockbench.net|Blockbench]] to generate it more easily.
  
-If you //do// want to have different models for each blockstate, you'd want to add multiple variants. For the same ''src/main/resources/assets/mymod/blockstates/my_block.json'' location we used above, your could would probably look like such:+If you want to have different models for each blockstate, you should add multiple variants. For the same ''src/main/resources/assets/mymod/blockstates/my_block.json'' location we used above, your model file would probably look like such:
  
 <code JavaScript resources/assets/mymod/blockstates/my_block.json> <code JavaScript resources/assets/mymod/blockstates/my_block.json>
 { {
     "variants": {     "variants": {
-        "hardened=false": { "model": "mymod:block/my_block" }, +        "charged=false": { "model": "mymod:block/my_block" }, 
-        "hardened=true": { "model": "mymod:block/my_block_hardened" }+        "charged=true": { "model": "mymod:block/my_block_charged" }
     }     }
 } }
 </code> </code>
  
-In this JSON, there are two variants, one for each possibility of the ''HARDENED'' property we defined above. Since we gave the property the string name of ''hardened'' 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 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. 
  
-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 ''hardened'' property, but if you want to include a property in one variant, it must be included in //all// variants. If ''mymod:my_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 hardened, you would need four variants: hardened off and glowing off, hardened on and glowing off, hardened off and glowing on, and hardened 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 ''mymod:my_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 JSONs. All of the tricks you can do with blockstate and model JSONs are documented on the [[https://minecraft.gamepedia.com/Model|Minecraft wiki]], along with examples of how the features are used in vanilla. Best of luck! This is only a simple introduction to blockstate JSONs. All of the tricks you can do with blockstate and model JSONs are documented on the [[https://minecraft.gamepedia.com/Model|Minecraft wiki]], along with examples of how the features are used in vanilla. Best of luck!
 ==== A note about performance ==== ==== A note about performance ====
 Every possible state of a block is registered at the start of the game. This means that if you have 14 boolean properties, the block has 2^14 = 16384 different states and 2^14 states are registered. For this reason blocks should not contain too many blockstate properties. Rather, blockstates should be mostly reserved for visuals, and [[tutorial:blockentity|Block Entities]] should be used for more advanced state. Every possible state of a block is registered at the start of the game. This means that if you have 14 boolean properties, the block has 2^14 = 16384 different states and 2^14 states are registered. For this reason blocks should not contain too many blockstate properties. Rather, blockstates should be mostly reserved for visuals, and [[tutorial:blockentity|Block Entities]] should be used for more advanced state.
tutorial/blockstate.txt · Last modified: 2023/11/18 08:13 by solidblock