Changes

37 bytes added ,  19:31, 15 July 2023
m
overwrite -> override
Line 9: Line 9:  
== Proper Usage of Block States ==
 
== Proper Usage of Block States ==
   −
<code><nowiki>BlockState</nowiki></code> is a flexible and powerful system, but it also has limitations. <code><nowiki>BlockState</nowiki></code>'s are immutable, and all combinations of their properties are generated on startup of the game. This means that having a <code><nowiki>BlockState</nowiki></code> with many properties and possible values will slow down the loading of the game, and befuddle anyone trying to make sense of your block logic.
+
<code><nowiki>BlockState</nowiki></code> is a flexible and powerful system, but it also has limitations. <code><nowiki>BlockState</nowiki></code>s are immutable, and all combinations of their properties are generated on startup of the game. This means that having a <code><nowiki>BlockState</nowiki></code> with many properties and possible values will slow down the loading of the game, and befuddle anyone trying to make sense of your block logic.
   −
Not all blocks and situations require the usage of <code><nowiki>BlockState</nowiki></code>; only the most basic properties of a block should be put into one, and any other situation is better off with having a <code><nowiki>TileEntity</nowiki></code> or being a separate <code><nowiki>Block</nowiki></code>. Always consider if you actually need to use a state for your purposes.
+
Not all blocks and situations require the usage of <code><nowiki>BlockState</nowiki></code>; only the most basic properties of a block should be put into one, and any other situation is better off with having a <code><nowiki>BlockEntity</nowiki></code> or being a separate <code><nowiki>Block</nowiki></code>. Always consider if you actually need to use a state for your purposes.
    
{{Colored box|title=Tip|content=A good rule of thumb is: '''if it has a different name, it should be a separate block'''.}}
 
{{Colored box|title=Tip|content=A good rule of thumb is: '''if it has a different name, it should be a separate block'''.}}
Line 31: Line 31:  
** Implements <code><nowiki>Property<E></nowiki></code>. Defines a property that can take on the values of an Enum class.
 
** Implements <code><nowiki>Property<E></nowiki></code>. Defines a property that can take on the values of an Enum class.
 
** Created by calling <code><nowiki>EnumProperty.create(String propertyName, Class<E> enumClass)</nowiki></code>.
 
** Created by calling <code><nowiki>EnumProperty.create(String propertyName, Class<E> enumClass)</nowiki></code>.
** It is also possible to use only a subset of the Enum values (e.g. <code><nowiki>RailShape</nowiki></code>'s that can only ascend and not turn). See the overloads of <code><nowiki>EnumProperty.create</nowiki></code>.
+
** It is also possible to use only a subset of the Enum values (e.g. <code><nowiki>RailShape</nowiki></code>s that can only ascend and not turn). See the overloads of <code><nowiki>EnumProperty.create</nowiki></code>.
 
* <code><nowiki>DirectionProperty</nowiki></code>
 
* <code><nowiki>DirectionProperty</nowiki></code>
 
** This is a convenience implementation of <code><nowiki>EnumProperty<Direction></nowiki></code>
 
** This is a convenience implementation of <code><nowiki>EnumProperty<Direction></nowiki></code>
Line 38: Line 38:  
The class <code><nowiki>BlockStateProperties</nowiki></code> contains shared vanilla properties which should be used or referenced whenever possible, in place of creating your own properties.
 
The class <code><nowiki>BlockStateProperties</nowiki></code> contains shared vanilla properties which should be used or referenced whenever possible, in place of creating your own properties.
   −
When you have your desired <code><nowiki>Property<></nowiki></code> objects, override <code><nowiki>Block#fillStateContainer(StateContainer$Builder)</nowiki></code> in your ''Block'' class. In that method, call <code><nowiki>StateContainer$Builder#add(...);</nowiki></code>  with the parameters as every <code><nowiki>Property<?></nowiki></code> you wish the block to have.
+
When you have your desired <code><nowiki>Property<></nowiki></code> objects, override <code><nowiki>Block#createBlockStateDefinition(StateDefinition$Builder)</nowiki></code> in your ''Block'' class. In that method, call <code><nowiki>StateDefinition$Builder#add(...);</nowiki></code>  with the parameters as every <code><nowiki>Property<?></nowiki></code> you wish the block to have.
   −
Every block will also have a "default" state that is automatically chosen for you. You can change this "default" state by calling the <code><nowiki>Block#setDefaultState(BlockState)</nowiki></code> method from your constructor. When your block is placed it will become this "default" state. An example from <code><nowiki>DoorBlock</nowiki></code>:
+
Every block will also have a "default" state that is automatically chosen for you. You can change this "default" state by calling the <code><nowiki>Block#registerDefaultState(BlockState)</nowiki></code> method from your constructor. When your block is placed it will become this "default" state. An example from <code><nowiki>DoorBlock</nowiki></code>:
    
<syntaxhighlight lang="java">
 
<syntaxhighlight lang="java">
this.setDefaultState(
+
this.registerDefaultState(
     this.stateContainer.getBaseState()
+
     this.stateDefinition.any()
         .with(FACING, Direction.NORTH)
+
         .setValue(FACING, Direction.NORTH)
         .with(OPEN, false)
+
         .setValue(OPEN, false)
         .with(HINGE, DoorHingeSide.LEFT)
+
         .setValue(HINGE, DoorHingeSide.LEFT)
         .with(POWERED, false)
+
         .setValue(POWERED, false)
         .with(HALF, DoubleBlockHalf.LOWER)
+
         .setValue(HALF, DoubleBlockHalf.LOWER)
 
);
 
);
</syntaxhighlight >
+
</syntaxhighlight>
   −
If you wish to change what <code><nowiki>BlockState</nowiki></code> is used when placing your block, you can overwrite <code><nowiki>Block#getStateForPlacement(BlockItemUseContext)</nowiki></code>. This can be used to, for example, set the direction of your block depending on where the player is standing when they place it.
+
If you wish to change what <code><nowiki>BlockState</nowiki></code> is used when placing your block, you can override <code><nowiki>Block#getStateForPlacement(BlockPlaceContext)</nowiki></code>. This can be used to, for example, set the direction of your block depending on where the player is standing when they place it.
   −
Because <code><nowiki>BlockState</nowiki></code>'s are immutable, and all combinations of their properties are generated on startup of the game, calling <code><nowiki>BlockState#with(IProperty<T>, T)</nowiki></code> will simply go to the <code><nowiki>Block</nowiki></code>'s <code><nowiki>StateContainer</nowiki></code> and request the <code><nowiki>BlockState</nowiki></code> with the set of values you want.
+
Because <code><nowiki>BlockState</nowiki></code>s are immutable, and all combinations of their properties are generated on startup of the game, calling <code><nowiki>BlockState#setValue(Property<T>, T)</nowiki></code> will simply go to the <code><nowiki>Block</nowiki></code>'s <code><nowiki>StateHolder</nowiki></code> and request the <code><nowiki>BlockState</nowiki></code> with the set of values you want.
   −
Because all possible <code><nowiki>BlockState</nowiki></code>'s are generated at startup, you are free and encouraged to use the reference equality operator (<code><nowiki>==</nowiki></code>) to check if two <code><nowiki>BlockState</nowiki></code>'s are equal.
+
Because all possible <code><nowiki>BlockState</nowiki></code>s are generated at startup, you are free and encouraged to use the reference equality operator (<code><nowiki>==</nowiki></code>) to check if two <code><nowiki>BlockState</nowiki></code>s are equal.
    
== Using <tt>BlockState</tt>s ==
 
== Using <tt>BlockState</tt>s ==
   −
You can get the value of a property by calling <code><nowiki>BlockState#get(IProperty<?>)</nowiki></code>, passing it the property you want to get the value of.
+
You can get the value of a property by calling <code><nowiki>BlockState#getValue(Property<?>)</nowiki></code>, passing it the property you want to get the value of.
If you want to get a <code><nowiki>BlockState</nowiki></code> with a different set of values, simply call <code><nowiki>BlockState#with(IProperty<T>, T)</nowiki></code> with the property and its value.
+
If you want to get a <code><nowiki>BlockState</nowiki></code> with a different set of values, simply call <code><nowiki>BlockState#setValue(Property<T>, T)</nowiki></code> with the property and its value.
   −
You can get and place <code><nowiki>BlockState</nowiki></code>'s in the world using <code><nowiki>World#setBlockState(BlockPos, BlockState)</nowiki></code> and <code><nowiki>World#getBlockState(BlockState)</nowiki></code>. If you are placing a <code><nowiki>Block</nowiki></code>, call <code><nowiki>Block#getDefaultState()</nowiki></code> to get the "default" state, and use subsequent calls to <code><nowiki>BlockState#with(IProperty<T>, T)</nowiki></code> as stated above to achieve the desired state.
+
You can get and place <code><nowiki>BlockState</nowiki></code>s in the level using <code><nowiki>Level#setBlockAndUpdate(BlockPos, BlockState)</nowiki></code> and <code><nowiki>Level#getBlockState(BlockPos)</nowiki></code>. If you are placing a <code><nowiki>Block</nowiki></code>, call <code><nowiki>Block#defaultBlockState()</nowiki></code> to get the "default" state, and use subsequent calls to <code><nowiki>BlockState#setValue(Property<T>, T)</nowiki></code> as stated above to achieve the desired state.
6

edits