tutorial:blockentity
Differences
This shows you the differences between two versions of the page.
Both sides previous revisionPrevious revisionNext revision | Previous revision | ||
tutorial:blockentity [2024/06/13 08:56] – update outdated read nbt method s1lverposting | tutorial:blockentity [2025/04/01 12:20] (current) – [Block entity ticking] solidblock | ||
---|---|---|---|
Line 1: | Line 1: | ||
====== Adding a BlockEntity ====== | ====== Adding a BlockEntity ====== | ||
- | ===== Introduction ===== | + | A **block entity** is primarily used to store data within blocks. Before creating one, you will need a [[blocks|Block]]. This tutorial will cover the creation of your BlockEntity class, and its registration. |
- | A BlockEntity is primarily used to store data within blocks. Before creating one, you will need a [[tutorial: | + | ===== Creating |
- | ===== Creating a BlockEntity | + | The simplest block entity simply extends '' |
- | The simplest Block Entity simply extends '' | + | < |
- | + | ||
- | <code java> | + | |
public class DemoBlockEntity extends BlockEntity { | public class DemoBlockEntity extends BlockEntity { | ||
public DemoBlockEntity(BlockPos pos, BlockState state) { | public DemoBlockEntity(BlockPos pos, BlockState state) { | ||
- | super(ExampleMod.DEMO_BLOCK_ENTITY, pos, state); | + | super(TutorialBlockEntityTypes.DEMO_BLOCK, pos, state); |
} | } | ||
} | } | ||
</ | </ | ||
- | Please ensure that the constructor only takes the two parameters, otherwise the method reference '' | + | Please ensure that the constructor only takes the two parameters, otherwise the method reference '' |
- | Block entities support a variety of methods to enable functionality such as serialization to and deserialization from NBT, ticking, providing inventories, | + | Block entities support a variety of methods to enable functionality such as serialization to and deserialization from NBT, providing inventories, |
- | ===== Registering your BlockEntity ===== | + | |
- | Once you have created the '' | + | ===== Registering block and block entities ===== |
- | The '' | + | Once you have created the '' |
- | <code java> | + | The '' |
- | public static final BlockEntityType< | + | |
- | Registries.BLOCK_ENTITY_TYPE, | + | < |
- | new Identifier("tutorial", | + | public final class TutorialBlocks { |
- | | + | |
- | | + | |
+ | // For versions before 1.21.2 | ||
+ | // public static final DemoBlock DEMO_BLOCK | ||
+ | |||
+ | // For version 1.21.2 and later | ||
+ | public static final DemoBlock DEMO_BLOCK = register(" | ||
+ | |||
+ | [...] | ||
+ | } | ||
</ | </ | ||
- | The block entity type defines that only the '' | + | <code java TutorialBlockEntityTypes.java> |
+ | public class TutorialBlockEntityTypes { | ||
+ | public static <T extends BlockEntityType<?>> | ||
+ | return Registry.register(Registries.BLOCK_ENTITY_TYPE, Identifier.of(" | ||
+ | } | ||
- | ==== Connecting a Block Entity to a Block ==== | + | public static final BlockEntityType< |
+ | " | ||
+ | // For versions before 1.21.2, please use BlockEntityType.Builder. | ||
+ | FabricBlockEntityTypeBuilder.create(DemoBlockEntity:: | ||
+ | ); | ||
+ | |||
+ | public static void initialize() { | ||
+ | } | ||
+ | } | ||
- | Once your '' | + | </code> |
- | + | ||
- | < | + | |
- | public class DemoBlock extends Block implements BlockEntityProvider { | + | |
+ | Remember to refer to the '' | ||
+ | <code java ExampleMod.java> | ||
+ | public class ExampleMod implements ModInitializer { | ||
[...] | [...] | ||
+ | | ||
@Override | @Override | ||
- | public | + | public |
- | | + | |
+ | |||
+ | TutorialBlockEntityTypes.initialize(); | ||
} | } | ||
} | } | ||
</ | </ | ||
- | ===== Serializing Data ===== | + | For old versions, if you cannot access '' |
- | If you want to store any data in your '' | + | The block entity type defines that only the '' |
- | '' | + | > **Note:** Like other blocks, the block also needs a block model and an item model, and may also need a loot table, see [[blocks]] for how to create them. As for loot tables, [[blockentity_sync_itemstack|subsequent tutorials]] will cover how to improve |
- | Knowing this, the example below demonstrates saving an integer from your '' | + | ===== Connecting |
- | <code java> | + | Once your '' |
- | public class DemoBlockEntity extends BlockEntity { | + | |
- | // Store the current value of the number | + | <code java DemoBlock.java> |
- | | + | public class DemoBlock extends BlockWithEntity { |
- | + | public | |
- | public | + | super(settings); |
- | super(ExampleMod.DEMO_BLOCK_ENTITY, | + | |
} | } | ||
- | + | ||
- | // Serialize the BlockEntity | + | |
@Override | @Override | ||
- | | + | |
- | | + | |
- | nbt.putInt(" | + | } |
- | super.writeNbt(nbt, wrapper); | + | @Override |
+ | public BlockEntity createBlockEntity(BlockPos pos, BlockState state) { | ||
+ | return new DemoBlockEntity(pos, | ||
} | } | ||
- | } | ||
- | </ | ||
- | In order to read the data, you will also need to override '' | + | |
- | + | | |
- | <code java> | + | |
- | // Deserialize the BlockEntity | + | |
- | @Override | + | |
- | public void readNbt(NbtCompound nbt, RegistryWrapper.WrapperLookup wrapper) { | + | |
- | super.readNbt(nbt, | + | |
- | | + | |
- | number = nbt.getInt(" | + | |
} | } | ||
</ | </ | ||
- | Once you have implemented the '' | + | Overriding |
- | + | ||
- | ===== Sync data from server to client ===== | + | |
- | The data is read in the server world usually. Most data are not needed by the client, for example, your client does not need to know what's in the chest or furnace, until you open the GUI. But for some block entities, such as signs and banners, you have to inform the client of the data of the block entity, for example, for rendering. | + | |
- | + | ||
- | For version 1.17.1 and below, implement '' | + | |
- | + | ||
- | For version 1.18 and above, override '' | + | |
- | <code java> | + | |
- | @Nullable | + | |
- | @Override | + | |
- | public Packet< | + | |
- | return BlockEntityUpdateS2CPacket.create(this); | + | |
- | } | + | |
- | + | ||
- | @Override | + | |
- | public NbtCompound toInitialChunkDataNbt() { | + | |
- | return createNbt(); | + | |
- | } | + | |
- | </ | + | |
- | **Warning**: | + | |
- | + | ||
- | ===== Block Entity Ticking ===== | + | |
- | 1.17 has added static ticking, where before you'd implement the '' | + | |
+ | ===== Block entity ticking ===== | ||
+ | Ticking means the block should run something on every tick (which is 1/20 second). For your block to tick, you would normally use '' | ||
In your '' | In your '' | ||
- | <code java> | + | < |
public class DemoBlock extends BlockWithEntity { | public class DemoBlock extends BlockWithEntity { | ||
[...] | [...] | ||
- | | + | |
- | public BlockRenderType getRenderType(BlockState state) { | + | |
- | // With inheriting from BlockWithEntity this defaults to INVISIBLE, so we need to change that! | + | |
- | return BlockRenderType.MODEL; | + | |
- | } | + | |
@Override | @Override | ||
public <T extends BlockEntity> | public <T extends BlockEntity> | ||
- | return | + | |
+ | | ||
} | } | ||
} | } | ||
</ | </ | ||
And in your '' | And in your '' | ||
- | <code java> | + | < |
- | public class DemoBlockEntity extends BlockEntity { | + | public class DemoBlockEntity extends BlockEntity |
- | | + | |
- | | + | |
- | | + | |
- | public static void tick(World world, BlockPos pos, BlockState state, DemoBlockEntity | + | public static void tick(World world, BlockPos pos, BlockState state, DemoBlockEntity |
[...] | [...] | ||
} | } | ||
Line 146: | Line 133: | ||
</ | </ | ||
- | ===== Overview | + | ===== Next steps ===== |
+ | |||
+ | You should now have your very own '' | ||
- | You should now have your very own '' | + | You also learned how to add ticking for it. Next step, you can try some other complex operations for the block entities, such as: |
+ | * [[blockentity_modify_data|Modifying block entity data]] | ||
+ | * [[inventory|Storing items in the block entity as an inventory]] | ||
+ | * [[blockentityrenderers|Using block entity renderers | ||
+ | * [[screenhandler|Creating a container block]] |
tutorial/blockentity.1718268962.txt.gz · Last modified: 2024/06/13 08:56 by s1lverposting