User Tools

Site Tools


tutorial:blockstate

This is an old revision of the document!


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? This is what BlockStates 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, 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:

public class MyBlock extends Block {
    public static final BooleanProperty MyBlockIsHard = BooleanProperty.of("is_hard");
}

Then we need to register the property by overriding appendProperties:

public class MyBlock extends Block {
    [...]
    @Override
    protected void appendProperties(StateFactory.Builder<Block, BlockState> stateFactory) {
        stateFactory.add(MyBlockIsHard);
    }
 
}

Then we need to set the default state of our property in the block constructor:

public class MyBlock extends Block {
    [...]
    public MyBlock(Settings settings) {
        super(settings);
        setDefaultState(getStateFactory().getDefaultState().with(MyBlockIsHard, false));
    }
 
}

Now, to set the property we need to call

world.setBlockState(<block-position>, <block-instance>.getDefaultState().with(<property-name>, <new-value>):

(Replace MyBlocks.MY_BLOCK_INSTANCE with your block's instance)

public class MyBlock extends Block {
    [...]
    @Override
    public boolean activate(BlockState state, World world, BlockPos pos, PlayerEntity player, Hand hand, BlockHitResult blockHitResult) {
        world.setBlockState(pos, MyBlocks.MY_BLOCK_INSTANCE.getDefaultState().with(MyBlockIsHard, true));
        return true;
    }
}

And to use the property we call blockState.get(<our-property-name>):

public class MyBlock extends Block {
    [...]
    @Override
    public float getHardness(BlockState blockState, BlockView blockView, BlockPos pos) {
        boolean isHard = blockState.get(MyBlockIsHard);
        if(isHard) return 2.0f;
        else return 0.5f;
    }
}

You can also make the texture of you block change based on the block state. [additional information needed]

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 Block Entities should be used for more advanced state.

tutorial/blockstate.1565124726.txt.gz · Last modified: 2019/08/06 20:52 by fudge