Hello! I'm trying to add a custom block to the game, by overriding some unadded blocks, but i need to store some data... precisely 2 bools, and an item with all its enchants durability etc. I'm having trouble understanding how exactly pocketmine handles tiles, i tried going trough tile\chest, spawnable, and tile but couldn't figure out a lot... I think i did some stuff correctly.. but I'm not sure... Any help pointing me in the right direction, is much appreciated! PS: The part I'm struggling with is understanding how exactly the spawn process goes, and how exactly data is formated and stored...
If you are adding a tile that does not exist in the game, its best not to spawn it to the player, it might cause unexpected behavior. As for data just read and write your data in readSaveData and writeSaveData respectively and pocketmine will handle the rest
What would be the best approach then? The block state (meta) is dependent on the 2 bools in the tile, I have that part figured out, but how would I go about making the tile exactly? Which method spawns it in? Should I just use an already existing one?
Ok, after a fresh cup of coffee, and a lot of following, i figured out how the whole spawn process works... thing is: I dont know where to start looking at the "despawning" aka when the server closes... So for now: i figured out how to spawn it and give it custom NBT, but now i need to figure out what methods save the data when the server closes and how to save an item instance to the NBT
Let's see if i have this right: So first off we register the tile by doing Code: pocketmine\tile\Tile::registerTile("className", ["mySaveID"]); then, we need to create the NBT using MyTile::createNBT(): (inherited method from pocketmine\tile\Tile, which takes care of putting the coordinates and id in the NBT and calls MyTile::createAdditionalNBT() where i can put my bools in the NBT using pocketmine\nbt\CompondTag::setByte()) Code: $tileNBTData = MyTile::createNBT($this, $clickedFace, $item, $placer) //args from block\MyBlock::place() after that, we can actually create the tile by doing: Code: Tile::createTile("mySaveID", $this->getLevel(), $tileNBTData); which creates a new instance of MyTile, and when pocketmine\tile\Tile is constructed, it calls MyTile::readSaveData() where i can get all my data, and then puts the tile in the world and also spawns it cause pcoketmine\tile\Spawnabe's construct method calls $this->spawnToAll(); Did i understand everything correctly? If so, where can i start looking at how tiles get saved to the world, and what methods are called then, and what methods are called when they are loaded/instantiated
thing is, I would really like to actually understand how everything works not just copy and paste random crap together and hope it works
Yea you got everything right, thats great! When i meant not spawning to the player, it means to extend Tile instead of Spawnable, so that it is not sent to the player and remains only server side. When a chunk is saved, it calls Tile::saveNBT() here https://github.com/pmmp/PocketMine-...mine/level/format/io/region/McRegion.php#L116 Then Tile::saveNBT calls Tile::writeSaveData() When a chunk is loaded It calls Tile::createTile() here https://github.com/pmmp/PocketMine-MP/blob/stable/src/pocketmine/level/format/Chunk.php#L720k Then proceeds as you described above For saving and loading of items you can take a look here https://github.com/pmmp/PocketMine-MP/blob/stable/src/pocketmine/tile/ContainerTrait.php
Thanks a bunch! Let's see if i understand everything correctly, when the server is stopping, somewhere in the process, (i will dig around, cause i wanna see the whole process) Code: pocketmine\level\format\io\region\McRegion::nbtSerialize() is called, which iterates over all the tiles in the passed chunk, and calls pocketmine\tile\Tile::saveNBT() on them, which takes care of creating a new pocketmine\nbt\CompondTag, and saves the ID and position to it, and then calls MyTile::writeSaveData(), where i can save my bools to it, and then thats saved! so that's how saving is done! Now loading: Somewhere in the chunk loading/initializing process (again, I'll dig a bit more to figure out the exact sequence of events) it grabs all the tile NBTs and re-creates the tiles by calling pocketmine\tile\createTile() with the NBT, and all the stuff that i said in my previous comment is done! Now, my question is, what's the difference between a spawned tile, and a tile? (also, did i get everything correctly? ) About the item storage, I'm trying to store a single tool item, nothing more. Using that seems like an overkill? I still haven't checked it out, but isn't there a simpler way of doing it?
Yea that's the idea. Whether it is a spawned tile just means whether the tile is sent to the player. If it is not sent, then the client doesn't know its there, which is ok if it doesn't exist in the game anyway. If you just want to store a single item you can do something like Saving: PHP: $nbt->setString("Item",$item->nbtSerialize()); Loading: PHP: $item = Item::nbtDeserialize($nbt->getString("Item"));