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 [2022/12/15 16:47] solidblocktutorial:blockstate [2024/10/27 14:57] (current) solidblock
Line 1: Line 1:
 +~~REDIRECT>https://docs.fabricmc.net/develop/blocks/blockstates~~
 +
 ====== Giving a block state ====== ====== Giving a block state ======
-Every type of block in Minecraft is represented by a singular ''Block'' instance. +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 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! +This is what ''BlockState''s are for. Say we wanted a block that can summon lightning, but only when charged up.   
-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.  +
-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!):+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''
 + 
 +Create the class first:
 <code java> <code java>
 public class ChargeableBlock extends Block { public class ChargeableBlock extends Block {
     public static final BooleanProperty CHARGED = BooleanProperty.of("charged");     public static final BooleanProperty CHARGED = BooleanProperty.of("charged");
          
-    // The block instanceYou can place it anywhere+    public ChargeableBlock(Settings settings) { 
-    public static final ChargeableBlock CHARGEABLE_BLOCK = Registry.register( +      super(settings); 
-        Registry.BLOCK, +    } 
-        new Identifier("tutorial", "chargeable_block"), +
-        new ChargeableBlock( /* write anything appropriate here */ ));+</code> 
 + 
 +We register the blocks in the form described in [[blocks]]. 
 +<code java> 
 +public final class TutorialBlocks { 
 +    // For versions below 1.21.2: 
 +    public static final Chargeable CHARGEABLE_BLOCK = register("chargeable_block", new ChargeableBlock(Block.Settings.copy(Blocks.STONE))); 
 +    // For versions since 1.21.2: 
 +    public static final Chargeable CHARGEABLE_BLOCK = register("chargeable_block", ChargeableBlock::new, Block.Settings.copy(Blocks.STONE)); 
 +     
 +    // [...]
 } }
 </code> </code>
Line 30: Line 43:
 } }
 </code> </code>
-Then we need to set the default state of our property in the block constructor (To set multiple propertieschain ''with()'' calls):+ 
 +Then we need to set the default state of our property. Go to the constructor of the class we created just nowand modify it like this:
 <code java> <code java>
 public class ChargeableBlock extends Block { public class ChargeableBlock extends Block {
-    [...] 
     public ChargeableBlock(Settings settings) {     public ChargeableBlock(Settings settings) {
         super(settings);         super(settings);
Line 46: Line 59:
     [...]     [...]
     @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, BlockHitResult hit) {
         player.playSound(SoundEvents.BLOCK_RESPAWN_ANCHOR_CHARGE, 1, 1);         player.playSound(SoundEvents.BLOCK_RESPAWN_ANCHOR_CHARGE, 1, 1);
         world.setBlockState(pos, state.with(CHARGED, true));         world.setBlockState(pos, state.with(CHARGED, true));
Line 62: Line 75:
         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 = (LightningEntity) EntityType.LIGHTNING_BOLT.create(world);+            LightningEntity lightningEntity = EntityType.LIGHTNING_BOLT.create(world);
             lightningEntity.refreshPositionAfterTeleport(Vec3d.ofBottomCenter(pos));             lightningEntity.refreshPositionAfterTeleport(Vec3d.ofBottomCenter(pos));
             world.spawnEntity(lightningEntity);             world.spawnEntity(lightningEntity);
Line 109: Line 122:
 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 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.wiki/Model|Minecraft wiki page]], 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 blockstate for a block is registered when the ''Block'' object is initialized. 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 reasonblocks 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
 + 
 +As all possible states have been built, an equal state for a block is a same object, and the ''with'' method returns an existing object, instead of creating a new object - which means, for example, ''CHARGEABLE_BLOCK.getDefaultState().with(CHARGED, true) == CHARGEABLE_BLOCK.getDefaultState().with(CHARGED, true)'' returns ''true''.
tutorial/blockstate.1671122843.txt.gz · Last modified: 2022/12/15 16:47 by solidblock