From eb916fe43d9b51e63e9715f255d8f93d53373d73 Mon Sep 17 00:00:00 2001 From: XenialDan Date: Sun, 24 Jul 2022 19:22:21 +0200 Subject: [PATCH] Use a falling block entity to improve client side performance of FloatingTextParticle (#4714) Performance tests show that this has a considerable client-side performance advantage over using players. In my local tests, using 1000 floating texts in a 10x10x10 area, I observed an FPS increase from 1.5 to 8.0. --- src/world/particle/FloatingTextParticle.php | 60 +++++++-------------- 1 file changed, 20 insertions(+), 40 deletions(-) diff --git a/src/world/particle/FloatingTextParticle.php b/src/world/particle/FloatingTextParticle.php index 1534d94fa..313e40d48 100644 --- a/src/world/particle/FloatingTextParticle.php +++ b/src/world/particle/FloatingTextParticle.php @@ -23,29 +23,20 @@ declare(strict_types=1); namespace pocketmine\world\particle; +use pocketmine\block\VanillaBlocks; use pocketmine\entity\Entity; -use pocketmine\entity\Skin; use pocketmine\math\Vector3; -use pocketmine\network\mcpe\convert\SkinAdapterSingleton; -use pocketmine\network\mcpe\protocol\AddPlayerPacket; -use pocketmine\network\mcpe\protocol\PlayerListPacket; +use pocketmine\network\mcpe\convert\RuntimeBlockMapping; +use pocketmine\network\mcpe\protocol\AddActorPacket; use pocketmine\network\mcpe\protocol\RemoveActorPacket; -use pocketmine\network\mcpe\protocol\types\command\CommandPermissions; -use pocketmine\network\mcpe\protocol\types\DeviceOS; +use pocketmine\network\mcpe\protocol\types\entity\ByteMetadataProperty; +use pocketmine\network\mcpe\protocol\types\entity\EntityIds; use pocketmine\network\mcpe\protocol\types\entity\EntityMetadataFlags; use pocketmine\network\mcpe\protocol\types\entity\EntityMetadataProperties; use pocketmine\network\mcpe\protocol\types\entity\FloatMetadataProperty; +use pocketmine\network\mcpe\protocol\types\entity\IntMetadataProperty; use pocketmine\network\mcpe\protocol\types\entity\LongMetadataProperty; -use pocketmine\network\mcpe\protocol\types\GameMode; -use pocketmine\network\mcpe\protocol\types\inventory\ItemStack; -use pocketmine\network\mcpe\protocol\types\inventory\ItemStackWrapper; -use pocketmine\network\mcpe\protocol\types\PlayerListEntry; -use pocketmine\network\mcpe\protocol\types\PlayerPermissions; -use pocketmine\network\mcpe\protocol\types\UpdateAbilitiesPacketLayer; -use pocketmine\network\mcpe\protocol\UpdateAbilitiesPacket; -use Ramsey\Uuid\Uuid; -use function array_fill; -use function str_repeat; +use pocketmine\network\mcpe\protocol\types\entity\StringMetadataProperty; class FloatingTextParticle implements Particle{ //TODO: HACK! @@ -98,45 +89,34 @@ class FloatingTextParticle implements Particle{ } if(!$this->invisible){ - $uuid = Uuid::uuid4(); $name = $this->title . ($this->text !== "" ? "\n" . $this->text : ""); - $p[] = PlayerListPacket::add([PlayerListEntry::createAdditionEntry($uuid, $this->entityId, $name, SkinAdapterSingleton::get()->toSkinData(new Skin("Standard_Custom", str_repeat("\x00", 8192))))]); - $actorFlags = ( 1 << EntityMetadataFlags::IMMOBILE ); $actorMetadata = [ EntityMetadataProperties::FLAGS => new LongMetadataProperty($actorFlags), - EntityMetadataProperties::SCALE => new FloatMetadataProperty(0.01) //zero causes problems on debug builds + EntityMetadataProperties::SCALE => new FloatMetadataProperty(0.01), //zero causes problems on debug builds + EntityMetadataProperties::BOUNDING_BOX_WIDTH => new FloatMetadataProperty(0.0), + EntityMetadataProperties::BOUNDING_BOX_HEIGHT => new FloatMetadataProperty(0.0), + EntityMetadataProperties::NAMETAG => new StringMetadataProperty($name), + EntityMetadataProperties::VARIANT => new IntMetadataProperty(RuntimeBlockMapping::getInstance()->toRuntimeId(VanillaBlocks::AIR()->getFullId())), + EntityMetadataProperties::ALWAYS_SHOW_NAMETAG => new ByteMetadataProperty(1), ]; - $p[] = AddPlayerPacket::create( - $uuid, - $name, + $p[] = AddActorPacket::create( $this->entityId, //TODO: actor unique ID - "", - $pos, //TODO: check offset + $this->entityId, + EntityIds::FALLING_BLOCK, + $pos, //TODO: check offset (0.49?) null, 0, 0, 0, - ItemStackWrapper::legacy(ItemStack::null()), - GameMode::SURVIVAL, - $actorMetadata, - UpdateAbilitiesPacket::create(CommandPermissions::NORMAL, PlayerPermissions::VISITOR, $this->entityId, [ - new UpdateAbilitiesPacketLayer( - UpdateAbilitiesPacketLayer::LAYER_BASE, - array_fill(0, UpdateAbilitiesPacketLayer::NUMBER_OF_ABILITIES, false), - 0.0, - 0.0 - ) - ]), + 0, [], - "", - DeviceOS::UNKNOWN + $actorMetadata, + [] ); - - $p[] = PlayerListPacket::remove([PlayerListEntry::createRemovalEntry($uuid)]); } return $p;