Wednesday, 14 January 2015

TileEntity

To skip straight to sample code for TileEntities, click here (MBE20).

A TileEntity is used for one of two reasons
  • To store extra information about a block location (eg a Chest); and/or
  • To provide advanced or animated rendering for a particular block (eg Piston, Beacon)
A standard block location can only store a single number from 0 - 15.  There are some special blocks which need to store more information than a standard Block - for example the BlockSign or BlockChest.  A TileEntity is used in this case.  TileEntities are treated differently from ordinary Blocks.  Each TileEntity instance corresponds to a single Block at a particular [x,y,z] location.  Minecraft maintains a list of TileEntity objects, each of which stores unique information such as the text on a sign or the contents of a chest. 

When rendering, the Minecraft may either render the underlying Block, the TileEntity (using TileEntitySpecialRenderer), or both.  The major difference is that the TileEntity is rendered fresh every frame, whereas the Block uses a 'cached render'  that is only refreshed when the block changes.  This means that if you want your Block to be animated, you need to either use an animated texture for your Block, or use a TileEntity.

The key points to know about TileEntities are:
  1. Each Tile Entity has a integer [x,y,z] location.  It is associated with a Block at that location, there are several Block and TileEntity methods that are used to link the two and keep them linked.   Your Block should either implement ITileEntityProvider or should override hasTileEntity(IBlockState state).
  2. Data storage and synchronisation is as illustrated in the diagram below:
    a) If the TileEntity is used to store permanent information (eg the writing on a sign for TileEntitySign), the readFromNBT() and writeFromNBT()  methods are used to create NBT information suitable for the saved game.  See here for more information about NBT.
    b) 
    If the client TileEntity needs a copy of the server TileEntity information, the getDescriptionPacket() and onDataPacket() methods are used.  If the TileEntity is only being used for animation, this is not required.  These methods are called when the world is initially loaded and when a block update is triggered (eg player places a new block).
  3. If your TileEntity implements IUpdatePlayerListBox, it receives a call to its update() method every tick on both the client and the server side.  This can be used for calculations, animation, responding to nearby objects, etc.

Data flow and synchronisation for a typical TileEntity



2 comments:

  1. This comment has been removed by the author.

    ReplyDelete
  2. This has changed slightly for 10.1.2. The principles are the same, however the methods are now:
    getUpdatePacket(), onDataPacket() for single tileentity updates, and
    getUpdateTag(), handleUpdateTag() for multiple tileentity updates (eg chunk loading)
    The packet is SPacketUpdateTileEntity

    ReplyDelete