NaturalMobSpawner 5.46.0
Natural mob spawning with Bedrock's algorithm and Mojang's spawn rules (see VanillaSpawnRules; until they are downloaded, SpawnRules::builtin()). Sources: https://minecraft.wiki/w/Mob_spawning (Bedrock Edition) and the spawn rule documentation of the Bedrock add-on API.
Each tick, every ticking chunk (the chunk tick radius around players, Bedrock's simulation distance) runs a cluster spawn attempt with a chance of 11 in 2000 (the chunks are sampled, not looped over: about 9 attempts per tick for 20 players). An attempt picks a random column of the chunk and tries:
- the surface: the position above the highest block with collision (through water and plants), if that block has a full solid top (under leaves there is no surface spawn);
- every other spawnable position below it ("underground": caves, under trees) within reach of the players. A position is spawnable with the feet in a block without collision (or water) above a full solid top, or in air above lava. It must be 24 to 44 blocks from the nearest player (distance_filter overrides it, e.g. 12-32 for fish; with a chunk tick radius over 4, up to 128).
The rules matching the biome and the position (placement, brightness, difficulty, height, blocks...) whose population cap is not reached are candidates; one is picked by weight. Population caps count the naturally spawned mobs of each population type in the 9x9 chunks around the attempt, separately for surface and underground mobs (PopulationCaps); density limits count the mob's own type the same way and let it spawn with a chance of (limit - count) / limit. At most PopulationCaps::GLOBAL_CAP naturally spawned mobs per world. The herd (pack) spawns around the position: each member is checked again and gets the herd events (babies, horse coat) and jockeys/riders (Jockeys::onMobSpawned() with naturalSpawn).
Bedrock specifics implemented in code (not in the rule files): slimes only in slime chunks below Y 40 or in swamps between Y 51 and 69 by moon phase (SlimeChunk), phantoms only above players who haven't rested for 3 days (Player::getTimeSinceRest()), strays turning into skeletons underground or 20% of the time (spawn_event), structure spawns (StructureSpawns), wandering traders (WanderingTraderSpawner) and village cats (VillageCatSpawner). Pillager patrols have their own spawner (PatrolSpawner).
Naturally spawned mobs are not persistent: they despawn far from players (MobDespawner).
Nothing spawns while the world's domobspawning gamerule is off (World::setMobSpawningEnabled()); mobs still despawn. Plugins can change or cancel each spawned mob with EntityNaturalSpawnEvent; rules for mobs without a registered implementation (EntitySpawnRegistry) are skipped.
With mobs.spawning.mode: legacy, the old simplified spawner is used instead (LegacyMobSpawner).
Constants
CHUNK_CHANCE
public const CHUNK_CHANCE = 11Chance per tick that a ticking chunk runs a spawn attempt: 11 in 2000 (Bedrock).
CHUNK_CHANCE_DIVISOR
public const CHUNK_CHANCE_DIVISOR = 2000HERD_SPREAD
public const HERD_SPREAD = 4Herd members spawn this many blocks around the first one (horizontally).
PHANTOM_HEIGHT
public const PHANTOM_HEIGHT = 28Phantoms spawn in a 21x15x21 box centred this many blocks above the player.
PHANTOM_INSOMNIA_TICKS
public const PHANTOM_INSOMNIA_TICKS = 72000Ticks without resting after which phantoms spawn around a player (Bedrock "Time Since Last Rest").
SLIME_CHUNK_MAX_Y
public const SLIME_CHUNK_MAX_Y = 40Slimes spawn in slime chunks below this Y.
SLIME_SWAMP_MAX_Y
public const SLIME_SWAMP_MAX_Y = 69SLIME_SWAMP_MIN_Y
public const SLIME_SWAMP_MIN_Y = 51Methods
__construct()
public function __construct(\pocketmine\world\World $world)clusterAttempt()
public function clusterAttempt(\pocketmine\world\mobs\spawn\SpawnRules $rules, int $chunkX, int $chunkZ) : voidOne Bedrock cluster spawn attempt in a random column of the chunk.
countPopulation()
public function countPopulation(int $chunkX, int $chunkZ, string $population, bool $surface) : intNaturally spawned mobs of the population type in the 9x9 chunks around the chunk.
countType()
public function countType(int $chunkX, int $chunkZ, string $type, bool $surface) : intNaturally spawned mobs of the type in the 9x9 chunks around the chunk (density limits).
getAttemptCount()
public function getAttemptCount() : intgetCandidatesAt()
public function getCandidatesAt(int $x, int $y, int $z, bool $surface) : arrayDebug helper: the spawn rules (identifiers) that could spawn at the position right now, ignoring caps.
getMaxDistance()
public function getMaxDistance() : intgetNaturalMobCount()
public function getNaturalMobCount() : intNumber of naturally spawned mobs in the world counted for the global cap (refreshed every second).
getRules()
public function getRules() : ?\pocketmine\world\mobs\spawn\SpawnRulesReturns the spawn rules in use (Mojang's once downloaded, the built-in ones until then), or null in legacy mode.
getSpawnCount()
public function getSpawnCount() : intgetWanderingTraderSpawner()
public function getWanderingTraderSpawner() : ?\pocketmine\world\mobs\WanderingTraderSpawnersetRules()
public function setRules(\pocketmine\world\mobs\spawn\SpawnRules $rules) : voidReplaces the spawn rules of this world (plugins, tests).
spawnRuleAt()
public function spawnRuleAt(\pocketmine\world\mobs\spawn\SpawnCondition $condition, int $x, int $y, int $z, bool $surface = true) : arraySpawns a mob of the rule at the position as the spawner would, without the distance, cap and chance checks (for tests and plugins). Returns the spawned mobs.
tick()
public function tick(int $currentTick) : void