Jump to content

[Solved] writeToNBT does not get called for the client TileEntity, only server

Lycanus Darkbinder

Recommended Posts

I have TileEntity with a field called isRemote that gets set in onBlockPlacedBy() based on world.isRemote.


When a block is placed, two TileEntity are created and the fields set to true and false. When I press ESC, writeToNBT() gets called only once and isRemote is false indicating this is the server TileEntity.


It seems that the TileEntity where isRemote is true never gets a call to writeToNBT(). I print to the console the value of isRemote every time the function is called and it never prints "true".

Link to comment
Share on other sites

I have TileEntity with a field called isRemote that gets set in onBlockPlacedBy() based on world.isRemote.

Why that?

has a field


. Use that.


Well for one, worldObj is not available while in the constructor. All properties from the TileEntity super class are NULL while in the constructor. My constructor accepts a boolean.


When a block is placed, two TileEntity are created and the fields set to true and false. When I press ESC, writeToNBT() gets called only once and isRemote is false indicating this is the server TileEntity.

Of course. Why should the client save any NBT data? The server is the side that manages the game, saves the world, etc. The client only has dummy values for everything.

Think of a dedicated server (connect via IP): Where should the client save the world to if it would?


On a singleplayer world, the chunkcache attempts to load the TileEntity for the client but fails so it builds a new one.


After the server TileEntity is loaded with readFromNBT, the call stack looks like this:


TileEntitySmartLight.<init>(World) line: 48   

BlockSmartLight.createTileEntity(World, int) line: 375   

Chunk.getChunkBlockTileEntity(int, int, int) line: 995  

ChunkCache.getBlockTileEntity(int, int, int) line: 115   

WorldRenderer.updateRenderer() line: 208   


The bolded part is where it falls down because the TileEntity is not saved so it builds a brand new one. Here's the piece from Chunk.getChunkBlockTileEntity

            if (tileentity == null)
                tileentity = Block.blocksList[l].createTileEntity(this.worldObj, meta);
                this.worldObj.setBlockTileEntity(this.xPosition * 16 + par1, par2, this.zPosition * 16 + par3, tileentity);


In the above code, this.worldObj is a WorldClient. Why is the client expecting chunkcache to have a TileEntity if, as you say, they're not supposed to be saved?



More importantly, could you please point me in the direction of some up-to-date documentation on how people save and load TileEntities? My TileEntity isn't even that fancy but it seems like it's a lot more work than advertised in the wiki.

Link to comment
Share on other sites

More importantly, could you please point me in the direction of some up-to-date documentation on how people save and load TileEntities? My TileEntity isn't even that fancy but it seems like it's a lot more work than advertised in the wiki.

It seems like you are doing or understanding something very wrong here.

To save a TE put the data you need into the NBTTagCompound passed to writeToNBT and read the data back in readFromNBT. Done.

If you need the data on the client, too, you need to sync it with packets.


Let me explain what's happening so you can better understand my issue:


1. Click "Single Player"

2. Choose a world and click "Play Selected World"

3. createAndLoadEntity() gets called (TileEntity.java)

4. This calls the default constructor of my TileEntitySmartLight (only here for breakpoint purposes)

5. Then my readFromNBT() gets called which indicates the server is requesting this TileEntity

6. Then WorldRenderer.updateRenderer() checks the chunkcache for a client side TileEntity

7. ChunkCache.getBlockTileEntity() calls chunk.getTileEntity()

8. This leads to BlockSmartLight.createTileEntity() indicating we're creating a client TileEntity

9. BlockSmartLight.getLightValue() gets called which has a parameter of IBlockAccess

10. IBlockAccess.getBlockTileEntity() returns the client TileEntity from #8, not the server TileEntity from #5


So, how do I synchronize the client TileEntity that getLightValue() is asking for when this is happening at world load and there is no function override between steps #5 and steps #6 when the game requests the two TileEntities?


It wouldn't be a problem if getLightValue() didn't use IBlockAccess but that always gets a client version of the TileEntity, it never loads a server version.


Any advice would be appreciated. I don't see how packets can help the situation but since I've not seen any good documentation on packets I can't really comment.





As for the constructor, I kept getting console messages "Ignoring entity with TileEntitySmartLight" until I added the constructor. Once I put it in (even an empty one) the messages stopped.

Link to comment
Share on other sites

You need to send packets in order for the client to get the TE from the server on entering the world, check out this thread, it may be of interest to you:



Thanks for that. It's still not clicking in my brain how that all works.


createTileEntity() has to be called for the client because it doesn't exist yet. This is where my disconnect comes in. I don't understand how those packet functions tell the server to give me a copy of it's TileEntity so I can stuff the data into the client version.


TileEntity.getDescriptionPacket() only gets called for server TileEntities (worldObj.isRemote == false) and TileEntity.onDataPacket() never got called at all.


edit: oops, I was returning null from getDescriptionPacket() instead of my actual packet...


I'm sure it's one of those "why didn't I think of that" moments when it clicks but right now it's just eluding me.

Link to comment
Share on other sites

Thanks for the help everyone, this did the trick:


    public Packet getDescriptionPacket()
      // The server calls this function and if we return the NBT filled
      //  with data, this.onDataPacket() will be called for the client with
      //  the server's NBT info
      NBTTagCompound tag = new NBTTagCompound();
        return new Packet132TileEntityData(this.xCoord, this.yCoord, this.zCoord, 1, tag);
    public void onDataPacket(INetworkManager net, Packet132TileEntityData pkt)
      //  PKT contains an NBTTagCompound with the server's TileEntity info.
      //  We can parse that into our local variables so we stay in sync when our various
      //  "get" methods are called to access TileEntity data.

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.


  • Recently Browsing

    • No registered users viewing this page.
  • Posts

    • Link Daftar : KLIK DISINI  Link Login : KLIK DISINI  Link RTP   : KLIK DISINI  Link Gacor Slot Dana   : KLIK DISINI slot deposit dana 5000 ribu via dana adalah permainan slot dana gacor dengan menyediakan slot server thailand deposit dana. dan slot deposit dana adalah slot terbesar di thailand. anda cukup daftar disini dan mainkan disini slot deposit 5000 ribu via dana sudah dipastikan dengan deposit dana akan membuat akun anda menjadi akun special. situs deposit dana adalah situs yang terpercaya dan terakurat. Slot dana merupakan situs slot deposit dana yang sangat trending dan sangat dikenal luas di masyarakat. dengan adanya MAXWINBET77 anda bisa mendapatkan keuntungan besar setiap hari tanpa adanya potongan  yang pastinya menguntungkan bagi anda. situs slot dana  maxwinbet77 adalah situs slot dana terbaik 2024 dan dijamin mudah maxwin. PERMAINAN YANG ADA DI SLOT DANA MAXWINBET77: - TOGEL 4D - SLOT ONLINE - LIVE CASINO - SPORTSBOOK - ARCADE TEMBAK IKAN - SABUNG AYAM Saat Ini Slot Dana Maxwinbet77 Menyediakan Bonus Berupa : - Bonus New Member - Bonus Deposit Harian - Bonus Cashback - Bonus 2D TERBALIK - Bonus Prize 2 & Prize 3 - Bonus Refferal DAFATR DISINI
    • LINK DAFTAR : KLIK DISINI LINK DAFTAR : KLIK DISINI   Slot seabank meruapakan salah satu situs slot paling gacor deposit seabank 100% mudah maxwin, hari ini situs slot seabank meghadirkan permainan slot dengan kemudahan bergabung hanya dengan menggunakan aplikasi Seabank langsung bisa join dengan bandar slot Seabank terbaik dan terpercaya no.1 di indonesia. Slot Seabank resmi di daftar situs slot deposit pakai Seabank 5000 Gampang Maxwin dimana aplikasi Seabank tersebut telah sanggat membantu para bosku untuk bermain slot online deposit via Seabank saat ini slot Seabank ini membantu dalam mempermudah transaksi disaat bosku ingin deposit melakukan pembayaran. kini orang orang ingin bermian judi online khusus nya games slot tidak perlu khawatir lagi apabila tidak memilikui saldo di ATM, sebab dengan adanya aplikasi Seabank sudah memberikan dampak signifikan buat perjudian di indonesia. Selain slot pakai Seabank, terdapat beberapa aplikasi e-wallet yang dapat di gunakan untuk bertansaksi antara lain, slot deposit 5000 Seabank, slot dana, slot ovo, slot pulsa tanpa potongan, dan slot shopeepay mudah menang bisa bosku pakai untuk setoran Seabank resmi terbaru. intinya slot online deposit Seabank memberikan jamianan kemudahan saat main games slot gacor uang asli terbaik di indonesia bos.
    • LINK DAFTAR : KLIK DISINI LINK DAFTAR : KLIK DISINI   Slot deposit bank bsi merupakan salah satu situs slot gacor deposit bank bsi 24 jam mudah maxwin tanpa batas. hari ini slot deposit bank bsi menawarkan bonus terbesar untuk player yang sudah bergabung di situs slot bank bsi ini, dengan ada nya slot bank bsi sanget mempermudah player untuk melakukan transaksi deposit dengan bank bsi. Sebagai Situs Slot Deposit Bank Bsi meyediakan banyak permainan seperti slot online, live casino, sabung ayam, tembak ikan, sportbook semua game tersebuat sangat aman dan terpercaya. Beramin slot bank bsi sangat mudah hanya dengan niminal deposit 5000 ribu saja anda sudah bisa bermain di semua game yang sudah di sediakan oleh situs slot bank bsi. Slot bank bsi adalah saranan untuk Pemain yang mencari pengalaman bermain slot gacor sekarang dapat menemukan metode pembayaran beragam di berbagai situs slot gacor yang tersebar luas di seluruh negeri. Munculnya situs Slot Bank BSI, kini para pemain dapat menikmati kemudahan dan kenyamanan dalam melakukan transaksi pembayaran. Bahkan memungkinkan pemain untuk fokus sepenuhnya pada permainan yang mereka nikmati sepanjang waktu. Ini adalah langkah penting dalam memperluas aksesibilitas judi slot online di Indonesia dan memberikan pengalaman bermain yang lebih baik kepada para pecinta slot gacor.    
    • Sometimes love could be the worst experience. you get to love and trust your partner only to feel regret over it. i have been married for 7 years now and i found some sudden change in my partner attitude, i tried talking about it but he complains i'm nagging a lot . i tried to ignore his attitude but it became unbearable so i was advised to hire a hacker to help me gain access to his phone so i had know if he is cheating or not so i was introduced to [ Remote spy hacker @ g m ail . c o m ] and this expert helped me gain access to his phone without his notice. i got to see his messages, photos, call recordings and many more . Now i can see his cheating and that's the reason for the attitude all along.
    • hola thanks for answering  i set some system outs to test and see whats going on      @Override     protected void saveAdditional( CompoundTag nbt ){                  nbt.put("itemhandler", itemhandler.serializeNBT() );         nbt.putInt("progress", this.progress );         System.out.println("saveAdditional(nbt)");                 System.out.println(NbtUtils.prettyPrint(nbt)); //<-- this is whats getting saved         super.saveAdditional( nbt );     }     @Override     public void load( CompoundTag nbt ){         itemhandler.deserializeNBT( nbt.getCompound("itemhandler") );         this.progress = nbt.getInt("progress" );         System.out.println(NbtUtils.prettyPrint(nbt)); //<-- this is whats minecraft is giving back to the entity          System.out.println("load(nbt)");         super.load( nbt );     }   This dead adventurer body  has two parts a block and a block Item  both has their own item-handlers and their own menus all of that seems fine  Testing remarks : *when i change some element inside the gui  it triggers the saveAdditional(nbt) system out and shows a pretty print of the data being saved  *when the world map loads it triggers the load(nbt) system out and shows a pretty print of the data minecraft is giving to this Block Entity For the testing i gonna set mi BlockEntityBodyBlock, save something in it, close minecraft, fireup the game again and check if the items remain      ################ first try set the block entity (dead adventurer body like shaped) and left only a weath seed  in the slot 10 the console says its all right    close minecraft, launch it again i see the system out whit the data returned to the entity and its look good theres is only a weed seed  ################ Second try, now i gonna change the seed for two arrows  the console says its all right the two arrows are being saved    ######### Now close and run again bam Error  minecraft returns the original data whit only a wheat seed the two arrows has been loss   ########## try again now i gonna put 3 wheat seeds Console system out says it gets it and is saving the data   ############## but after close fire again  wheat seed,  data losed once more time  and it just throw the original   ####################################################################################### sorry for the long post and the crappy video  this is the reason why i say its saving the Block Entity data only when it feels like  coze its saves data when it feels like  ¿ its something wrong whit mi BlockEntity.saveAdditional()  if  i keep trying eventually it updates and the data chages      i alredy try to  level.removeBlockEntity(pos); level.setBlockEntity(pos, bebb);     BlockEntityBodyBlock.class   BlockEntityInit.class     body_blockitem.class                  
  • Topics

  • Create New...

Important Information

By using this site, you agree to our Terms of Use.