Uploaded image for project: 'Minecraft: Java Edition'
  1. Minecraft: Java Edition
  2. MC-271630

Pack spawning isolation issue for fortress mobs on nether bricks

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Unresolved
    • None
    • 24w18a, 1.20.6
    • None
    • Unconfirmed
    • (Unassigned)

      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 returned
      • Case 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 of NetherFortressStructure.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 on MobSpawnSettings.SpawnerData
      • Replace the java.util.List#contains call in canSpawnMobAt with something else

            Unassigned Unassigned
            Fallen_Breath Nellaforax
            Votes:
            7 Vote for this issue
            Watchers:
            4 Start watching this issue

              Created:
              Updated: