diff --git a/src/main/java/chylex/hee/game/world/structure/IStructureWorld.kt b/src/main/java/chylex/hee/game/world/structure/IStructureWorld.kt
index ed50f11c..f5571cc6 100644
--- a/src/main/java/chylex/hee/game/world/structure/IStructureWorld.kt
+++ b/src/main/java/chylex/hee/game/world/structure/IStructureWorld.kt
@@ -20,6 +20,8 @@ interface IStructureWorld{
 	
 	fun addTrigger(pos: BlockPos, trigger: IStructureTrigger)
 	
+	fun finalize()
+	
 	// Utilities
 	
 	@JvmDefault fun getBlock(pos: BlockPos): Block{
diff --git a/src/main/java/chylex/hee/game/world/structure/world/OffsetStructureWorld.kt b/src/main/java/chylex/hee/game/world/structure/world/OffsetStructureWorld.kt
index d5e3cdfc..b1f3373d 100644
--- a/src/main/java/chylex/hee/game/world/structure/world/OffsetStructureWorld.kt
+++ b/src/main/java/chylex/hee/game/world/structure/world/OffsetStructureWorld.kt
@@ -18,4 +18,8 @@ class OffsetStructureWorld(private val wrapped: IStructureWorld, private val off
 	override fun addTrigger(pos: BlockPos, trigger: IStructureTrigger){
 		wrapped.addTrigger(pos.add(offset), trigger)
 	}
+	
+	override fun finalize(){
+		wrapped.finalize()
+	}
 }
diff --git a/src/main/java/chylex/hee/game/world/structure/world/RotatedStructureWorld.kt b/src/main/java/chylex/hee/game/world/structure/world/RotatedStructureWorld.kt
index 8e6c7847..f6576f39 100644
--- a/src/main/java/chylex/hee/game/world/structure/world/RotatedStructureWorld.kt
+++ b/src/main/java/chylex/hee/game/world/structure/world/RotatedStructureWorld.kt
@@ -58,4 +58,8 @@ class RotatedStructureWorld(private val wrapped: IStructureWorld, private val si
 	override fun addTrigger(pos: BlockPos, trigger: IStructureTrigger){
 		wrapped.addTrigger(rotatePos(pos, size, rotation), RotatedStructureTrigger(trigger, rotation))
 	}
+	
+	override fun finalize(){
+		wrapped.finalize()
+	}
 }
diff --git a/src/main/java/chylex/hee/game/world/structure/world/WorldToStructureWorldAdapter.kt b/src/main/java/chylex/hee/game/world/structure/world/WorldToStructureWorldAdapter.kt
new file mode 100644
index 00000000..0ac943d0
--- /dev/null
+++ b/src/main/java/chylex/hee/game/world/structure/world/WorldToStructureWorldAdapter.kt
@@ -0,0 +1,71 @@
+package chylex.hee.game.world.structure.world
+import chylex.hee.game.world.structure.IStructureTrigger
+import chylex.hee.game.world.structure.IStructureWorld
+import chylex.hee.init.ModBlocks
+import chylex.hee.system.util.FLAG_SYNC_CLIENT
+import chylex.hee.system.util.getState
+import chylex.hee.system.util.setState
+import net.minecraft.block.Block
+import net.minecraft.block.state.IBlockState
+import net.minecraft.init.Blocks
+import net.minecraft.util.Rotation
+import net.minecraft.util.math.BlockPos
+import net.minecraft.world.World
+
+class WorldToStructureWorldAdapter(private val world: World, private val offset: BlockPos) : IStructureWorld{
+	private companion object{
+		private val REQUIRE_SECOND_PASS = setOf<Block>(
+			Blocks.WOODEN_BUTTON,
+			Blocks.STONE_BUTTON,
+			Blocks.TORCH,
+			Blocks.REDSTONE_TORCH,
+			Blocks.UNLIT_REDSTONE_TORCH,
+			Blocks.REDSTONE_WIRE,
+			Blocks.VINE,
+			ModBlocks.DRY_VINES
+		)
+		
+		private val REQUIRE_IMMEDIATE_UPDATE = setOf<Block>(
+			Blocks.LAVA,
+			Blocks.WATER,
+			ModBlocks.ENDER_GOO
+		)
+	}
+	
+	private val secondPass = mutableMapOf<BlockPos, IBlockState>()
+	
+	override val rand = world.rand!!
+	
+	override fun getState(pos: BlockPos): IBlockState{
+		return secondPass[pos] ?: pos.add(offset).getState(world)
+	}
+	
+	override fun setState(pos: BlockPos, state: IBlockState){
+		val block = state.block
+		
+		if (REQUIRE_SECOND_PASS.contains(block)){
+			secondPass[pos] = state
+			return
+		}
+		
+		val worldPos = pos.add(offset)
+		worldPos.setState(world, state, FLAG_SYNC_CLIENT)
+		
+		if (REQUIRE_IMMEDIATE_UPDATE.contains(block)){
+			world.immediateBlockTick(worldPos, state, world.rand)
+			world.neighborChanged(worldPos, block, worldPos) // needed for liquids
+		}
+	}
+	
+	override fun addTrigger(pos: BlockPos, trigger: IStructureTrigger){
+		trigger.realize(world, pos.add(offset), Rotation.NONE)
+	}
+	
+	override fun finalize(){
+		for((pos, state) in secondPass){
+			pos.add(offset).setState(world, state, FLAG_SYNC_CLIENT)
+		}
+		
+		secondPass.clear()
+	}
+}