public class BoxBlockEntity extends BlockEntity implements NamedScreenHandlerFactory, ImplementedInventory { private final DefaultedList inventory = DefaultedList.ofSize(9, ItemStack.EMPTY); public BoxBlockEntity(BlockPos pos, BlockState state) { super(ExampleMod.BOX_BLOCK_ENTITY, pos, state); } // From the ImplementedInventory Interface @Override public DefaultedList getItems() { return inventory; } // These Methods are from the NamedScreenHandlerFactory Interface // createMenu creates the ScreenHandler itself // `getDisplayName` will Provide its name which is normally shown at the top @Override public ScreenHandler createMenu(int syncId, PlayerInventory playerInventory, PlayerEntity player) { // We provide *this* to the screenHandler as our class Implements Inventory // Only the Server has the Inventory at the start, this will be synced to the client in the ScreenHandler return new BoxScreenHandler(syncId, playerInventory, this); } @Override public Text getDisplayName() { // for 1.19+ return Text.translatable(getCachedState().getBlock().getTranslationKey()); // for earlier versions // return new TranslatableText(getCachedState().getBlock().getTranslationKey()); } // For the following two methods, for earlier versions, remove the parameter `registryLookup`. @Override public void readNbt(NbtCompound nbt, RegistryWrapper.WrapperLookup registryLookup) { super.readNbt(nbt, registryLookup); Inventories.readNbt(nbt, this.inventory, registryLookup); } @Override public NbtCompound writeNbt(NbtCompound nbt, RegistryWrapper.WrapperLookup registryLookup) { super.writeNbt(nbt, registryLookup); Inventories.writeNbt(nbt, this.inventory, registryLookup); return nbt; } }