Changes to the Mob Cap in latest Paper builds

Hi there, this is my first post on the forums here. I keep to myself usually, but my acute attention to detail means I notice lots of quirks with the behavior of Paper. So, I made this thread to document what I think are some of the strange and interesting effects of the recent change to the mob cap in Paper build 572. This is actually a pretty significant change to the vanilla mechanics, all things considered, so I think a bit of analysis on it could be useful.

First off, I want to explain how the changes were implemented for those who might not be familiar with it.

In Paper build 572 for mc 1.13.2, a change was made to how the server calculates the “mob cap” for a world. If you don’t know what the mob cap is, it’s how minecraft determines there’s too many mobs spawned, and so it shouldn’t attempt to naturally spawn more mobs.

The change Paper made was to track the “spawn reason” for any given entity in the world, and only count entities whose spawn reason is NATURAL. Any entity that does not have the spawn reason NATURAL is ignored when determining how many mobs count towards the mob cap. In addition to this, hostile mobs that are considered “persistent” are also ignored.

What this means, essentially, is that mobs that do not spawn because of the regular mob spawning algorithm will not affect your mob cap whatsoever- this includes things like mobs from mob spawners, animals that are bred, slimes that split into smaller slimes, mobs that spawned because of the world generation, etc. All of these will not count towards your mob cap, and thus, the amount of mob spawns you get will be increased overall, due to the server hitting the mob cap less often.

The question that you may be asking, and what I definitely asked, is how Paper determines what is a “natural” spawn or not. And the answer is: it seems to just rely on a pre-existing bukkit enum for that (Specifically, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason).

Here’s where I lay out some of the problems/quirks with this new system, because I think there’s a few things broken/odd about how bukkit handles the spawn reasons. I’ll go over a few of the spawn reasons, mostly just the ones with something interesting to comment on.

DEFAULT is the default spawn reason given when the server can’t find a valid spawn reason for something. This is the spawn reason given to most non-living entities such as items, armor stands, item frames, paintings, etc. It’s also given to any entity spawned using the /summon command. As well, in any other case where the server can’t find the spawn reason for an entity, it will return as DEFAULT.

NATURAL is what all mobs spawned from the natural mob spawning algorithm get. This includes phantoms that spawn above the player.

BREEDING is the spawn reason given to any animal or etc. that was bred by a player (or from villagers breeding). What’s interesting about this one is that the mob keeps it for as long as it lives, even after growing to an adult.

CHUNK_GEN is the spawn reason that’s supposed to be given to mobs that spawn along with the world generation, but in practice I haven’t seen this work. I’ve visited freshly generated witch huts and the witches that generated there had spawn reason DEFAULT.

CUSTOM is the spawn reason for when mobs are spawned via plugin. However, items that are dropped from dying mobs seem to get the CUSTOM spawn reason, even with no plugins installed. This includes armor stand items, dropped from breaking the armor stand in survival. I’m not sure why this is, because items dropped by a player/dispenser/dropper etc are given DEFAULT like normal.

DISPENSE_EGG is the spawn reason that’s supposed to be given to mobs spawned by a dispenser using a spawn egg, yet for some reason they are just given SPAWNER_EGG instead.

EGG is given to entities spawned from eggs- this includes baby chickens as well as baby turtles.

JOCKEY is given to entities that spawn as part of a jockey mob- i.e. the spider of a spider jockey, chicken of a chicken jockey, etc.

LIGHTNING is given to entities that spawn due to being struck by lightning- witches from villagers, pigmen from pigs, etc. Might also apply to trapped skeleton horses, but I’m not sure.

NETHER_PORTAL is given to mobs spawned from nether portals. This is basically just zombie pigmen. It does not include other mobs that pass through portals; they retain their original spawn reason.

SHOULDER_ENTITY is supposed to be given to a parrot that is spawned from the player who owns it jumping when it’s on their shoulder… This one doesn’t make sense to me because, I believe, the server keeps an exact copy of the parrot stored in the player’s nbt data while it is perched on the player’s shoulder. Regardless, this doesn’t work on Paper.

SLIME_SPLIT is given to slimes or magma cubes after they’ve split into smaller slimes/magma cubes.

SPAWNER is supposed to be given to mobs that come from a mob spawner. However, mob spawner mobs get DEFAULT instead for some reason. I’d like to point out, though, paper already applies a separate tag to these mobs: Paper.FromMobSpawner.

SPAWNER_EGG is given to mobs spawned using a spawn egg. It is ALSO given to fish spawned from fish in a bucket, which are obtainable in vanilla survival mode.

TRAP is given to the skeletons riding atop skeleton horses from a skeleton horse trap. The skeleton horses themselves get JOCKEY.


I didn’t cover those ones because they were either self-explanatory or they didn’t have much of interest to comment on.

Anyways, with all of that in mind, there’s a few observations one can make here. I think one of the biggest and most obvious issues is how Paper seems to handle the spawn reasons of entities that already existed before this change was made to the server. Because it cannot determine the spawn reason of an already existing entity, it will automatically assign the spawn reason DEFAULT to the entity, regardless of how it came to be. And, as discussed before, only entities with the spawn reason NATURAL will count against the mob cap of a world.

Essentially- all pre-existing mobs on your server that were there before this update WILL NOT COUNT towards your mob caps, and thus your server will just spawn new mobs until it hits the mob cap with those new mobs. This is perfectly fine for entities that despawn (hostile mobs), but for passive mobs it may be a bit of an issue. Personally, I think this isn’t that big of a deal, but it’s worth discussing at least.

Beyond that, it’s worth looking at how this will affect mob spawns in general after doing this update. Another really big thing I’ve noticed while reviewing these changes is that this will essentially make it so that players can have massive farms full of dozens, possibly hundreds of farm animals that they bred, and it will make absolutely no impact on the passive mob cap, due to all those animals having the spawn reason BREEDING. Chickens and turtles hatched from eggs also wouldn’t affect mob caps.

Another obvious difference is that mobs from mob spawners won’t count towards the mob cap. I believe this is the number one reason this change was implemented to begin with, and it’s a welcome change. Although they should probably get the spawn reason SPAWNER instead of DEFAULT…

Overall, I think it is safe to say that after this update, your server will experience more mob spawns, potentially a very significant increase in mob spawns at that. Players who operate natural spawning based mob farms will find that their farms are more reliable/consistent with others playing on the server- particularly passive mob farms, because peoples’ bred animals, chickens, turtles etc. won’t count towards the mob cap for those.

In addition, this will be a huge buff to slime farms, as the slimes that spawn from slimes splitting will no longer count towards the hostile mob cap, allowing the mob cap to be freed up faster & allowing for quicker slime spawns. I don’t know how much this would potentially increase the output of slime farms, but I’m willing to bet it’s a significant amount. Could be seen as a positive or a negative depending on what kind of server owner you are.

Also worth mentioning: gold farms based on zombie pigmen spawning from nether portals just became a whole lot more viable/useful after this update, because their spawn reason (NETHER_PORTAL) will never count towards the hostile mob cap. You could run a pigman farm of this design while running another natural-spawning based hostile mob farm, such as a guardian farm etc., and not impact the efficiency of either farm whatsoever. You could even combine it with a natural spawning based pigman farm to create a pigman farm that’s twice as fast and gets twice as much gold in the same amount of time… Honestly this one might be even more prone to being abused than the buff to slime farms.

I’d love to do some testing on the efficiency of mob farms before and after these changes, but this post is already very in-depth.

CONCLUSION: After Paper build 572 for 1.13.2, mob spawning has changed in a pretty significant way. It might not seem that different to the casual observer, but probe deeper and you’ll realize this has some pretty big implications. Whether these changes are a positive or a negative remains to be seen, but personally I think it is a welcome change. As a server owner myself, I think I and all of my players will be happy about a general increase in mob spawns. However, I do have my concerns, as these changes open the possibility for some incredibly op mob farms. Also, lag is still a concern, because entities in 1.13 are the most horrendous lag source I’ve seen since hoppers back in the olden days before they were optimized.

All in all, I think with some additional work done to smooth out the issues with this new system, it could be a really positive thing for every paper server. But, those are just my thoughts. What do you think?


Sorry to necro this thread but my (wither) mob switch stopped working after switching my server to paper. I was looking for solutions and found this post. I was able to get the mob switch working again by setting count-all-mobs-for-spawning to true in paper.yml. Thanks aeon for making this important observation!

1 Like