diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/MatteryBlockEntity.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/MatteryBlockEntity.kt
index 1d3ef857c..2cdd698da 100644
--- a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/MatteryBlockEntity.kt
+++ b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/MatteryBlockEntity.kt
@@ -67,7 +67,7 @@ import kotlin.reflect.KProperty
 import kotlin.reflect.KProperty0
 
 /**
- * Absolute barebone block entity class in Overdrive that Matters, providing bare minimum functionality
+ * Absolute barebone (lol) block entity class in Overdrive that Matters, providing bare minimum (lulmao, minecraft engine) functionality
  */
 abstract class MatteryBlockEntity(p_155228_: BlockEntityType<*>, p_155229_: BlockPos, p_155230_: BlockState) : BlockEntity(p_155228_, p_155229_, p_155230_) {
 	private var isSynchronizing = false
@@ -97,8 +97,17 @@ abstract class MatteryBlockEntity(p_155228_: BlockEntityType<*>, p_155229_: Bloc
 	private data class SidelessCap<T : Any>(val cap: T, var optional: LazyOptional<T>)
 	private val sidelessCaps = Reference2ObjectOpenHashMap<Capability<*>, SidelessCap<*>>()
 	protected val tickList = TickList()
+
+	/**
+	 * Shared savetables, written both to level storage and to item tag
+	 */
 	protected val savetables = Savetables()
 
+	/**
+	 * Level-only savetables, written only to level storage
+	 */
+	protected val savetablesLevel = Savetables()
+
 	open fun tick() {
 		tickList.tick()
 	}
@@ -401,14 +410,30 @@ abstract class MatteryBlockEntity(p_155228_: BlockEntityType<*>, p_155229_: Bloc
 		savetables.stateful(property, name, T::class.java)
 	}
 
-	override fun saveAdditional(nbt: CompoundTag) {
+	final override fun saveAdditional(nbt: CompoundTag) {
 		super.saveAdditional(nbt)
+		saveShared(nbt)
+		saveLevel(nbt)
+	}
+
+	/**
+	 * Saved both to item dropped, and to level storage
+	 */
+	open fun saveShared(nbt: CompoundTag) {
 		savetables.serializeNBT(nbt)
 	}
 
+	/**
+	 * Only saved to level storage, discarded when dropped as item
+	 */
+	open fun saveLevel(nbt: CompoundTag) {
+		savetablesLevel.serializeNBT(nbt)
+	}
+
 	override fun load(nbt: CompoundTag) {
 		super.load(nbt)
 		savetables.deserializeNBT(nbt)
+		savetablesLevel.deserializeNBT(nbt)
 	}
 
 	@Suppress("OVERRIDE_DEPRECATION")
diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/MatteryDeviceBlockEntity.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/MatteryDeviceBlockEntity.kt
index 74216b68f..dcef9b156 100644
--- a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/MatteryDeviceBlockEntity.kt
+++ b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/MatteryDeviceBlockEntity.kt
@@ -62,8 +62,9 @@ abstract class MatteryDeviceBlockEntity(blockEntityType: BlockEntityType<*>, blo
 
 	protected open fun redstoneStatusUpdated(newBlocked: Boolean, oldBlocked: Boolean) {}
 
-	override fun saveAdditional(nbt: CompoundTag) {
-		super.saveAdditional(nbt)
+	override fun saveShared(nbt: CompoundTag) {
+		super.saveShared(nbt)
+
 		if (customDisplayName != null)
 			nbt.putJson("Name", Component.Serializer.toJsonTree(customDisplayName!!))
 	}
diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/MatteryPoweredBlockEntity.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/MatteryPoweredBlockEntity.kt
index 9a7390335..a563312ce 100644
--- a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/MatteryPoweredBlockEntity.kt
+++ b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/MatteryPoweredBlockEntity.kt
@@ -25,7 +25,7 @@ abstract class MatteryPoweredBlockEntity(p_155228_: BlockEntityType<*>, p_155229
 	val batteryItemHandler = batteryContainer.handler(HandlerFilter.Dischargeable)
 
 	init {
-		savetable(::batteryContainer, BATTERY_KEY)
+		savetables.stateful(::batteryContainer, BATTERY_KEY)
 	}
 
 	override fun tick() {
diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/MatteryWorkerBlockEntity.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/MatteryWorkerBlockEntity.kt
index 0bf39c687..b19fee0c5 100644
--- a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/MatteryWorkerBlockEntity.kt
+++ b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/MatteryWorkerBlockEntity.kt
@@ -156,8 +156,8 @@ abstract class MatteryWorkerBlockEntity<JobType : MatteryWorkerBlockEntity.Job>(
 			return (workTicks / currentJob.ticks).coerceAtMost(1.0).toFloat()
 		}
 
-	override fun saveAdditional(nbt: CompoundTag) {
-		super.saveAdditional(nbt)
+	override fun saveShared(nbt: CompoundTag) {
+		super.saveShared(nbt)
 		nbt[WORK_TICKS_KEY] = workTicks
 		currentJob?.let { nbt[JOB_KEY] = it.serializeNBT() }
 	}
diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/blackhole/BlackHoleBlockEntity.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/blackhole/BlackHoleBlockEntity.kt
index 55697319c..41e9360d7 100644
--- a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/blackhole/BlackHoleBlockEntity.kt
+++ b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/blackhole/BlackHoleBlockEntity.kt
@@ -161,8 +161,8 @@ class BlackHoleBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) : Mattery
 		}
 	}
 
-	public override fun saveAdditional(nbt: CompoundTag) {
-		super.saveAdditional(nbt)
+	override fun saveLevel(nbt: CompoundTag) {
+		super.saveLevel(nbt)
 		nbt["mass"] = mass.serializeNBT()
 		nbt["spin_direction"] = spinDirection
 	}
diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/decorative/CargoCrateBlockEntity.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/decorative/CargoCrateBlockEntity.kt
index e1bf6e0e6..25fc2140c 100644
--- a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/decorative/CargoCrateBlockEntity.kt
+++ b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/decorative/CargoCrateBlockEntity.kt
@@ -84,11 +84,11 @@ class CargoCrateBlockEntity(
 
 	init {
 		exposeItemsGlobally(handler)
-		savetable(::container, INVENTORY_KEY)
+		savetablesLevel.stateful(::container, INVENTORY_KEY)
 	}
 
-	override fun saveAdditional(nbt: CompoundTag) {
-		super.saveAdditional(nbt)
+	override fun saveLevel(nbt: CompoundTag) {
+		super.saveLevel(nbt)
 		lootTable?.let { nbt[LOOT_TABLE_KEY] = it.toString() }
 		lootTableSeed?.let { nbt[LOOT_TABLE_SEED_KEY] = it }
 	}
diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/decorative/HoloSignBlockEntity.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/decorative/HoloSignBlockEntity.kt
index e6eecaf09..3e2884aa4 100644
--- a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/decorative/HoloSignBlockEntity.kt
+++ b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/decorative/HoloSignBlockEntity.kt
@@ -29,7 +29,7 @@ class HoloSignBlockEntity(blockPos: BlockPos, blockState: BlockState) : MatteryB
 
 	init {
 		savetables.string(::signText)
-		savetables.bool(::isLocked)
+		savetablesLevel.bool(::isLocked)
 		savetables.stateful(::redstoneControl)
 	}
 
diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/matter/MatterBottlerBlockEntity.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/matter/MatterBottlerBlockEntity.kt
index 87d3d7b84..812c7045d 100644
--- a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/matter/MatterBottlerBlockEntity.kt
+++ b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/matter/MatterBottlerBlockEntity.kt
@@ -46,11 +46,6 @@ class MatterBottlerBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) :
 			this.setChangedLight()
 		}
 
-	fun switchWorkFlow() {
-		isBottling = !isBottling
-		updateBlockState()
-	}
-
 	private fun updateBlockState() {
 		val level = level as? ServerLevel ?: return
 
diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/matter/MatterPanelBlockEntity.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/matter/MatterPanelBlockEntity.kt
index 76284295d..b51146f0e 100644
--- a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/matter/MatterPanelBlockEntity.kt
+++ b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/matter/MatterPanelBlockEntity.kt
@@ -140,8 +140,8 @@ class MatterPanelBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) :
 		return true
 	}
 
-	override fun saveAdditional(nbt: CompoundTag) {
-		super.saveAdditional(nbt)
+	override fun saveShared(nbt: CompoundTag) {
+		super.saveShared(nbt)
 
 		val list = ListTag()
 
diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/storage/ItemMonitorBlockEntity.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/storage/ItemMonitorBlockEntity.kt
index 1bb496c93..73247f2d3 100644
--- a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/storage/ItemMonitorBlockEntity.kt
+++ b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/storage/ItemMonitorBlockEntity.kt
@@ -222,7 +222,7 @@ class ItemMonitorBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) :
 			if (!inProcessOfCraft)
 				scanCraftingGrid()
 		}
-	}
+	}.also(::addDroppableContainer)
 
 	private var inProcessOfCraft = false
 
@@ -448,8 +448,8 @@ class ItemMonitorBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) :
 
 	val craftingResultContainer = CraftingResultContainer()
 
-	override fun saveAdditional(nbt: CompoundTag) {
-		super.saveAdditional(nbt)
+	override fun saveLevel(nbt: CompoundTag) {
+		super.saveLevel(nbt)
 
 		nbt.put("player_settings", CompoundTag().also {
 			for ((key, value) in this.settings) {
diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/tech/EnergyCounterBlockEntity.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/tech/EnergyCounterBlockEntity.kt
index 189ac1b99..967565860 100644
--- a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/tech/EnergyCounterBlockEntity.kt
+++ b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/tech/EnergyCounterBlockEntity.kt
@@ -81,18 +81,20 @@ class EnergyCounterBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) : Mat
 		return value
 	}
 
-	override fun saveAdditional(nbt: CompoundTag) {
-		super.saveAdditional(nbt)
+	override fun saveShared(nbt: CompoundTag) {
+		super.saveShared(nbt)
 		nbt[PASSED_ENERGY_KEY] = passed.serializeNBT()
+		ioLimit?.let { nbt[IO_LIMIT_KEY] = it.serializeNBT() }
+	}
 
+	override fun saveLevel(nbt: CompoundTag) {
+		super.saveLevel(nbt)
 		val list = ListTag()
 		nbt[POWER_HISTORY_KEY] = list
 		nbt[POWER_HISTORY_POINTER_KEY] = historyTick
 
 		for (num in history)
 			list.add(num.serializeNBT())
-
-		ioLimit?.let { nbt[IO_LIMIT_KEY] = it.serializeNBT() }
 	}
 
 	override fun load(nbt: CompoundTag) {
diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/core/util/Savetables.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/core/util/Savetables.kt
index acc1b2845..670a2a580 100644
--- a/src/main/kotlin/ru/dbotthepony/mc/otm/core/util/Savetables.kt
+++ b/src/main/kotlin/ru/dbotthepony/mc/otm/core/util/Savetables.kt
@@ -22,7 +22,7 @@ import kotlin.reflect.KMutableProperty0
 import kotlin.reflect.KProperty0
 
 /**
- * Utility class to manage list of composited properties in other classes to be (de)serialized in NBT tags
+ * Utility class to manage serialization and deserialization of properties
  */
 class Savetables : INBTSerializable<CompoundTag?> {
 	private val entries = ArrayList<Entry<*, *>>()
diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/data/Codec2Serializer.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/data/Codec2Serializer.kt
index 6d026f219..10d9550bd 100644
--- a/src/main/kotlin/ru/dbotthepony/mc/otm/data/Codec2Serializer.kt
+++ b/src/main/kotlin/ru/dbotthepony/mc/otm/data/Codec2Serializer.kt
@@ -11,27 +11,27 @@ import ru.dbotthepony.mc.otm.core.set
 import ru.dbotthepony.mc.otm.core.toJsonStrict
 
 class Codec2Serializer<T : Any>(val codec: Codec<T>, val embed: Boolean = true) : Serializer<T> {
-	override fun serialize(p_79325_: JsonObject, p_79326_: T, p_79327_: JsonSerializationContext) {
+	override fun serialize(data: JsonObject, value: T, context: JsonSerializationContext) {
 		if (embed) {
-			val result = codec.toJsonStrict(p_79326_, p_79325_)
+			val result = codec.toJsonStrict(value, data)
 
 			if (result !is JsonObject) {
 				throw RuntimeException("Expected JsonObject from codec, got ${result::class.qualifiedName}")
 			}
 
-			val keys = ArrayList(p_79325_.keySet())
-			for (k in keys) p_79325_.remove(k)
-			for ((k, v) in result.entrySet()) p_79325_[k] = v
+			val keys = ArrayList(data.keySet())
+			for (k in keys) data.remove(k)
+			for ((k, v) in result.entrySet()) data[k] = v
 		} else {
-			p_79325_["value"] = codec.toJsonStrict(p_79326_)
+			data["value"] = codec.toJsonStrict(value)
 		}
 	}
 
-	override fun deserialize(p_79323_: JsonObject, p_79324_: JsonDeserializationContext): T {
+	override fun deserialize(data: JsonObject, context: JsonDeserializationContext): T {
 		if (embed) {
-			return codec.fromJsonStrict(p_79323_)
+			return codec.fromJsonStrict(data)
 		} else {
-			return codec.fromJsonStrict(p_79323_["value"] ?: throw JsonSyntaxException("Missing 'value' element"))
+			return codec.fromJsonStrict(data["value"] ?: throw JsonSyntaxException("Missing 'value' element"))
 		}
 	}
 }