Block Entities
BlockEntities
are like simplified Entities
that are bound to a Block.
They are used to store dynamic data, execute tick based tasks, and dynamic rendering.
Some examples from vanilla Minecraft would be handling of inventories on chests, smelting logic on furnaces, or area effects on beacons.
More advanced examples exist in mods, such as quarries, sorting machines, pipes, and displays.
BlockEntities
aren't a solution for everything and they can cause lag when used wrongly.
When possible, try to avoid them.
Registering
Block Entities are created and removed dynamically and as such are not registry objects on their own.
In order to create a BlockEntity
, you need to extend the BlockEntity
class. As such, another object is registered instead to easily create and refer to the type of the dynamic object. For a BlockEntity
, these are known as BlockEntityType
s.
A BlockEntityType
can be registered like any other registry object. To construct a BlockEntityType
, its builder form can be used via BlockEntityType$Builder#of
. This takes in two arguments: a BlockEntityType.BlockEntitySupplier which takes in a BlockPos
and BlockState
to create a new instance of the associated BlockEntity
, and a varargs of Block
s which this BlockEntity
can be attached to. Building the BlockEntityType
is done by calling BlockEntityType$Builder#build
. This takes in a Type
which represents the type-safe reference used to refer to this registry object in a DataFixer
. Since DataFixer
s are an optional system to use for mods, this can be passed as null
.
// For some DeferredRegister<BlockEntityType<?>> REGISTER
public static final RegistryObject<BlockEntityType<MyBE>> MY_BE = REGISTER.register("mybe", () -> BlockEntityType.Builder.of(MyBE::new, validBlocks).build(null));
// In MyBE, a BlockEntity subclass
public MyBE(BlockPos pos, BlockState state) {
super(MY_BE.get(), pos, state);
}
Creating a BlockEntity
To create a BlockEntity
and attach it to a Block
, the EntityBlock
interface must be implemented on your Block
subclass. The method EntityBlock#newBlockEntity(BlockPos, BlockState)
must be implemented and return a new instance of your BlockEntity
.