From b172c93e45e60ee3dbfd8a2efbede60b894673a3 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 6 Oct 2020 17:27:17 +0100 Subject: [PATCH] World: do not group broadcasted packets by chunk, broadcast directly instead Grouping packets to batch by chunk instead of by player reduces bandwidth efficiency, because the number of active chunks is almost always larger than the number of active players. With the old mechanism, a batch of packets for each active chunk (which could be dozens, or hundreds... or thousands) would be created once, and then sent to many players. This makes the compression load factor O(nActiveChunks). Broadcasting directly is simpler and changes the load factor to O(nActivePlayers), which usually means a smaller number of larger batches are created, achieving better compression ratios for approximately the same cost (the same amount of data is being compressed, just in a different way). --- src/world/World.php | 19 +------------------ 1 file changed, 1 insertion(+), 18 deletions(-) diff --git a/src/world/World.php b/src/world/World.php index f649a27d7..02c11558c 100644 --- a/src/world/World.php +++ b/src/world/World.php @@ -172,9 +172,6 @@ class World implements ChunkManager{ /** @var Player[][] */ private $playerChunkListeners = []; - /** @var ClientboundPacket[][] */ - private $chunkPackets = []; - /** @var float[] */ private $unloadQueue = []; @@ -525,11 +522,7 @@ class World implements ChunkManager{ * Broadcasts a packet to every player who has the target position within their view distance. */ public function broadcastPacketToViewers(Vector3 $pos, ClientboundPacket $packet) : void{ - if(!isset($this->chunkPackets[$index = World::chunkHash($pos->getFloorX() >> 4, $pos->getFloorZ() >> 4)])){ - $this->chunkPackets[$index] = [$packet]; - }else{ - $this->chunkPackets[$index][] = $packet; - } + $this->server->broadcastPackets($this->getChunkPlayers($pos->getFloorX() >> 4, $pos->getFloorZ() >> 4), [$packet]); } public function registerChunkLoader(ChunkLoader $loader, int $chunkX, int $chunkZ, bool $autoLoad = true) : void{ @@ -775,16 +768,6 @@ class World implements ChunkManager{ if($this->sleepTicks > 0 and --$this->sleepTicks <= 0){ $this->checkSleep(); } - - foreach($this->chunkPackets as $index => $entries){ - World::getXZ($index, $chunkX, $chunkZ); - $chunkPlayers = $this->getChunkPlayers($chunkX, $chunkZ); - if(count($chunkPlayers) > 0){ - $this->server->broadcastPackets($chunkPlayers, $entries); - } - } - - $this->chunkPackets = []; } public function checkSleep() : void{