What happens
During natural mob spawnings for nether fortress mobs:
For packed spawning for fortress mob whose spawner data is picked on netherbricks blocks, its spawn attempts cannot spawn mobs in inner fortress bounding box on non-netherbricks block
For packed spawning for fortress mob whose spawner data is picked on non-netherbricks blocks, its spawn attempts cannot spawn mobs in outer fortress bounding box on netherbricks block
Here "spawner data" means net.minecraft.world.level.biome.MobSpawnSettings.SpawnerData
Affected versions: from 1.18.2 release, to the current latest release and snapshot
Analyze
Let's have a look at class net.minecraft.world.level.NaturalSpawner#getRandomSpawnMobAt
During natural mob spawning, NaturalSpawner#getRandomSpawnMobAt is used to get theΒ SpawnerData for the current pack spawning, and NaturalSpawner#canSpawnMobAt is used to check if the mob can still be spawned at the current pos.
Β
Both getRandomSpawnMobAt and canSpawnMobAt invoke mobsAt method to get the list of SpawnerData for the given pos
For nether fortress mobs,Β mobsAt method could return 2 different list:
return isInNetherFortressBounds(blockPos, serverLevel, mobCategory, structureManager)
? NetherFortressStructure.FORTRESS_ENEMIES
: chunkGenerator.getMobsAt(holder != null ? holder : serverLevel.getBiome(blockPos), structureManager, mobCategory, blockPos);Case A: If the pos is inside the outer bounding box of the fortress, and is on the top of a nether bricks block, then
NetherFortressStructure.FORTRESS_ENEMIESis returnedCase B: Otherwise, the return value of
chunkGenerator.getMobsAtis used. If the pos is inside the inner bounding box of the fortress, then a list with the same value ofNetherFortressStructure.FORTRESS_ENEMIESis returned
Since 1.18.2-pre1, the returned list of case A will be a different object with case B, and the list elements will be different as well. Notes that canSpawnMobAt uses java.util.List#contains to check if the spawner data is inside the list, and class MobSpawnSettings.SpawnerData does not implements the equals methods.
As the result, canSpawnMobAt will return false, if a pack spawning picks the spawner data on a netherbricks block (pick from case A list), and trying to spawn a fortress mob on non-nether bricks (check with case B list), vice versa
For the 1.18.2-pre1 change, 1.18.2-pre1 makes the spawn data list data-driven, resulting in spawner data list for fortress mobs are serialized and deserialized (i.e. deep copied) during the creation of the current level's RegistryAccess
How this affects the game
Wither skeleton farms built at fortress crossroads, using dirt + wither rose as the spawning platform, will have its rate decreased, if nether bricks floor is built around the spawning platform (see attachment wiskefarm.png). For MC version < 1.18.2, the rate will increase instead
The reason is, with extended netherbricks floors built, for pack spawning that picks its spawner data on inner bounding box structure (e.g. fortress bridges) adjacent to the intersection spawning platform, it can no longer spawns wither skeleton on the spawning platform, due to the described issue
Possible solution
Implements the
equalsmethod onMobSpawnSettings.SpawnerDataReplace the
java.util.List#containscall incanSpawnMobAtwith something else
Attachments
Comments 4
Attached a world containing wither skeleton spawning platform and spawn rate counter datapack for reproduction. The world is saved in 1.16.5, but it is safe to upgrade to higher versions.
The rate of three situations shown in the world save is different across different versions.
Note: if you want to use the datapack in 1.21, don't forget to rename these folders in all namespaces: functions -> function, tags/functions -> tags/function, tags/entity_types -> tags/entity_type
Thank you for your report!
After consideration, the issue is being closed as Won't Fix.
Please note that this is not the same as Working as Intended, as this bug report correctly describes behavior in the game that might not be the intended or desirable behavior, but it will not be fixed right now. Sometimes, this is because the issue reported is minor and/or impossible to change without large architectural changes to the code base.
Quick Links:
π Bug Tracker Guidelines β π¬ Community Support β π§ Mojang Support (Technical Issues) β π§ Microsoft Support (Account Issues)
π Project Summary β βοΈ Feedback and Suggestions β π Game Wiki
This issue should be fixed in 25w02a (observable in 25w03a)
In 25w02a, the MobSpawnSettings.SpawnerData class has become a record class, and thus automatically gains a correctly implemented equals function
It's not observable in 25w02a because of another mob spawning bug (MC-279245)
Could you provide a way to clearly and consistently reproduce this issue? For the sake of confirming the report, it would be helpful to know how to get reliable results to confirm the behavior.