--- a/net/minecraft/world/level/levelgen/structure/StructureStart.java
+++ b/net/minecraft/world/level/levelgen/structure/StructureStart.java
@@ -32,6 +32,12 @@
     @Nullable
     private volatile StructureBoundingBox cachedBoundingBox;
 
+    // CraftBukkit start
+    private static final org.bukkit.craftbukkit.persistence.CraftPersistentDataTypeRegistry DATA_TYPE_REGISTRY = new org.bukkit.craftbukkit.persistence.CraftPersistentDataTypeRegistry();
+    public org.bukkit.craftbukkit.persistence.DirtyCraftPersistentDataContainer persistentDataContainer = new org.bukkit.craftbukkit.persistence.DirtyCraftPersistentDataContainer(DATA_TYPE_REGISTRY);
+    public org.bukkit.event.world.AsyncStructureGenerateEvent.Cause generationEventCause = org.bukkit.event.world.AsyncStructureGenerateEvent.Cause.WORLD_GENERATION;
+    // CraftBukkit end
+
     public StructureStart(Structure structure, ChunkCoordIntPair chunkcoordintpair, int i, PiecesContainer piecescontainer) {
         this.structure = structure;
         this.chunkPos = chunkcoordintpair;
@@ -91,6 +97,8 @@
             StructureBoundingBox structureboundingbox1 = ((StructurePiece) list.get(0)).boundingBox;
             BlockPosition blockposition = structureboundingbox1.getCenter();
             BlockPosition blockposition1 = new BlockPosition(blockposition.getX(), structureboundingbox1.minY(), blockposition.getZ());
+            // CraftBukkit start
+            /*
             Iterator iterator = list.iterator();
 
             while (iterator.hasNext()) {
@@ -100,6 +108,18 @@
                     structurepiece.postProcess(generatoraccessseed, structuremanager, chunkgenerator, randomsource, structureboundingbox, chunkcoordintpair, blockposition1);
                 }
             }
+            */
+            List<StructurePiece> pieces = list.stream().filter(piece -> piece.getBoundingBox().intersects(structureboundingbox)).toList();
+            if (!pieces.isEmpty()) {
+                org.bukkit.craftbukkit.util.TransformerGeneratorAccess transformerAccess = new org.bukkit.craftbukkit.util.TransformerGeneratorAccess();
+                transformerAccess.setHandle(generatoraccessseed);
+                transformerAccess.setStructureTransformer(new org.bukkit.craftbukkit.util.CraftStructureTransformer(generationEventCause, generatoraccessseed, structuremanager, structure, structureboundingbox, chunkcoordintpair));
+                for (StructurePiece piece : pieces) {
+                    piece.postProcess(transformerAccess, structuremanager, chunkgenerator, randomsource, structureboundingbox, chunkcoordintpair, blockposition1);
+                }
+                transformerAccess.getStructureTransformer().discard();
+            }
+            // CraftBukkit end
 
             this.structure.afterPlace(generatoraccessseed, structuremanager, chunkgenerator, randomsource, structureboundingbox, chunkcoordintpair, this.pieceContainer);
         }
@@ -107,6 +127,11 @@
 
     public NBTTagCompound createTag(StructurePieceSerializationContext structurepieceserializationcontext, ChunkCoordIntPair chunkcoordintpair) {
         NBTTagCompound nbttagcompound = new NBTTagCompound();
+        // CraftBukkit start - store persistent data in nbt
+        if (!persistentDataContainer.isEmpty()) {
+            nbttagcompound.put("StructureBukkitValues", persistentDataContainer.toTagCompound());
+        }
+        // CraftBukkit end
 
         if (this.isValid()) {
             nbttagcompound.putString("id", structurepieceserializationcontext.registryAccess().lookupOrThrow(Registries.STRUCTURE).getKey(this.structure).toString());
