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

Structure blocks take and apply NBT data of entities and tile entities directly instead of a copy when loading and saving structures


    • Confirmed
    • Structures

      The bug

      Structure blocks do not make a copy of the NBT data of an entity or tile entity when they save it in a structure or when they load it from the structure. This results in multiple bugs:

      1. Loading a structure multiple times results in multiple entities or tile entities "sharing" the same NBT data
      2. Modifying an entity or tile entity which was saved as part of a structure might modify the NBT data of the respective entity or tile entity in the structure data as well
      3. Loading a structure with entities and tile entities and modifying them might modify the NBT data of the entity or tile entity which was saved as part of the structure

      How to reproduce

      1. Place a structure block
      2. Place a mob spawner on top of it and save it as structure
        /setblock ~ ~ ~ mob_spawner default replace {SpawnData:{id:"armor_stand"},SpawnCount:0s,SpawnRange:0s,MinSpawnDelay:0s,MaxSpawnDelay:0s,MaxNearbyEntities:1s,RequiredPlayerRange:16s,SpawnPotentials:[{Weight:1,Entity:{id:"bat"}}]}
      3. Load the structure at multiple positions in the world
      4. Right click one of the loaded spawners with for example a creeper spawn egg
      5. Go to the other spawners and check their NBT data (they won't update visually)
        /blockdata ~ ~-1 ~ {}

        → You will notice that id tag in the SpawnData tag has now the value "minecraft:creeper" (= case 1)

      6. Load the structure again
        → Even the newly loaded mob spawners will spawn creepers despite the fact that you did not overwrite the structure (= case 2)
      7. Set the time to night and use /blockdata on one of the loaded spawners to make it spawn the SpawnData entity and switch to the SpawnPotentials entry
        /time set 14000
        /blockdata ~ ~-1 ~ {SpawnCount:1b}
      8. Right click the spawner with for example a chicken spawn egg
      9. Use /blockdata on the spawner you saved in the structure
        /blockdata ~ ~-1 ~ {}

        → You will notice that its SpawnPotentials entry changed as well. Its value is now "minecraft:chicken" instead of "minecraft:bat" (= case 3)

      Code analysis

      Based on 1.11.2 decompiled using MCP 9.35 rc1

      The following methods do not make a copy of the NBT data taken from the world

      • net.minecraft.world.gen.structure.template.Template.takeEntitiesFromWorld(World, BlockPos, BlockPos)
      • net.minecraft.world.gen.structure.template.Template.takeBlocksFromWorld(World, BlockPos, BlockPos, boolean, Block)

      The following methods do not make a copy when loading entities respectively tile entities in the world

      • net.minecraft.world.gen.structure.template.Template.addEntitiesToWorld(World, BlockPos, Mirror, Rotation, StructureBoundingBox)
      • net.minecraft.world.gen.structure.template.Template.addBlocksToWorld(World, BlockPos, ITemplateProcessor, PlacementSettings, int)

            boq [Mojang] Bartosz Bok
            IceMetalPunk Daniel Burnett
            0 Vote for this issue
            5 Start watching this issue