This is an old revision of the document!
Table of Contents
Syncing BlockEntity data with ItemStack
Introduction
When you create a block with block entity, you might want to place the block with predefined NBT data from an ItemStack (of your BlockItem), or save the BlockEntity data in the ItemStack after breaking the block.
In this tutorial, we assume you have created a block (and block item) and the block entity, and stored data for it.
Block Drops with data
For a block to drop an ItemStack with the Nbt from the BlockEntity of the broken block, we only need to change the loot table.
For versions since 1.20.5
As data components have been introduced, you need to store the block entity data in the data components of the block item. This requires you to store nbt data as data components. See using_data_components about it.
If you'are using versions before 1.21, replace the word loot_table with loot_tables in the path.
- src/main/resources/data/tutorial/loot_table/blocks/demo_block.json
{ "pools": [ { "rolls": 1.0, "bonus_rolls": 0.0, "entries": [ { "name": "tutorial:demo_block", "type": "minecraft:item" } ], "conditions": [ { "condition": "minecraft:survives_explosion" } ] } ], "functions": [ { "source": "block_entity", "include": [ "tutorial:number" ], "function": "minecraft:copy_components" } ] }
where:
"include": the IDs of the data component types.
For versions before 1.20.5
Before version 1.20.5, data components were not introduced. Therefore, just copy nbt.
- src/main/resources/data/tutorial/loot_tables/blocks/demo_block.json
{ "type": "minecraft:block", "pools": [ { "rolls": 1.0, "entries": [ { "type": "minecraft:item", "name": "tutorial:demo_block", "functions": [ { "function": "minecraft:copy_nbt", "source": "block_entity", "ops": [ { "source": "number", "target": "BlockEntityTag.number", "op": "replace" } ] } ] } ] } ] }
where:
"source"is the key of the nbt we used in thewriteNbtandreadNbtmethods in ourDemoBlockEntityclass –"number""target"is the hierarchy in the nbt of droppedItemStack(sourceprefixed with the"BlockEntityTag"key, which is needed for placing the block back with the saved data) –"BlockEntityTag.number"
To save more fields, just add more replace operations (with source, target and op) to the %“ops”%% array.
Reading saved data in the tooltip
For versions since 1.20.5, to get the BlockEntity's data stored in the item stack, we can use get its data component.
For versions since 1.20.5:
- DemoBlock.class
public class DemoBlock extends BlockWithEntity { [...] @Override public void appendTooltip(ItemStack stack, Item.TooltipContext context, List<Text> tooltip, TooltipType options) { final Integer i = stack.get(TutorialDataComponentTypes.NUMBER); if (i == null) return; tooltip.add(Text.literal("Number: " + i)); } }
For versions before 1.20.5, we call getBlockEntityNbt, which internally calls getSubNbt.
For versions before 1.20.5:
- DemoBlock.class
public class DemoBlock extends BlockWithEntity { [...] @Override public void appendTooltip(ItemStack stack, BlockView world, List<Text> tooltip, TooltipContext context) { NbtCompound nbt = BlockItem.getBlockEntityNbt(stack); if (nbt == null) return; tooltip.add(Text.literal("Number: " + nbt.getInt("number")) } }
Changing ItemStack's BlockEntity data
We can change our tooltip to always display some default value even if the stack does not have any BlockEntity data.
public class DemoBlock extends Block implements BlockEntityProvider { [...] @Override public void appendTooltip(ItemStack stack, BlockView world, List<Text> tooltip, TooltipContext context) { NbtCompound nbt = BlockItem.getBlockEntityNbt(stack); if (nbt == null){ NbtCompound nbt = new NbtCompound(); nbt.putInt("number", 0); BlockItem.setBlockEntityNbt(stack, ExampleMod.DEMO_BLOCK_ENTITY, nbt); } tooltip.add(Text.literal("Number: "+nbt.getInt("number")) } }
Placing Block with data
Is automatic! As long as the data is in the “BlockEntityTag” subNbt (e.g. by using the BlockItem.getBlockEntityNbt and BlockItem.setBlockEntityNbt helper methods) under tag keys recognized by the readNbt method of the BlockEntity.
Helpful Reference
If something still isn't clear or you want more examples, I highly recommend looking at the Minecraft implementation of ShulkerBoxBlock and ShulkerBoxBlockEntity. That for example also implements Nameable interface and has code to save custom names through ItemStack and BlockEntity.
Loot Tables
More info on Loot tables on Minecraft Wiki.
Vanilla loot tables: .minecraft\versions\[version]\[version].jar\data\minecraft\loot_tables\
Also, this Loot Table Generator might be useful.