This is an old revision of the document!
−Table of Contents
Fabric Transfer API: Understanding Storage<ItemVariant>
This article is part of a series on the Fabric Transfer API. Link to the home page of the series.
This tutorial aims to give an overview of the Fabric Item Transfer API. Please make sure that you read the various fluid tutorials before reading this one, since most concepts used in the Fluid Storage API apply to the Item Transfer API.
Brief overview
The core message is: The Item Transfer API is used exactly the same as the Fluid Transfer API, but with ItemVariant
instead of FluidVariant
.
ItemVariant
Item variants represent the “type” of an item, i.e. the Minecraft `Item`, and also an optional NBT compound tag. They are immutable. The following examples are very similar to the FluidVariant
ones, since they are the same concept. Reading them is recommended though since ItemVariant
has a few nice functions to work with ItemStack
s.
// Creating an item variant from an item, without an NBT tag. ItemVariant ironVariant = ItemVariant.of(Items.IRON_INGOT); ironVariant.getItem() // returns Items.IRON_INGOT ironVariant.copyNbt() // returns a copy of the optional nbt tag, in this case null // Creating an item variant from an item, with an NBT tag. NbtCompound customTag = new NbtCompound(); customTag.putBoolean("magic", true); ItemVariant magicIron = ItemVariant.of(Items.IRON_INGOT, customTag); // Creating an item variant from an ItemStack ItemStack specialStack = new ItemStack(Items.IRON_INGOT); specialStack.setCustomName(new LiteralText("My Special Ingot")); ItemVariant specialIngot = ItemVariant.of(specialStack); // Further modifications to the ItemStack will not affect the ItemVariant since all the data is copied by of(...). // Creating an item stack from an item variant ItemStack size1 = specialIngot.toStack(); // no parameter -> count of the stack is 1 ItemStack anySize = specialIngot.toStack(32); // int parameter -> sets the count of the stack
Variants are always compared with .equals
, NEVER WITH ==
!
ironVariant.equals(ironVariant); // returns true ironVariant.equals(magicIron); // returns false // You can easily test if a variant has some item: ironVariant.isOf(Items.IRON_INGOT); // returns true magicIron.isOf(Items.IRON_INGOT); // returns true // The matches function can be used to compare an item variant with an item stack: ironVariant.matches(specialStack); // returns false specialIngot.matches(specialStack); // returns true
They can easily be serialized to and from NBT or network packets:
// NBT NbtCompound compound = variant.toNbt(); ItemVariant variant = ItemVariant.fromNbt(compound); // Network packets variant.toPacket(buf); ItemVariant variant = ItemVariant.fromPacket(buf);
Finding Storage<ItemVariant> instances in the world
Storage<ItemVariant>
is the type used to represent item containers in the Transfer API.
It is queried and exposed through the ItemStorage.SIDED
lookup for access by other mods:
// Finding an instance @Nullable Storage<ItemVariant> maybeStorage = ItemStorage.SIDED.find(world, pos, side); // To expose an instance, use one of the ItemStorage.SIDED.registerFor* functions
To learn how to use Storage
, please refer to the Storage<FluidVariant> tutorial since the methods are exactly the same.
Dealing with Inventory/SidedInventory and PlayerInventory
Sometimes, it is necessary to convert some Inventory
to a Storage<ItemVariant>
. For that purpose, InventoryStorage.of(inventory, side) can be used.
InventoryStorage
also allows recovering each slot separately through the getSlot
and getSlots
functions.
The side @Nullable Direction
parameter exists so that if a non-null side is specified and the inventory is a SidedInventory
, canInsert
and canExtract
are checked before insertion and extraction respectively.
PlayerInventoryStorage serves a similar purpose, but for player inventories. Make sure to read its documentation, it contains very useful functions such as offerOrDrop
.