Server ticks tiles every tick but i think it is needless, isn't it? What about ticking every 10 ticks? Maybe im wrong.
Server doesn't tick tiles every tick. It just checks tiles from the to-be-updated queue and updates them. If nothing is scheduled, they don't need to be ticked at all. They are used for furnaces.
Yes i know but why one update per 10 ticks isn't enough? If i do burnTime += 10 (and other furnace/brewing times)
Daylight sensor. And probably others, we never know. What exists is not the problem. The tile ticking system was designed to support any kind of tiles that exist right now or in the future, without knowing what the tiles are. It is like PocketMine calling PluginManager::callEvent() without knowing whether there is a plugin that handles it. After all, if there are no tiles that need ticking, there will be almost no lag.
but i don't have to set this in level class but in furnace/brewing class, so it doesn't affect another tiles
i've just tested it and it works fine and it is almost same like 20 ticks per seconds (im using 2 ticks per second)
this is onUpdate function in my enderFurnace PHP: private $lastUpdate2 = 0; public function onUpdate(){ if($this->closed === true){ return false; } if($this->lastUpdate2 < 10){ $this->lastUpdate2++; return true; } $this->lastUpdate2 = 0; $this->timings->startTiming(); //$ret = false; foreach($this->inventories as $inventory) { $fuel = $inventory->getFuel(); $raw = $inventory->getSmelting(); $product = $inventory->getResult(); $smelt = $this->server->getCraftingManager()->matchFurnaceRecipe($raw); $canSmelt = ($smelt instanceof FurnaceRecipe and $raw->getCount() > 0 and (($smelt->getResult()->equals($product) and $product->getCount() < $product->getMaxStackSize()) or $product->getId() === Item::AIR)); if ($inventory->burnTime <= 0 and $canSmelt and $fuel->getFuelTime() !== null and $fuel->getCount() > 0) { $this->checkFuel($fuel, $inventory); } if ($inventory->burnTime > 0) { $inventory->burnTime--; $inventory->burnTicks = ceil(($inventory->burnTime / $inventory->maxTime * 20)); if ($smelt instanceof FurnaceRecipe and $canSmelt) { $inventory->cookTime++; if ($inventory->cookTime >= 20) { //10 seconds $product = Item::get($smelt->getResult()->getId(), $smelt->getResult()->getDamage(), $product->getCount() + 1); $inventory->setResult($product); $raw->setCount($raw->getCount() - 1); if ($raw->getCount() === 0) { $raw = Item::get(Item::AIR, 0, 0); } $inventory->setSmelting($raw); $inventory->cookTime = $inventory->cookTime - 20; } } elseif ($inventory->burnTime <= 0) { $inventory->burnTime = 0; $inventory->cookTime = 0; $inventory->burnTicks = 0; } else { $inventory->cookTime = 0; } //$ret = true; foreach ($inventory->getViewers() as $player) { $windowId = $player->getWindowId($inventory); if ($windowId > 0) { $pk = new ContainerSetDataPacket(); $pk->windowid = $windowId; $pk->property = 0; //Smelting $pk->value = floor($inventory->cookTime * 10); $player->dataPacket($pk); $pk = new ContainerSetDataPacket(); $pk->windowid = $windowId; $pk->property = 1; //Fire icon $pk->value = $inventory->burnTicks * 10; $player->dataPacket($pk); } } } else { $inventory->burnTime = 0; $inventory->cookTime = 0; $inventory->burnTicks = 0; unset($this->inventories[$inventory->owner]); } } $this->lastUpdate = microtime(true); $this->timings->stopTiming(); return true; }
And that method is called from https://github.com/PocketMine/PocketMine-MP/blob/master/src/pocketmine/level/Level.php#L674 And if the tile was not updated at all, why would the onUpdate function be called? Anyway, more optimization can be done, but not through skipping ticks.
if tile was not updated it wouldn't be called. but im using this in my minigame and i need it, that's why it returns true always, but i think normal furnace in pocketmine can run only 2 times per second too