NBT pieces overriding a block entity during worldgen deadlocks/stalls the game
NBT pieces with block entity deadlocks or stalls the game. For example, if a fossil attempts to replace a bed from a village or sign from an igloo basement and such.
To reproduce:
- Attached datapack has all fossil NBT files replaced with files which only contain furnaces, barrels, and lecterns.
- Overrode the PlacedFeature for the fossil to increase its spawnrate to 40.
- Created a minecraft:desert_barebones biome json that only contains this PlacedFeature to make testing show it is that feature that is
- Replaced the overworld to only spawn that biome.
- Enter the world with the datapack. It may take a bit of time to create. Start travelling. The next chunk created will be stuck and the game will be stalled. (IF IT DOES NOT DEADLOCK HERE, exit and re-enter the world so that the block entities' stored level is not null and it should definitely deadlock when re-entering and trying to generate chunks.)
I attached a thread dump as well. Look at the Worker-Main-17 thread which is stuck.
This maximizes the chances of the new fossil to replace the blockentities placed by other fossils and deadlock the game. By default, fossils will not replace minecraft:feature_cannot_replace tagged blocks which includes spawners and chests. This is why this deadlock is trickier to trigger in vanilla.
The issue lies in StructureTemplate's placeInWorld method at line 329 where it calls blockentity2.setChanged(). Since placeInWorld is called during worldgen in the FossilFeature's class, the passed in world is a WorldGenRegion which is what all getBlockState/setBlockState calls must use. If a ServerLevel is used instead in a thread during worldgen, ServerLevel will park and wait for the chunk to finish generating before returning/setting a block which means, it causes the worldgen thread to wait on itself forever. A deadlock. Inside blockentity2.setChanged();, it is using the block entity's level which is a ServerLevel instead of a WorldGenRegion and later, it calls .getBlockState(...) and the deadlock is achieved. A temporary solution can be to only ever call blockentity2.setChanged(); if the level passed into StructureTemplate's placeInWorld is not a WorldGenRegion, thus bypassing the deadlock entirely.
There is a second spot that can deadlock and that is with the Clearable.tryClear(blockentity); in StructureTemplate's placeInWorld if the block entity being cleared is a lectern. This is because the lectern tries to call clearContent from the tryClear and it then calls this.setBook(ItemStack.EMPTY); and in there, it calls this.setChanged(); and triggers the deadlock described in the paragraph above this one.
Created Issue:
Nbt pieces overriding a block entity during worldgen deadlocks/stalls the game
To reproduce this bug, I created the attached datapack where I replaced all fossil nbt files with new nbt files that only contains Furnace, Barrel, and Lecterns. Then overrode the PlacedFeature for the fossil to increase its spawnrate to 200. Next I created a minecraft:desert_barebones biome json that only contains this PlacedFeature to make testing show it is that feature that is the problem. Then I replaced the overworld to only spawn that biome.
This maximizes the chances of the new fossil to replace the blockentities placed by other fossils and deadlock the game. By default, fossils will not replace minecraft:feature_cannot_replace tagged blocks which includes spawners and chests which is why this deadlock is tricker to trigger in vanilla. But it should be possible if a fossil attempts to replace a bed from a village or sign from an igloo basement and such.
Now when entering the world with the datapack, it may take a bit of time to create and eventually join, start travelling and the next chunk created will be stuck and the game stalled. The integrated server is now deadlocked. I attached a thread dump as well. Look at the Worker-Main-17 thread which is stuck.
The issue lies in StructureTemplate's placeInWorld method at line 329 where it calls blockentity2.setChanged(); Now since this placeInWorld is called during worldgen in the FossilFeature's class, the passed in world is a WorldGenRegion which is what all getBlockState/setBlockState calls must use. If a ServerLevel is used instead in a thread during worldgen, ServerLevel will park and wait for the chunk to finish generating before returning/setting a block which means, it causes the worldgen thread to wait on itself forever. A deadlock. Inside blockentity2.setChanged();, it is using the block entity's level which is a ServerLevel instead of a WorldGenRegion and later, it calls .getBlockState(...) and the deadlock is achieved. A temporary solution can be to only ever call blockentity2.setChanged(); if the level passed into StructureTemplate's placeInWorld is not a WorldGenRegion, thus bypassing the deadlock entirely.
To reproduce this bug, I created the attached datapack where I replaced all fossil nbt files with new nbt files that only contains Furnace, Barrel, and Lecterns. Then overrode the PlacedFeature for the fossil to increase its spawnrate to
200. Next I created a minecraft:desert_barebones biome json that only contains this PlacedFeature to make testing show it is that feature that is the problem. Then I replaced the overworld to only spawn that biome.This maximizes the chances of the new fossil to replace the blockentities placed by other fossils and deadlock the game. By default, fossils will not replace minecraft:feature_cannot_replace tagged blocks which includes spawners and chests which is why this deadlock is tricker to trigger in vanilla. But it should be possible if a fossil attempts to replace a bed from a village or sign from an igloo basement and such.
Now when entering the world with the datapack, it may take a bit of time to create and eventually join, start travelling and the next chunk created will be stuck and the game stalled. The integrated server is now deadlocked. I attached a thread dump as well. Look at the Worker-Main-17 thread which is stuck.
The issue lies in StructureTemplate's placeInWorld method at line 329 where it calls blockentity2.setChanged(); Now since this placeInWorld is called during worldgen in the FossilFeature's class, the passed in world is a WorldGenRegion which is what all getBlockState/setBlockState calls must use. If a ServerLevel is used instead in a thread during worldgen, ServerLevel will park and wait for the chunk to finish generating before returning/setting a block which means, it causes the worldgen thread to wait on itself forever. A deadlock. Inside blockentity2.setChanged();, it is using the block entity's level which is a ServerLevel instead of a WorldGenRegion and later, it calls .getBlockState(...) and the deadlock is achieved. A temporary solution can be to only ever call blockentity2.setChanged(); if the level passed into StructureTemplate's placeInWorld is not a WorldGenRegion, thus bypassing the deadlock entirely.
To reproduce this bug, I created the attached datapack where I replaced all fossil nbt files with new nbt files that only contains Furnace, Barrel, and Lecterns. Then overrode the PlacedFeature for the fossil to increase its spawnrate to 40. Next I created a minecraft:desert_barebones biome json that only contains this PlacedFeature to make testing show it is that feature that is the problem. Then I replaced the overworld to only spawn that biome.
This maximizes the chances of the new fossil to replace the blockentities placed by other fossils and deadlock the game. By default, fossils will not replace minecraft:feature_cannot_replace tagged blocks which includes spawners and chests which is why this deadlock is tricker to trigger in vanilla. But it should be possible if a fossil attempts to replace a bed from a village or sign from an igloo basement and such.
Now when entering the world with the datapack, it may take a bit of time to create and eventually join, start travelling and the next chunk created will be stuck and the game stalled. The integrated server is now deadlocked. I attached a thread dump as well. Look at the Worker-Main-17 thread which is stuck.
The issue lies in StructureTemplate's placeInWorld method at line 329 where it calls blockentity2.setChanged(); Now since this placeInWorld is called during worldgen in the FossilFeature's class, the passed in world is a WorldGenRegion which is what all getBlockState/setBlockState calls must use. If a ServerLevel is used instead in a thread during worldgen, ServerLevel will park and wait for the chunk to finish generating before returning/setting a block which means, it causes the worldgen thread to wait on itself forever. A deadlock. Inside blockentity2.setChanged();, it is using the block entity's level which is a ServerLevel instead of a WorldGenRegion and later, it calls .getBlockState(...) and the deadlock is achieved. A temporary solution can be to only ever call blockentity2.setChanged(); if the level passed into StructureTemplate's placeInWorld is not a WorldGenRegion, thus bypassing the deadlock entirely.
To reproduce this bug, I created the attached datapack where I replaced all fossil nbt files with new nbt files that only contains Furnace, Barrel, and Lecterns. Then overrode the PlacedFeature for the fossil to increase its spawnrate to 40. Next I created a minecraft:desert_barebones biome json that only contains this PlacedFeature to make testing show it is that feature that is the problem. Then I replaced the overworld to only spawn that biome.
This maximizes the chances of the new fossil to replace the blockentities placed by other fossils and deadlock the game. By default, fossils will not replace minecraft:feature_cannot_replace tagged blocks which includes spawners and chests which is why this deadlock is tricker to trigger in vanilla. But it should be possible if a fossil attempts to replace a bed from a village or sign from an igloo basement and such.
Now when entering the world with the datapack, it may take a bit of time to create and eventually join, start travelling and the next chunk created will be stuck and the game stalled.
The integrated serveris now deadlocked. I attached a thread dump as well. Look at the Worker-Main-17 thread which is stuck.The issue lies in StructureTemplate's placeInWorld method at line 329 where it calls blockentity2.setChanged(); Now since this placeInWorld is called during worldgen in the FossilFeature's class, the passed in world is a WorldGenRegion which is what all getBlockState/setBlockState calls must use. If a ServerLevel is used instead in a thread during worldgen, ServerLevel will park and wait for the chunk to finish generating before returning/setting a block which means, it causes the worldgen thread to wait on itself forever. A deadlock. Inside blockentity2.setChanged();, it is using the block entity's level which is a ServerLevel instead of a WorldGenRegion and later, it calls .getBlockState(...) and the deadlock is achieved. A temporary solution can be to only ever call blockentity2.setChanged(); if the level passed into StructureTemplate's placeInWorld is not a WorldGenRegion, thus bypassing the deadlock entirely.
To reproduce this bug, I created the attached datapack where I replaced all fossil nbt files with new nbt files that only contains Furnace, Barrel, and Lecterns. Then overrode the PlacedFeature for the fossil to increase its spawnrate to 40. Next I created a minecraft:desert_barebones biome json that only contains this PlacedFeature to make testing show it is that feature that is the problem. Then I replaced the overworld to only spawn that biome.
This maximizes the chances of the new fossil to replace the blockentities placed by other fossils and deadlock the game. By default, fossils will not replace minecraft:feature_cannot_replace tagged blocks which includes spawners and chests which is why this deadlock is tricker to trigger in vanilla. But it should be possible if a fossil attempts to replace a bed from a village or sign from an igloo basement and such.
Now when entering the world with the datapack, it may take a bit of time to create and eventually join, start travelling and the next chunk created will be stuck and the game stalled. IF IT DOES NOT DEADLOCK HERE, exit and re-enter the world so that the block entities's stored level is not null and it should definitely deadlock when re-entering and trying to generate chunks now. I attached a thread dump as well. Look at the Worker-Main-17 thread which is stuck.
The issue lies in StructureTemplate's placeInWorld method at line 329 where it calls blockentity2.setChanged(); Now since this placeInWorld is called during worldgen in the FossilFeature's class, the passed in world is a WorldGenRegion which is what all getBlockState/setBlockState calls must use. If a ServerLevel is used instead in a thread during worldgen, ServerLevel will park and wait for the chunk to finish generating before returning/setting a block which means, it causes the worldgen thread to wait on itself forever. A deadlock. Inside blockentity2.setChanged();, it is using the block entity's level which is a ServerLevel instead of a WorldGenRegion and later, it calls .getBlockState(...) and the deadlock is achieved. A temporary solution can be to only ever call blockentity2.setChanged(); if the level passed into StructureTemplate's placeInWorld is not a WorldGenRegion, thus bypassing the deadlock entirely.
To reproduce this bug, I created the attached datapack where I replaced all fossil nbt files with new nbt files that only contains Furnace, Barrel, and Lecterns. Then overrode the PlacedFeature for the fossil to increase its spawnrate to 40. Next I created a minecraft:desert_barebones biome json that only contains this PlacedFeature to make testing show it is that feature that is the problem. Then I replaced the overworld to only spawn that biome.
This maximizes the chances of the new fossil to replace the blockentities placed by other fossils and deadlock the game. By default, fossils will not replace minecraft:feature_cannot_replace tagged blocks which includes spawners and chests which is why this deadlock is tricker to trigger in vanilla. But it should be possible if a fossil attempts to replace a bed from a village or sign from an igloo basement and such.
Now when entering the world with the datapack, it may take a bit of time to create and eventually join, start travelling and the next chunk created will be stuck and the game stalled. IF IT DOES NOT DEADLOCK HERE, exit and re-enter the world so that the block entities's stored level is not null and it should definitely deadlock when re-entering and trying to generate chunks now. I attached a thread dump as well. Look at the Worker-Main-17 thread which is stuck.
The issue lies in StructureTemplate's placeInWorld method at line 329 where it calls blockentity2.setChanged(); Now since this placeInWorld is called during worldgen in the FossilFeature's class, the passed in world is a WorldGenRegion which is what all getBlockState/setBlockState calls must use. If a ServerLevel is used instead in a thread during worldgen, ServerLevel will park and wait for the chunk to finish generating before returning/setting a block which means, it causes the worldgen thread to wait on itself forever. A deadlock. Inside blockentity2.setChanged();, it is using the block entity's level which is a ServerLevel instead of a WorldGenRegion and later, it calls .getBlockState(...) and the deadlock is achieved. A temporary solution can be to only ever call blockentity2.setChanged(); if the level passed into StructureTemplate's placeInWorld is not a WorldGenRegion, thus bypassing the deadlock entirely.
There is a second spot that can deadlock and that is with the Clearable.tryClear(blockentity); in StructureTemplate's placeInWorld if the block entity being cleared is a lectern. This is because the lectern tries to call clearContent from the tryClear and it then calls this.setBook(ItemStack.EMPTY); and in there,
To reproduce this bug, I created the attached datapack where I replaced all fossil nbt files with new nbt files that only contains Furnace, Barrel, and Lecterns. Then overrode the PlacedFeature for the fossil to increase its spawnrate to 40. Next I created a minecraft:desert_barebones biome json that only contains this PlacedFeature to make testing show it is that feature that is the problem. Then I replaced the overworld to only spawn that biome.
This maximizes the chances of the new fossil to replace the blockentities placed by other fossils and deadlock the game. By default, fossils will not replace minecraft:feature_cannot_replace tagged blocks which includes spawners and chests which is why this deadlock is tricker to trigger in vanilla. But it should be possible if a fossil attempts to replace a bed from a village or sign from an igloo basement and such.
Now when entering the world with the datapack, it may take a bit of time to create and eventually join, start travelling and the next chunk created will be stuck and the game stalled. IF IT DOES NOT DEADLOCK HERE, exit and re-enter the world so that the block entities's stored level is not null and it should definitely deadlock when re-entering and trying to generate chunks now. I attached a thread dump as well. Look at the Worker-Main-17 thread which is stuck.
The issue lies in StructureTemplate's placeInWorld method at line 329 where it calls blockentity2.setChanged(); Now since this placeInWorld is called during worldgen in the FossilFeature's class, the passed in world is a WorldGenRegion which is what all getBlockState/setBlockState calls must use. If a ServerLevel is used instead in a thread during worldgen, ServerLevel will park and wait for the chunk to finish generating before returning/setting a block which means, it causes the worldgen thread to wait on itself forever. A deadlock. Inside blockentity2.setChanged();, it is using the block entity's level which is a ServerLevel instead of a WorldGenRegion and later, it calls .getBlockState(...) and the deadlock is achieved. A temporary solution can be to only ever call blockentity2.setChanged(); if the level passed into StructureTemplate's placeInWorld is not a WorldGenRegion, thus bypassing the deadlock entirely.
There is a second spot that can deadlock and that is with the Clearable.tryClear(blockentity); in StructureTemplate's placeInWorld if the block entity being cleared is a lectern. This is because the lectern tries to call clearContent from the tryClear and it then calls
this.setBook(ItemStack.EMPTY); and in there,To reproduce this bug, I created the attached datapack where I replaced all fossil nbt files with new nbt files that only contains Furnace, Barrel, and Lecterns. Then overrode the PlacedFeature for the fossil to increase its spawnrate to 40. Next I created a minecraft:desert_barebones biome json that only contains this PlacedFeature to make testing show it is that feature that is the problem. Then I replaced the overworld to only spawn that biome.
This maximizes the chances of the new fossil to replace the blockentities placed by other fossils and deadlock the game. By default, fossils will not replace minecraft:feature_cannot_replace tagged blocks which includes spawners and chests which is why this deadlock is tricker to trigger in vanilla. But it should be possible if a fossil attempts to replace a bed from a village or sign from an igloo basement and such.
Now when entering the world with the datapack, it may take a bit of time to create and eventually join, start travelling and the next chunk created will be stuck and the game stalled. IF IT DOES NOT DEADLOCK HERE, exit and re-enter the world so that the block entities's stored level is not null and it should definitely deadlock when re-entering and trying to generate chunks now. I attached a thread dump as well. Look at the Worker-Main-17 thread which is stuck.
The issue lies in StructureTemplate's placeInWorld method at line 329 where it calls blockentity2.setChanged(); Now since this placeInWorld is called during worldgen in the FossilFeature's class, the passed in world is a WorldGenRegion which is what all getBlockState/setBlockState calls must use. If a ServerLevel is used instead in a thread during worldgen, ServerLevel will park and wait for the chunk to finish generating before returning/setting a block which means, it causes the worldgen thread to wait on itself forever. A deadlock. Inside blockentity2.setChanged();, it is using the block entity's level which is a ServerLevel instead of a WorldGenRegion and later, it calls .getBlockState(...) and the deadlock is achieved. A temporary solution can be to only ever call blockentity2.setChanged(); if the level passed into StructureTemplate's placeInWorld is not a WorldGenRegion, thus bypassing the deadlock entirely.
There is a second spot that can deadlock and that is with the Clearable.tryClear(blockentity); in StructureTemplate's placeInWorld if the block entity being cleared is a lectern. This is because the lectern tries to call clearContent from the tryClear and it then calls this.setBook(ItemStack.EMPTY); and in there, it calls this.setChanged(); and triggers the deadlock described in the paragraph above this on.
To reproduce this bug, I created the attached datapack where I replaced all fossil nbt files with new nbt files that only contains Furnace, Barrel, and Lecterns. Then overrode the PlacedFeature for the fossil to increase its spawnrate to 40. Next I created a minecraft:desert_barebones biome json that only contains this PlacedFeature to make testing show it is that feature that is the problem. Then I replaced the overworld to only spawn that biome.
This maximizes the chances of the new fossil to replace the blockentities placed by other fossils and deadlock the game. By default, fossils will not replace minecraft:feature_cannot_replace tagged blocks which includes spawners and chests which is why this deadlock is tricker to trigger in vanilla. But it should be possible if a fossil attempts to replace a bed from a village or sign from an igloo basement and such.
Now when entering the world with the datapack, it may take a bit of time to create and eventually join, start travelling and the next chunk created will be stuck and the game stalled. IF IT DOES NOT DEADLOCK HERE, exit and re-enter the world so that the block entities's stored level is not null and it should definitely deadlock when re-entering and trying to generate chunks now. I attached a thread dump as well. Look at the Worker-Main-17 thread which is stuck.
The issue lies in StructureTemplate's placeInWorld method at line 329 where it calls blockentity2.setChanged(); Now since this placeInWorld is called during worldgen in the FossilFeature's class, the passed in world is a WorldGenRegion which is what all getBlockState/setBlockState calls must use. If a ServerLevel is used instead in a thread during worldgen, ServerLevel will park and wait for the chunk to finish generating before returning/setting a block which means, it causes the worldgen thread to wait on itself forever. A deadlock. Inside blockentity2.setChanged();, it is using the block entity's level which is a ServerLevel instead of a WorldGenRegion and later, it calls .getBlockState(...) and the deadlock is achieved. A temporary solution can be to only ever call blockentity2.setChanged(); if the level passed into StructureTemplate's placeInWorld is not a WorldGenRegion, thus bypassing the deadlock entirely.
There is a second spot that can deadlock and that is with the Clearable.tryClear(blockentity); in StructureTemplate's placeInWorld if the block entity being cleared is a lectern. This is because the lectern tries to call clearContent from the tryClear and it then calls this.setBook(ItemStack.EMPTY); and in there, it calls
this.setChanged(); and triggers the deadlock described in the paragraph above this on.To reproduce this bug, I created the attached datapack where I replaced all fossil nbt files with new nbt files that only contains Furnace, Barrel, and Lecterns. Then overrode the PlacedFeature for the fossil to increase its spawnrate to 40. Next I created a minecraft:desert_barebones biome json that only contains this PlacedFeature to make testing show it is that feature that is the problem. Then I replaced the overworld to only spawn that biome.
This maximizes the chances of the new fossil to replace the blockentities placed by other fossils and deadlock the game. By default, fossils will not replace minecraft:feature_cannot_replace tagged blocks which includes spawners and chests which is why this deadlock is tricker to trigger in vanilla. But it should be possible if a fossil attempts to replace a bed from a village or sign from an igloo basement and such.
Now when entering the world with the datapack, it may take a bit of time to create and eventually join, start travelling and the next chunk created will be stuck and the game stalled. IF IT DOES NOT DEADLOCK HERE, exit and re-enter the world so that the block entities's stored level is not null and it should definitely deadlock when re-entering and trying to generate chunks now. I attached a thread dump as well. Look at the Worker-Main-17 thread which is stuck.
The issue lies in StructureTemplate's placeInWorld method at line 329 where it calls blockentity2.setChanged(); Now since this placeInWorld is called during worldgen in the FossilFeature's class, the passed in world is a WorldGenRegion which is what all getBlockState/setBlockState calls must use. If a ServerLevel is used instead in a thread during worldgen, ServerLevel will park and wait for the chunk to finish generating before returning/setting a block which means, it causes the worldgen thread to wait on itself forever. A deadlock. Inside blockentity2.setChanged();, it is using the block entity's level which is a ServerLevel instead of a WorldGenRegion and later, it calls .getBlockState(...) and the deadlock is achieved. A temporary solution can be to only ever call blockentity2.setChanged(); if the level passed into StructureTemplate's placeInWorld is not a WorldGenRegion, thus bypassing the deadlock entirely.
There is a second spot that can deadlock and that is with the Clearable.tryClear(blockentity); in StructureTemplate's placeInWorld if the block entity being cleared is a lectern. This is because the lectern tries to call clearContent from the tryClear and it then calls this.setBook(ItemStack.EMPTY); and in there, it calls this.setChanged(); and triggers the deadlock described in the paragraph above this one.
To reproduce this bug, I created the attached datapack where I replaced all fossil nbt files with new nbt files that only contains Furnace, Barrel, and Lecterns. Then overrode the PlacedFeature for the fossil to increase its spawnrate to 40. Next I created a minecraft:desert_barebones biome json that only contains this PlacedFeature to make testing show it is that feature that is the problem. Then I replaced the overworld to only spawn that biome.
This maximizes the chances of the new fossil to replace the blockentities placed by other fossils and deadlock the game. By default, fossils will not replace minecraft:feature_cannot_replace tagged blocks which includes spawners and chests which is why this deadlock is trickier to trigger in vanilla. But it should be possible if a fossil attempts to replace a bed from a village or sign from an igloo basement and such.
Now when entering the world with the datapack, it may take a bit of time to create and eventually join, start travelling and the next chunk created will be stuck and the game stalled. IF IT DOES NOT DEADLOCK HERE, exit and re-enter the world so that the block entities's stored level is not null and it should definitely deadlock when re-entering and trying to generate chunks now. I attached a thread dump as well. Look at the Worker-Main-17 thread which is stuck.
The issue lies in StructureTemplate's placeInWorld method at line 329 where it calls blockentity2.setChanged(); Now since this placeInWorld is called during worldgen in the FossilFeature's class, the passed in world is a WorldGenRegion which is what all getBlockState/setBlockState calls must use. If a ServerLevel is used instead in a thread during worldgen, ServerLevel will park and wait for the chunk to finish generating before returning/setting a block which means, it causes the worldgen thread to wait on itself forever. A deadlock. Inside blockentity2.setChanged();, it is using the block entity's level which is a ServerLevel instead of a WorldGenRegion and later, it calls .getBlockState(...) and the deadlock is achieved. A temporary solution can be to only ever call blockentity2.setChanged(); if the level passed into StructureTemplate's placeInWorld is not a WorldGenRegion, thus bypassing the deadlock entirely.
There is a second spot that can deadlock and that is with the Clearable.tryClear(blockentity); in StructureTemplate's placeInWorld if the block entity being cleared is a lectern. This is because the lectern tries to call clearContent from the tryClear and it then calls this.setBook(ItemStack.EMPTY); and in there, it calls this.setChanged(); and triggers the deadlock described in the paragraph above this one.
To reproduce this bug, I created the attached datapack where I replaced all fossil nbt files with new nbt files that only contains Furnace, Barrel, and Lecterns. Then overrode the PlacedFeature for the fossil to increase its spawnrate to 40. Next I created a minecraft:desert_barebones biome json that only contains this PlacedFeature to make testing show it is that feature that is the problem. Then I replaced the overworld to only spawn that biome.This maximizes the chances of the new fossil to replace the blockentities placed by other fossils and deadlock the game. By default, fossils will not replace minecraft:feature_cannot_replace tagged blocks which includes spawners and chests which is why this deadlock is trickier to trigger in vanilla. But it should be possible if a fossil attempts to replace a bed from a village or sign from an igloo basement and such.
Now when entering the world with the datapack, it may take a bit of time to create and eventually join, start travelling and the next chunk created will be stuck and the game stalled. IF IT DOES NOT DEADLOCK HERE, exit and re-enter the world so that the block entities's stored level is not null and it should definitely deadlock when re-entering and trying to generate chunks now. I attached a thread dump as well. Look at the Worker-Main-17 thread which is stuck.The issue lies in StructureTemplate's placeInWorld method at line 329 where it calls blockentity2.setChanged(); Now since this placeInWorld is called during worldgen in the FossilFeature's class, the passed in world is a WorldGenRegion which is what all getBlockState/setBlockState calls must use. If a ServerLevel is used instead in a thread during worldgen, ServerLevel will park and wait for the chunk to finish generating before returning/setting a block which means, it causes the worldgen thread to wait on itself forever. A deadlock. Inside blockentity2.setChanged();, it is using the block entity's level which is a ServerLevel instead of a WorldGenRegion and later, it calls .getBlockState(...) and the deadlock is achieved. A temporary solution can be to only ever call blockentity2.setChanged(); if the level passed into StructureTemplate's placeInWorld is not a WorldGenRegion, thus bypassing the deadlock entirely.
There is a second spot that can deadlock and that is with the Clearable.tryClear(blockentity); in StructureTemplate's placeInWorld if the block entity being cleared is a lectern. This is because the lectern tries to call clearContent from the tryClear and it then calls this.setBook(ItemStack.EMPTY); and in there, it calls this.setChanged(); and triggers the deadlock described in the paragraph above this one.
NBT pieces with block entity deadlocks or stalls the game. For example, if a fossil attempts to replace a bed from a village or sign from an igloo basement and such.
To reproduce:
- Attached datapack has all fossil NBT files replaced with files which only contain furnaces, barrels, and lecterns.
- Overrode the PlacedFeature for the fossil to increase its spawnrate to 40.
- Created a minecraft:desert_barebones biome json that only contains this PlacedFeature to make testing show it is that feature that is
- Replaced the overworld to only spawn that biome.
- Enter the world with the datapack. It may take a bit of time to create. Start travelling. The next chunk created will be stuck and the game will be stalled. (IF IT DOES NOT DEADLOCK HERE, exit and re-enter the world so that the block entities' stored level is not null and it should definitely deadlock when re-entering and trying to generate chunks.)
I attached a thread dump as well. Look at the Worker-Main-17 thread which is stuck.
This maximizes the chances of the new fossil to replace the blockentities placed by other fossils and deadlock the game. By default, fossils will not replace minecraft:feature_cannot_replace tagged blocks which includes spawners and chests. This is why this deadlock is trickier to trigger in vanilla.
The issue lies in StructureTemplate's placeInWorld method at line 329 where it calls blockentity2.setChanged(). Since placeInWorld is called during worldgen in the FossilFeature's class, the passed in world is a WorldGenRegion which is what all getBlockState/setBlockState calls must use. If a ServerLevel is used instead in a thread during worldgen, ServerLevel will park and wait for the chunk to finish generating before returning/setting a block which means, it causes the worldgen thread to wait on itself forever. A deadlock. Inside blockentity2.setChanged();, it is using the block entity's level which is a ServerLevel instead of a WorldGenRegion and later, it calls .getBlockState(...) and the deadlock is achieved. A temporary solution can be to only ever call blockentity2.setChanged(); if the level passed into StructureTemplate's placeInWorld is not a WorldGenRegion, thus bypassing the deadlock entirely.
There is a second spot that can deadlock and that is with the Clearable.tryClear(blockentity); in StructureTemplate's placeInWorld if the block entity being cleared is a lectern. This is because the lectern tries to call clearContent from the tryClear and it then calls this.setBook(ItemStack.EMPTY); and in there, it calls this.setChanged(); and triggers the deadlock described in the paragraph above this one.
Nbtpieces overriding a block entity during worldgen deadlocks/stalls the gameNBT pieces overriding a block entity during worldgen deadlocks/stalls the game
relates to
relates to
relates to
Relates to MC-199487 and MC-246262 (same/similar root cause)
Analysis (yarn mapping):
This is another "getChunk during worldgen" deadlock. (Not an infinite loop.) Entity#readNbt (ayl.g, L1687) is a method that reads a NBT compound and sets an entity's fields. (While I could not figure out which entity it is, One of the operations include Entity#setPos (aly.o, L3212) which sets the new position of an entity and calls several callbacks. One of the callbacks called is EntityGameEventHandler#onEntitySetPos (cvx.a, L34), which calls EntityGameEventHandler#updateDispatcher (cvx.a, L46), a method that queries the chunk for the new position of the entity. This uses the getChunk method.
Since the chunk queried is currently generating, getChunk never returns until the chunk is fully generated. However, since the getChunk call is part of the chunk generation, getChunk must return to fully generate the chunk. This obviously causes a deadlock.
Improved readability of the description.
seems to be fixed in 1.19. Unable to reproduce anymore