Alright, I spent hours figuring this one out. There are a myriad of methods you need to implement besides writeToNBT() and readFromNBT(NBTTagCompound). A working example of a luckyblock tileentity is:
import net.minecraft.block.state.IBlockState;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.network.NetworkManager;
import net.minecraft.network.play.server.SPacketUpdateTileEntity;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
public class TileEntityLuckyBlock extends TileEntity {
public static final int MAX_TYPE = 1;
private int luck;
private int type; // 0: normal, 1: well
private boolean isPlayerEditing;
public TileEntityLuckyBlock() {
this.luck = 0;
this.type = 0;
this.isPlayerEditing = false;
}
public int getLuck() {
return luck;
}
public void setLuck(int newLuck) {
luck = newLuck;
markDirty(); // important
}
public int getType() {
return type;
}
public void setType(int newType) {
type = newType;
markDirty(); // important
}
public boolean isPlayerEditing() {
return isPlayerEditing;
}
public void setPlayerEditing(boolean editing) {
isPlayerEditing = editing; // not marked because this field doesn't need to be persistent
}
public void executeDrop(World world, BlockPos pos, EntityPlayer breaker) {
switch(type) {
case 0:
LBDrops.executeDrop(luck, world, pos, breaker);
break;
case 1:
{
EntityPlayer player = world.getClosestPlayer(pos.getX() + 0.5, pos.getY() + 0.5, pos.getZ() + 0.5, 16.0 * 16.0 * 32.0, false);
if(player != null)
LBDrops.executeWellDrop(luck, world, pos, player, false);
break;
}
}
}
/** Everything below here is an absolute MUST have. **/
@Override
public boolean shouldRefresh(World world, BlockPos pos, IBlockState oldState, IBlockState newSate) {
return false;
}
@Override
public NBTTagCompound getTileData() {
return serializeNBT();
}
@Override
public SPacketUpdateTileEntity getUpdatePacket() {
NBTTagCompound nbt = new NBTTagCompound();
writeToNBT(nbt);
return new SPacketUpdateTileEntity(this.pos, 1, nbt);
}
@Override
public NBTTagCompound getUpdateTag() {
NBTTagCompound nbt = new NBTTagCompound();
writeToNBT(nbt);
return nbt;
}
@Override
public void onDataPacket(NetworkManager manager, SPacketUpdateTileEntity packet) {
readFromNBT(packet.getNbtCompound());
}
/** Obviously these mehtods will be different. **/
@Override
public NBTTagCompound writeToNBT(NBTTagCompound nbt) {
super.writeToNBT(nbt);
nbt.setInteger("luck", luck);
nbt.setInteger("type", type);
return nbt;
}
@Override
public void readFromNBT(NBTTagCompound nbt) {
super.readFromNBT(nbt);
luck = nbt.getInteger("luck");
type = nbt.getInteger("type");
isPlayerEditing = false;
}
}
So basically try copying the implementations of shouldRefresh, getTileData, getUpdatePacket, getUpdateTag, and onDataPacket. You will also need to schedule a render update in onDataPacket if you're rendering your tile entity.