Skip to content
This repository was archived by the owner on Jul 9, 2026. It is now read-only.

Entity spawned in unloaded chunk of world takes void damage #7017

Description

@DaisukeDaisuke

Plugin information

Bug only happens with certain plugins (describe below)

Problem description

PocketMine-MP allows spawning entities in an unloaded chunk.

However, when an entity is spawned in an unloaded chunk:

  • The entity appears to be created successfully.
  • The entity immediately falls into the void.
  • When a player is teleported to that position later, the entity does not exist.

This behavior is difficult to understand and appears similar to undefined behavior.

Currently, no warning or exception is produced.

Steps to reproduce the issue

  1. Install this script plugin
  2. Log in to the server and Sneak
  3. If the message "chunk is loaded" appears, unload the chunk by restarting the server, etc.
  4. View the console output
  5. You will be automatically teleported, but there are no zombies here.

List of installed plugins

plugins
Command output | Plugins (1): mobUndefined v1.0.0
<?php


declare(strict_types=1);

use pocketmine\plugin\PluginBase;
use pocketmine\event\Listener;
use pocketmine\event\player\PlayerToggleSneakEvent;
use pocketmine\entity\Zombie;
use pocketmine\entity\Location;
use pocketmine\entity\EntityFactory;
use pocketmine\world\World;
use pocketmine\nbt\tag\CompoundTag;
use pocketmine\entity\EntityDataHelper as Helper;
use pocketmine\scheduler\ClosureTask;
use pocketmine\world\format\SubChunk;
use pocketmine\Server;
use pocketmine\event\entity\EntityDamageEvent;

/**
 * @name mobUndefined
 * @api 5.41.0
 * @description For issues
 * @version 1.0.0
 * @main mobUndefined_MpqCz
 * @author DaisukeDaisuke
 */
class mobUndefined_MpqCz extends PluginBase implements Listener{
	protected function onEnable() : void{
		/* Registering an event on the server */
		$this->getServer()->getPluginManager()->registerEvents($this, $this);

		/* Prepare a custom entity */
		EntityFactory::getInstance()->register(ExpandedZombie::class, function(World $world, CompoundTag $nbt) : ExpandedZombie{
			return new ExpandedZombie(Helper::parseLocation($nbt, $world), $nbt);
		}, ['ExpandedZombie', 'minecraft:zombie']);
	}

	protected function onDisable() : void{
		foreach(Server::getInstance()->getWorldManager()->getWorlds() as $world){
			foreach($world->getEntities() as $entity){
				if($entity instanceof ExpandedZombie){
					$entity->close();
				}
			}
		}
	}


	public function test(PlayerToggleSneakEvent $event) : void{
		$player = $event->getPlayer();
		$world = $player->getWorld();

		$x = 2000;
		$y = 84;
		$z = 2000;

		if($event->isSneaking()){
			return;
		}

		if($world->isChunkLoaded($x >> SubChunk::COORD_BIT_SIZE, $z >> SubChunk::COORD_BIT_SIZE)){
			$player->sendMessage("chunk is loaded");
		}else{
			$player->sendMessage("chunk is not loaded");
		}


		/* Spawning an entity */
		$entity = new ExpandedZombie(new Location($x, $y, $z, $world, 0, 0));
		$entity->spawnToAll();


		/* Teleporting the player */
		$this->getScheduler()->scheduleDelayedTask(new ClosureTask(function() use ($y, $z, $x, $player) : void{
			if(!$player->isOnline()){
				return;
			}
			$player->teleport(new Location($x, $y, $z, $player->getWorld(), 0, 0));
		}), 20 * 15);
	}
}

class ExpandedZombie extends Zombie{
	private int $count = 0;
	protected function entityBaseTick(int $tickDiff = 1) : bool{
		parent::entityBaseTick($tickDiff);
		var_dump($this->count++);
		return true;
	}

	protected function initEntity(CompoundTag $nbt) : void{
		parent::initEntity($nbt);
		$this->setCanSaveWithChunk(false);
	}

	public function attack(EntityDamageEvent $source) : void{
		parent::attack($source);
		var_dump([$source->getCause(), strrchr($source::class, "\\")]);
	}
}

console output

The entity is found to be mortally wounded by void damage

public const CAUSE_VOID = 11;
int(88)
array(2) {
  [0]=>
  int(11)
  [1]=>
  string(18) "\EntityDamageEvent"
}
int(89)
array(2) {
  [0]=>
  int(11)
  [1]=>
  string(18) "\EntityDamageEvent"
}
int(90)
array(2) {
  [0]=>
  int(11)
  [1]=>
  string(18) "\EntityDamageEvent"
}
int(91)
[10:18:24.863] [Server thread/INFO]: [Memory Manager] [Cyclic Garbage Collector] Run #4 took 12.10 ms (40170 -> 0 roots, 0 cycles collected) - cumulative GC time: 36.30 ms

Expected behaviour

Entities should be banned or have a warning added in pm6 from spawning in unloaded chunks.

PocketMine-MP version

Server version: 5.41.0 (git hash: bb8ae4a)

PHP version

PHP version: 8.4.16

Server OS

Operating system: win

Game version (if applicable)

Windows

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions