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_ENEMIES
is returnedCase B: Otherwise, the return value of
chunkGenerator.getMobsAt
is used. If the pos is inside the inner bounding box of the fortress, then a list with the same value ofNetherFortressStructure.FORTRESS_ENEMIES
is 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
equals
method onMobSpawnSettings.SpawnerData
Replace the
java.util.List#contains
call incanSpawnMobAt
with 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.