A number of advanced blocks use "containers" - these are blocks that can store items, including
- crafting table
It is relatively easy to implement a custom container once you understand how the components fit together and communicate with each other. As shown in the diagram below:
- The data about the container is stored in the TileEntity for that block. Typical examples of the data are -what items are in the container, furnace fuel burning time & smelting time.
- The "master copy" of the TileEntity data is always on the server. During initial load, and when chunk data is updated/resent, the client copy is updated as for normal TileEntities (using NBT in getDescriptionPacket() and onDataPacket() - see here.
- While the GUI is open, two extra classes are used to synchronise the data in real time and display it interactively to the user(s). These are:
a) GuiContainer, which specifies the layout of the GUI, retrieves items and other data (eg progress bars) for display, and interacts with the user. The basic element of the GuiContainer is a number of "Slots" where items can be placed.
b) Container, which collates the information from various sources into a single instance that the GUIContainer can use. For example, the ContainerFurnace collates information from the TileEntityFurnace and player inventory. It provides a consecutive list of Slots numbered from 0 .. N-1, where (eg) 0..35 might come from the player inventory, and 36 - 44 might come from the TileEntity.
- The Server Container is responsible for detecting changes to the Container that might need updating:
a) for any clients which have the container open (eg multiple users accessing the same chest) - sendSlotContents() for items and sendProgressBarUpdate() for other data
b) for other clients - marking the block for update (which then uses the getDescriptionPacket() / onDataPacket() to update the client copy
- Simple information can be sent from the client container to the server container using the crafters member variable of the container - icrafting.sendProgressBarUpdate() and icrafting.updateProgressBar().
- getServerGuiElement() for the server side Container
- getClientGuiElement() for the GuiContainer (which contains a Container during construction)