diff --git a/src/data/kotlin/ru/dbotthepony/mc/otm/datagen/DecorativeData.kt b/src/data/kotlin/ru/dbotthepony/mc/otm/datagen/DecorativeData.kt
index a9380202f..fd50bef53 100644
--- a/src/data/kotlin/ru/dbotthepony/mc/otm/datagen/DecorativeData.kt
+++ b/src/data/kotlin/ru/dbotthepony/mc/otm/datagen/DecorativeData.kt
@@ -140,6 +140,14 @@ fun addDecorativeData(blockStateProvider: MatteryBlockStateProvider, itemModelPr
 	blockModelProvider.decorativeGlassAll(MRegistry.INDUSTRIAL_GLASS.allBlocks.values)
 	blockStateProvider.simpleBlockM(MRegistry.INDUSTRIAL_GLASS.allBlocks.values)
 
+	blockModelProvider.colored("computer_terminal", mapOf(
+		"0" to "decorative/computer_base",
+		"1" to "decorative/computer_screen",
+		"particle" to "decorative/computer_base",
+	))
+
+	blockStateProvider.block(MRegistry.COMPUTER_TERMINAL.allBlocks.values)
+
 	blockStateProvider.simpleBlockM(MBlocks.FLUID_TANK)
 
 	for ((block, colors) in MRegistry.TRITANIUM_STRIPED_BLOCK.blocksWithColor) {
diff --git a/src/data/kotlin/ru/dbotthepony/mc/otm/datagen/blocks/MatteryBlockStateProvider.kt b/src/data/kotlin/ru/dbotthepony/mc/otm/datagen/blocks/MatteryBlockStateProvider.kt
index 509171aa9..fa5038372 100644
--- a/src/data/kotlin/ru/dbotthepony/mc/otm/datagen/blocks/MatteryBlockStateProvider.kt
+++ b/src/data/kotlin/ru/dbotthepony/mc/otm/datagen/blocks/MatteryBlockStateProvider.kt
@@ -1,6 +1,7 @@
 package ru.dbotthepony.mc.otm.datagen.blocks
 
 import net.minecraft.core.Direction
+import net.minecraft.resources.ResourceLocation
 import net.minecraft.world.level.block.Block
 import net.minecraft.world.level.block.RotatedPillarBlock
 import net.minecraft.world.level.block.state.BlockState
@@ -56,10 +57,10 @@ class MatteryBlockStateProvider(event: GatherDataEvent) : BlockStateProvider(eve
 		return this
 	}
 
-	fun block(block: Block, func: BlockStateTransform) = exec {
+	fun block(block: Block, model: String = "block/${block.registryName!!.path}", func: BlockStateTransform = EMPTY) = exec {
 		getVariantBuilder(block).forAllStates {
 			val builder = ConfiguredModel.builder()
-			var modelPath = initialTransform(it, "block/${block.registryName!!.path}", builder)
+			var modelPath = initialTransform(it, model, builder)
 			modelPath = func(it, builder, modelPath) ?: modelPath
 
 			builder.modelFile(models().getExistingFile(modLocation(modelPath)))
@@ -70,7 +71,7 @@ class MatteryBlockStateProvider(event: GatherDataEvent) : BlockStateProvider(eve
 
 	fun block(blocks: Collection<Block>): MatteryBlockStateProvider {
 		for (block in blocks) {
-			this.block(block, EMPTY)
+			this.block(block)
 		}
 
 		return this
@@ -78,7 +79,7 @@ class MatteryBlockStateProvider(event: GatherDataEvent) : BlockStateProvider(eve
 
 	fun block(vararg blocks: Block): MatteryBlockStateProvider {
 		for (block in blocks) {
-			this.block(block, EMPTY)
+			block(block)
 		}
 
 		return this
@@ -86,11 +87,16 @@ class MatteryBlockStateProvider(event: GatherDataEvent) : BlockStateProvider(eve
 
 	fun simpleBlockM(vararg blocks: Block): MatteryBlockStateProvider {
 		for (block in blocks) {
-			exec {
-				getVariantBuilder(block).forAllStates {
-					check(block.registryName != null) {"$block registry name is null!"}
-					return@forAllStates arrayOf(ConfiguredModel(models().getExistingFile(block.registryName)))
-				}
+			simpleBlockM(block)
+		}
+
+		return this
+	}
+
+	fun simpleBlockM(block: Block, model: ResourceLocation = checkNotNull(block.registryName) {"$block registry name is null!"}): MatteryBlockStateProvider {
+		exec {
+			getVariantBuilder(block).forAllStates {
+				return@forAllStates arrayOf(ConfiguredModel(models().getExistingFile(model)))
 			}
 		}
 
diff --git a/src/data/kotlin/ru/dbotthepony/mc/otm/datagen/items/ItemModels.kt b/src/data/kotlin/ru/dbotthepony/mc/otm/datagen/items/ItemModels.kt
index d16873818..21e5437f7 100644
--- a/src/data/kotlin/ru/dbotthepony/mc/otm/datagen/items/ItemModels.kt
+++ b/src/data/kotlin/ru/dbotthepony/mc/otm/datagen/items/ItemModels.kt
@@ -35,6 +35,7 @@ fun addItemModels(provider: MatteryItemModelProvider) {
 	MRegistry.VENT.allItems.values.forEach(provider::block)
 	MRegistry.VENT_ALTERNATIVE.allItems.values.forEach(provider::block)
 	MRegistry.TRITANIUM_BLOCK.allItems.values.forEach(provider::block)
+	MRegistry.COMPUTER_TERMINAL.allItems.values.forEach(provider::block)
 	MRegistry.INDUSTRIAL_GLASS.allItems.values.forEach(provider::block)
 
 	for (block in MRegistry.TRITANIUM_STRIPED_BLOCK.flatItems) {
diff --git a/src/data/kotlin/ru/dbotthepony/mc/otm/datagen/lang/English.kt b/src/data/kotlin/ru/dbotthepony/mc/otm/datagen/lang/English.kt
index e03ae6762..1c6ed54ab 100644
--- a/src/data/kotlin/ru/dbotthepony/mc/otm/datagen/lang/English.kt
+++ b/src/data/kotlin/ru/dbotthepony/mc/otm/datagen/lang/English.kt
@@ -7,6 +7,7 @@ private fun decoratives(provider: MatteryLanguageProvider) {
 		add(MRegistry.VENT, "%s Vent")
 		add(MRegistry.VENT_ALTERNATIVE, "%s Alternative Vent")
 
+		add(MRegistry.COMPUTER_TERMINAL, "%s Computer Terminal")
 		add(MRegistry.TRITANIUM_BLOCK, "%s Tritanium Block")
 		add(MRegistry.TRITANIUM_STAIRS, "%s Tritanium Stairs")
 		add(MRegistry.TRITANIUM_SLAB, "%s Tritanium Slab")
@@ -53,6 +54,7 @@ private fun decoratives(provider: MatteryLanguageProvider) {
 		add(MEntityTypes.CARGO_CRATE_MINECARTS[null]!!, "Minecart with Cargo Crate")
 
 		add(MRegistry.CARGO_CRATES.block, "Cargo Crate")
+		add(MRegistry.COMPUTER_TERMINAL.block, "Computer Terminal")
 		add(MRegistry.TRITANIUM_BLOCK.block, "Tritanium Block")
 		add(MRegistry.TRITANIUM_STAIRS.block, "Tritanium Stairs")
 		add(MRegistry.TRITANIUM_SLAB.block, "Tritanium Slab")
diff --git a/src/data/kotlin/ru/dbotthepony/mc/otm/datagen/lang/Russian.kt b/src/data/kotlin/ru/dbotthepony/mc/otm/datagen/lang/Russian.kt
index 82856ae07..db989cc4b 100644
--- a/src/data/kotlin/ru/dbotthepony/mc/otm/datagen/lang/Russian.kt
+++ b/src/data/kotlin/ru/dbotthepony/mc/otm/datagen/lang/Russian.kt
@@ -13,12 +13,13 @@ private const val FEELING_SAFE_NOW = "...ощущаете ли вы себя т
 
 private fun decoratives(provider: MatteryLanguageProvider) {
 	with(provider.russianColors) {
-		add(MRegistry.VENT, "%s Вентиляция")
-		add(MRegistry.VENT_ALTERNATIVE, "%s Альтернативная Вентиляция")
+		add(MRegistry.VENT, "%s вентиляция")
+		add(MRegistry.VENT_ALTERNATIVE, "%s альтернативная вентиляция")
 
 		add(MRegistry.TRITANIUM_BLOCK, "%s тритановый блок")
-		add(MRegistry.TRITANIUM_STAIRS, "%s Тритановые ступеньки")
-		add(MRegistry.TRITANIUM_SLAB, "%s Тритановая плита")
+		add(MRegistry.COMPUTER_TERMINAL, "%s компьютерный терминал")
+		add(MRegistry.TRITANIUM_STAIRS, "%s тритановые ступеньки")
+		add(MRegistry.TRITANIUM_SLAB, "%s тритановая плита")
 		add(MRegistry.TRITANIUM_WALL, "%s тритановая ограда")
 		add(MRegistry.FLOOR_TILES, "%s керамическая плитка")
 		add(MRegistry.FLOOR_TILES_STAIRS, "%s ступеньки из керамической плитки")
@@ -62,6 +63,7 @@ private fun decoratives(provider: MatteryLanguageProvider) {
 		add(MEntityTypes.CARGO_CRATE_MINECARTS[null]!!, "Вагонетка с грузовым ящиком")
 
 		add(MRegistry.CARGO_CRATES.block, "Грузовой ящик")
+		add(MRegistry.COMPUTER_TERMINAL.block, "Компьютерный терминал")
 		add(MRegistry.TRITANIUM_BLOCK.block, "Тритановый блок")
 		add(MRegistry.TRITANIUM_STAIRS.block, "Тритановые ступеньки")
 		add(MRegistry.TRITANIUM_SLAB.block, "Тритановая плита")
diff --git a/src/data/kotlin/ru/dbotthepony/mc/otm/datagen/loot/LootTablesData.kt b/src/data/kotlin/ru/dbotthepony/mc/otm/datagen/loot/LootTablesData.kt
index ca8d3a69f..eb14cda0b 100644
--- a/src/data/kotlin/ru/dbotthepony/mc/otm/datagen/loot/LootTablesData.kt
+++ b/src/data/kotlin/ru/dbotthepony/mc/otm/datagen/loot/LootTablesData.kt
@@ -14,6 +14,7 @@ import ru.dbotthepony.mc.otm.registry.MRegistry
 fun addLootTables(lootTables: LootTables) {
 	lootTables.dropsSelf(MRegistry.DECORATIVE_CRATE.allBlocks.values) { condition(ExplosionCondition.survivesExplosion()) }
 
+	lootTables.dropsSelf(MRegistry.COMPUTER_TERMINAL.allBlocks.values) { condition(ExplosionCondition.survivesExplosion()) }
 	lootTables.dropsSelf(MRegistry.CARGO_CRATES.allBlocks.values) { condition(ExplosionCondition.survivesExplosion()) }
 	lootTables.dropsSelf(MRegistry.INDUSTRIAL_GLASS.allBlocks.values) { condition(ExplosionCondition.survivesExplosion()) }
 	lootTables.dropsSelf(MRegistry.INDUSTRIAL_GLASS_PANE.allBlocks.values) { condition(ExplosionCondition.survivesExplosion()) }
diff --git a/src/data/kotlin/ru/dbotthepony/mc/otm/datagen/models/MatteryModelProvider.kt b/src/data/kotlin/ru/dbotthepony/mc/otm/datagen/models/MatteryModelProvider.kt
index cebb67f1e..113e69a4f 100644
--- a/src/data/kotlin/ru/dbotthepony/mc/otm/datagen/models/MatteryModelProvider.kt
+++ b/src/data/kotlin/ru/dbotthepony/mc/otm/datagen/models/MatteryModelProvider.kt
@@ -114,6 +114,18 @@ class MatteryBlockModelProvider(event: GatherDataEvent) : BlockModelProvider(eve
 		}
 	}
 
+	fun colored(modelName: String, textureKeys: Map<String, String>) {
+		for (color in DyeColor.entries) {
+			exec {
+				val model = withExistingParent(modelName + "_${color.name.lowercase()}", modLocation(modelName))
+
+				for ((key, value) in textureKeys) {
+					model.texture(key, modLocation("block/$value/${color.name.lowercase()}"))
+				}
+			}
+		}
+	}
+
 	fun coloredMachineCombined(modelName: String, textureName: String, states: Collection<String>, textureKeys: Collection<String>) {
 		exec {
 			for (color in DyeColor.entries) {
diff --git a/src/data/kotlin/ru/dbotthepony/mc/otm/datagen/recipes/DecorativesRecipes.kt b/src/data/kotlin/ru/dbotthepony/mc/otm/datagen/recipes/DecorativesRecipes.kt
index ef69bdd76..522c48dbc 100644
--- a/src/data/kotlin/ru/dbotthepony/mc/otm/datagen/recipes/DecorativesRecipes.kt
+++ b/src/data/kotlin/ru/dbotthepony/mc/otm/datagen/recipes/DecorativesRecipes.kt
@@ -233,7 +233,7 @@ fun addDecorativesRecipes(provider: MatteryRecipeProvider, consumer: RecipeOutpu
 		DyeColor.BLACK to Items.BLACK_STAINED_GLASS,
 	)
 
-	for (color in DyeColor.values()) {
+	for (color in DyeColor.entries) {
 		val item = MRegistry.INDUSTRIAL_GLASS.items[color]!!
 		val paneItem = MRegistry.INDUSTRIAL_GLASS_PANE.items[color]!!
 		val mappedVanilla = mappingUpgradeVanilla[color]!!
diff --git a/src/data/kotlin/ru/dbotthepony/mc/otm/datagen/recipes/PainterRecipes.kt b/src/data/kotlin/ru/dbotthepony/mc/otm/datagen/recipes/PainterRecipes.kt
index 6bb0f685c..23694cb1d 100644
--- a/src/data/kotlin/ru/dbotthepony/mc/otm/datagen/recipes/PainterRecipes.kt
+++ b/src/data/kotlin/ru/dbotthepony/mc/otm/datagen/recipes/PainterRecipes.kt
@@ -275,6 +275,7 @@ fun addPainterRecipes(consumer: RecipeOutput) {
 	generate(consumer, MItems.ESSENCE_STORAGE[null]!!, MItems.ESSENCE_STORAGE)
 	generate(consumer, MItems.PLATE_PRESS[null]!!, MItems.PLATE_PRESS)
 	generate(consumer, MItems.TWIN_PLATE_PRESS[null]!!, MItems.TWIN_PLATE_PRESS)
+	generate(consumer, MRegistry.COMPUTER_TERMINAL.item, MRegistry.COMPUTER_TERMINAL.items)
 
 	generate(consumer, MRegistry.VENT.item, MRegistry.VENT.items)
 	generate(consumer, MRegistry.VENT_ALTERNATIVE.item, MRegistry.VENT_ALTERNATIVE.items)
diff --git a/src/data/kotlin/ru/dbotthepony/mc/otm/datagen/tags/Tags.kt b/src/data/kotlin/ru/dbotthepony/mc/otm/datagen/tags/Tags.kt
index f23b251af..0e2712d35 100644
--- a/src/data/kotlin/ru/dbotthepony/mc/otm/datagen/tags/Tags.kt
+++ b/src/data/kotlin/ru/dbotthepony/mc/otm/datagen/tags/Tags.kt
@@ -244,6 +244,7 @@ fun addTags(tagsProvider: TagsProvider) {
 	tagsProvider.requiresPickaxe(MRegistry.VENT.allBlocks.values, Tiers.IRON)
 	tagsProvider.requiresPickaxe(MRegistry.VENT_ALTERNATIVE.allBlocks.values, Tiers.IRON)
 	tagsProvider.requiresPickaxe(MRegistry.TRITANIUM_BLOCK.allBlocks.values, Tiers.IRON)
+	tagsProvider.requiresPickaxe(MRegistry.COMPUTER_TERMINAL.allBlocks.values, Tiers.STONE)
 	tagsProvider.requiresPickaxe(MRegistry.TRITANIUM_SLAB.allBlocks.values, Tiers.IRON)
 	tagsProvider.requiresPickaxe(MRegistry.TRITANIUM_WALL.allBlocks.values, Tiers.IRON)
 	tagsProvider.requiresPickaxe(MRegistry.TRITANIUM_PRESSURE_PLATE.allBlocks.values, Tiers.IRON)
diff --git a/src/main/java/ru/dbotthepony/mc/otm/shapes/BlockShapes.java b/src/main/java/ru/dbotthepony/mc/otm/shapes/BlockShapes.java
index 6a1851dab..a0bf71844 100644
--- a/src/main/java/ru/dbotthepony/mc/otm/shapes/BlockShapes.java
+++ b/src/main/java/ru/dbotthepony/mc/otm/shapes/BlockShapes.java
@@ -797,4 +797,11 @@ public class BlockShapes {
 		new SimpleCuboid(0.3125d, 0.3125d, 0.0625d, 0.9375d, 0.875d, 0.0625d),
 		new SimpleCuboid(0.3125d, 0.6875d, 0.5d, 0.375d, 0.875d, 0.8125d)
 	);
+
+	public static final BlockShape COMPUTER_TERMINAL = new BlockShape(
+		new SimpleCuboid(0.0625d, 0d, 0.0625d, 0.9375d, 0.125d, 0.9375d),
+		new SimpleCuboid(0.0625d, 0.125d, 0.3125d, 0.9375d, 0.3125d, 0.9375d),
+		new SimpleCuboid(0.125d, 0.3125d, 0.25d, 0.875d, 0.9375d, 0.875d),
+		new SimpleCuboid(0.1875d, 0.5d, 0.875d, 0.8125d, 0.875d, 0.9375d)
+	);
 }
diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/block/RotatableMatteryBlock.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/block/RotatableMatteryBlock.kt
index 9843a2acb..b2ecb1775 100644
--- a/src/main/kotlin/ru/dbotthepony/mc/otm/block/RotatableMatteryBlock.kt
+++ b/src/main/kotlin/ru/dbotthepony/mc/otm/block/RotatableMatteryBlock.kt
@@ -10,7 +10,7 @@ import ru.dbotthepony.mc.otm.core.get
 import ru.dbotthepony.mc.otm.core.math.BlockRotation
 import ru.dbotthepony.mc.otm.core.math.BlockRotationFreedom
 
-abstract class RotatableMatteryBlock(properties: Properties = DEFAULT_PROPERTIES) : MatteryBlock(properties) {
+open class RotatableMatteryBlock(properties: Properties = DEFAULT_PROPERTIES) : MatteryBlock(properties) {
 	init {
 		@Suppress("LeakingThis")
 		registerDefaultState(getStateDefinition().any().setValue(rotationProperty, BlockRotation.SOUTH))
diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/registry/MBlocks.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/registry/MBlocks.kt
index 0bd6a4775..74e4ef5e8 100644
--- a/src/main/kotlin/ru/dbotthepony/mc/otm/registry/MBlocks.kt
+++ b/src/main/kotlin/ru/dbotthepony/mc/otm/registry/MBlocks.kt
@@ -361,5 +361,6 @@ object MBlocks {
 		MRegistry.TRITANIUM_STRIPED_STAIRS.registerBlocks(registry)
 		MRegistry.TRITANIUM_STRIPED_SLAB.registerBlocks(registry)
 		MRegistry.TRITANIUM_STRIPED_WALL.registerBlocks(registry)
+		MRegistry.COMPUTER_TERMINAL.registerBlocks(registry)
 	}
 }
diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/registry/MCreativeTabs.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/registry/MCreativeTabs.kt
index 258ca4ed1..71673402b 100644
--- a/src/main/kotlin/ru/dbotthepony/mc/otm/registry/MCreativeTabs.kt
+++ b/src/main/kotlin/ru/dbotthepony/mc/otm/registry/MCreativeTabs.kt
@@ -243,6 +243,8 @@ private fun addDecorativeTabItems(consumer: CreativeModeTab.Output) {
 
 		colored(MItems.CARGO_CRATE_MINECARTS)
 
+		all(MRegistry.COMPUTER_TERMINAL.allItems)
+
 		all(MRegistry.DECORATIVE_CRATE.allItems)
 
 		for (color in colorOrder) {
diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/registry/MItems.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/registry/MItems.kt
index 0cfc227f3..857d79ad5 100644
--- a/src/main/kotlin/ru/dbotthepony/mc/otm/registry/MItems.kt
+++ b/src/main/kotlin/ru/dbotthepony/mc/otm/registry/MItems.kt
@@ -685,5 +685,6 @@ object MItems {
 		MRegistry.TRITANIUM_STRIPED_STAIRS.registerItems(registry)
 		MRegistry.TRITANIUM_STRIPED_SLAB.registerItems(registry)
 		MRegistry.TRITANIUM_STRIPED_WALL.registerItems(registry)
+		MRegistry.COMPUTER_TERMINAL.registerItems(registry)
 	}
 }
diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/registry/MRegistry.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/registry/MRegistry.kt
index bdb7615ad..cd582a85f 100644
--- a/src/main/kotlin/ru/dbotthepony/mc/otm/registry/MRegistry.kt
+++ b/src/main/kotlin/ru/dbotthepony/mc/otm/registry/MRegistry.kt
@@ -44,6 +44,7 @@ import ru.dbotthepony.mc.otm.block.decorative.TritaniumPressurePlate
 import ru.dbotthepony.mc.otm.capability.matteryEnergy
 import ru.dbotthepony.mc.otm.client.MatteryGUI
 import ru.dbotthepony.mc.otm.compat.vanilla.MatteryChestMenu
+import ru.dbotthepony.mc.otm.core.math.BlockRotationFreedom
 import ru.dbotthepony.mc.otm.core.math.Decimal
 import ru.dbotthepony.mc.otm.core.math.RGBAColor
 import ru.dbotthepony.mc.otm.data.DecimalProvider
@@ -53,6 +54,7 @@ import ru.dbotthepony.mc.otm.matter.IMatterFunction
 import ru.dbotthepony.mc.otm.registry.objects.ColoredDecorativeBlock
 import ru.dbotthepony.mc.otm.registry.objects.DecorativeBlock
 import ru.dbotthepony.mc.otm.registry.objects.StripedColoredDecorativeBlock
+import ru.dbotthepony.mc.otm.shapes.BlockShapes
 import ru.dbotthepony.mc.otm.storage.StorageStack
 import ru.dbotthepony.mc.otm.triggers.AndroidBatteryTrigger
 import ru.dbotthepony.mc.otm.triggers.KillAsAndroidTrigger
@@ -126,6 +128,14 @@ object MRegistry {
 			.destroyTime(2.5f)
 	}
 
+	val COMPUTER_TERMINAL = DecorativeBlock.rotatable("computer_terminal", BlockShapes.COMPUTER_TERMINAL, BlockRotationFreedom.HORIZONTAL) {
+		BlockBehaviour.Properties.of()
+			.mapColor(it?.mapColor ?: MapColor.COLOR_LIGHT_BLUE)
+			.sound(SoundType.METAL)
+			.explosionResistance(15f)
+			.destroyTime(1.5f)
+	}
+
 	val TRITANIUM_STAIRS = DecorativeBlock(MNames.TRITANIUM_STAIRS) {
 		StairBlock(
 			{ TRITANIUM_BLOCK.allBlocks[it]!!.defaultBlockState() },
diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/registry/objects/DecorativeBlock.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/registry/objects/DecorativeBlock.kt
index f5ca9181c..03a4dae6d 100644
--- a/src/main/kotlin/ru/dbotthepony/mc/otm/registry/objects/DecorativeBlock.kt
+++ b/src/main/kotlin/ru/dbotthepony/mc/otm/registry/objects/DecorativeBlock.kt
@@ -1,16 +1,27 @@
 package ru.dbotthepony.mc.otm.registry.objects
 
 import com.google.common.collect.Streams
+import net.minecraft.core.BlockPos
 import net.minecraft.world.item.BlockItem
 import net.minecraft.world.item.DyeColor
 import net.minecraft.world.item.Item
+import net.minecraft.world.level.BlockGetter
 import net.minecraft.world.level.block.Block
 import net.minecraft.world.level.block.state.BlockBehaviour
+import net.minecraft.world.level.block.state.BlockState
+import net.minecraft.world.phys.shapes.CollisionContext
+import net.minecraft.world.phys.shapes.VoxelShape
 import net.minecraftforge.registries.DeferredRegister
 import net.minecraftforge.registries.RegistryObject
+import ru.dbotthepony.mc.otm.block.RotatableMatteryBlock
+import ru.dbotthepony.mc.otm.block.getShapeForEachState
 import ru.dbotthepony.mc.otm.core.collect.SupplierMap
+import ru.dbotthepony.mc.otm.core.get
+import ru.dbotthepony.mc.otm.core.math.BlockRotationFreedom
 import ru.dbotthepony.mc.otm.core.util.WriteOnce
 import ru.dbotthepony.mc.otm.registry.MRegistry
+import ru.dbotthepony.mc.otm.shapes.BlockShape
+import ru.dbotthepony.mc.otm.shapes.BlockShapes
 import java.util.stream.Stream
 
 /**
@@ -52,5 +63,33 @@ class DecorativeBlock(
 				Block(provider.invoke(it))
 			}
 		}
+
+		fun rotatable(baseName: String, provider: (DyeColor?) -> BlockBehaviour.Properties): DecorativeBlock {
+			return DecorativeBlock(baseName) {
+				RotatableMatteryBlock(provider.invoke(it))
+			}
+		}
+
+		fun rotatable(baseName: String, shape: BlockShape, rotationFreedom: BlockRotationFreedom, provider: (DyeColor?) -> BlockBehaviour.Properties): DecorativeBlock {
+			return DecorativeBlock(baseName) {
+				object : RotatableMatteryBlock(provider.invoke(it)) {
+					override fun rotationFreedom(): BlockRotationFreedom {
+						return rotationFreedom
+					}
+
+					private val shapes = getShapeForEachState(rotationProperty) { shape.rotateFromNorth(it[rotationProperty]).computeShape() }
+
+					@Suppress("override_deprecation")
+					override fun getShape(
+						state: BlockState,
+						blockGetter: BlockGetter,
+						pos: BlockPos,
+						context: CollisionContext
+					): VoxelShape {
+						return shapes[state]!!
+					}
+				}
+			}
+		}
 	}
 }
diff --git a/src/main/resources/assets/overdrive_that_matters/models/block/decorative/computer_terminal.json b/src/main/resources/assets/overdrive_that_matters/models/block/computer_terminal.json
similarity index 100%
rename from src/main/resources/assets/overdrive_that_matters/models/block/decorative/computer_terminal.json
rename to src/main/resources/assets/overdrive_that_matters/models/block/computer_terminal.json
diff --git a/src/main/resources/assets/overdrive_that_matters/textures/block/decorative/computer_base/black.png b/src/main/resources/assets/overdrive_that_matters/textures/block/decorative/computer_base/black.png
new file mode 100644
index 000000000..83954e68d
Binary files /dev/null and b/src/main/resources/assets/overdrive_that_matters/textures/block/decorative/computer_base/black.png differ
diff --git a/src/main/resources/assets/overdrive_that_matters/textures/block/decorative/computer_base/blue.png b/src/main/resources/assets/overdrive_that_matters/textures/block/decorative/computer_base/blue.png
new file mode 100644
index 000000000..c409b3338
Binary files /dev/null and b/src/main/resources/assets/overdrive_that_matters/textures/block/decorative/computer_base/blue.png differ
diff --git a/src/main/resources/assets/overdrive_that_matters/textures/block/decorative/computer_base/brown.png b/src/main/resources/assets/overdrive_that_matters/textures/block/decorative/computer_base/brown.png
new file mode 100644
index 000000000..e3b482392
Binary files /dev/null and b/src/main/resources/assets/overdrive_that_matters/textures/block/decorative/computer_base/brown.png differ
diff --git a/src/main/resources/assets/overdrive_that_matters/textures/block/decorative/computer_base/cyan.png b/src/main/resources/assets/overdrive_that_matters/textures/block/decorative/computer_base/cyan.png
new file mode 100644
index 000000000..6160ae402
Binary files /dev/null and b/src/main/resources/assets/overdrive_that_matters/textures/block/decorative/computer_base/cyan.png differ
diff --git a/src/main/resources/assets/overdrive_that_matters/textures/block/decorative/computer_base/gray.png b/src/main/resources/assets/overdrive_that_matters/textures/block/decorative/computer_base/gray.png
new file mode 100644
index 000000000..da9cafd18
Binary files /dev/null and b/src/main/resources/assets/overdrive_that_matters/textures/block/decorative/computer_base/gray.png differ
diff --git a/src/main/resources/assets/overdrive_that_matters/textures/block/decorative/computer_base/green.png b/src/main/resources/assets/overdrive_that_matters/textures/block/decorative/computer_base/green.png
new file mode 100644
index 000000000..a3e9bf139
Binary files /dev/null and b/src/main/resources/assets/overdrive_that_matters/textures/block/decorative/computer_base/green.png differ
diff --git a/src/main/resources/assets/overdrive_that_matters/textures/block/decorative/computer_base/light_blue.png b/src/main/resources/assets/overdrive_that_matters/textures/block/decorative/computer_base/light_blue.png
new file mode 100644
index 000000000..dcc904484
Binary files /dev/null and b/src/main/resources/assets/overdrive_that_matters/textures/block/decorative/computer_base/light_blue.png differ
diff --git a/src/main/resources/assets/overdrive_that_matters/textures/block/decorative/computer_base/light_gray.png b/src/main/resources/assets/overdrive_that_matters/textures/block/decorative/computer_base/light_gray.png
new file mode 100644
index 000000000..7827e72a2
Binary files /dev/null and b/src/main/resources/assets/overdrive_that_matters/textures/block/decorative/computer_base/light_gray.png differ
diff --git a/src/main/resources/assets/overdrive_that_matters/textures/block/decorative/computer_base/lime.png b/src/main/resources/assets/overdrive_that_matters/textures/block/decorative/computer_base/lime.png
new file mode 100644
index 000000000..327a63772
Binary files /dev/null and b/src/main/resources/assets/overdrive_that_matters/textures/block/decorative/computer_base/lime.png differ
diff --git a/src/main/resources/assets/overdrive_that_matters/textures/block/decorative/computer_base/magenta.png b/src/main/resources/assets/overdrive_that_matters/textures/block/decorative/computer_base/magenta.png
new file mode 100644
index 000000000..5d4bbc272
Binary files /dev/null and b/src/main/resources/assets/overdrive_that_matters/textures/block/decorative/computer_base/magenta.png differ
diff --git a/src/main/resources/assets/overdrive_that_matters/textures/block/decorative/computer_base/orange.png b/src/main/resources/assets/overdrive_that_matters/textures/block/decorative/computer_base/orange.png
new file mode 100644
index 000000000..628146c3c
Binary files /dev/null and b/src/main/resources/assets/overdrive_that_matters/textures/block/decorative/computer_base/orange.png differ
diff --git a/src/main/resources/assets/overdrive_that_matters/textures/block/decorative/computer_base/pink.png b/src/main/resources/assets/overdrive_that_matters/textures/block/decorative/computer_base/pink.png
new file mode 100644
index 000000000..b5d746097
Binary files /dev/null and b/src/main/resources/assets/overdrive_that_matters/textures/block/decorative/computer_base/pink.png differ
diff --git a/src/main/resources/assets/overdrive_that_matters/textures/block/decorative/computer_base/purple.png b/src/main/resources/assets/overdrive_that_matters/textures/block/decorative/computer_base/purple.png
new file mode 100644
index 000000000..03428ad6a
Binary files /dev/null and b/src/main/resources/assets/overdrive_that_matters/textures/block/decorative/computer_base/purple.png differ
diff --git a/src/main/resources/assets/overdrive_that_matters/textures/block/decorative/computer_base/red.png b/src/main/resources/assets/overdrive_that_matters/textures/block/decorative/computer_base/red.png
new file mode 100644
index 000000000..8f04ce6ed
Binary files /dev/null and b/src/main/resources/assets/overdrive_that_matters/textures/block/decorative/computer_base/red.png differ
diff --git a/src/main/resources/assets/overdrive_that_matters/textures/block/decorative/computer_base/white.png b/src/main/resources/assets/overdrive_that_matters/textures/block/decorative/computer_base/white.png
new file mode 100644
index 000000000..2f262c4b0
Binary files /dev/null and b/src/main/resources/assets/overdrive_that_matters/textures/block/decorative/computer_base/white.png differ
diff --git a/src/main/resources/assets/overdrive_that_matters/textures/block/decorative/computer_base/yellow.png b/src/main/resources/assets/overdrive_that_matters/textures/block/decorative/computer_base/yellow.png
new file mode 100644
index 000000000..86ba22a64
Binary files /dev/null and b/src/main/resources/assets/overdrive_that_matters/textures/block/decorative/computer_base/yellow.png differ
diff --git a/src/main/resources/assets/overdrive_that_matters/textures/block/decorative/computer_base_mask.png b/src/main/resources/assets/overdrive_that_matters/textures/block/decorative/computer_base_mask.png
new file mode 100644
index 000000000..5b5b5c9fd
Binary files /dev/null and b/src/main/resources/assets/overdrive_that_matters/textures/block/decorative/computer_base_mask.png differ
diff --git a/src/main/resources/assets/overdrive_that_matters/textures/block/decorative/computer_screen/black.png b/src/main/resources/assets/overdrive_that_matters/textures/block/decorative/computer_screen/black.png
new file mode 100644
index 000000000..c5412450c
Binary files /dev/null and b/src/main/resources/assets/overdrive_that_matters/textures/block/decorative/computer_screen/black.png differ
diff --git a/src/main/resources/assets/overdrive_that_matters/textures/block/decorative/computer_screen/blue.png b/src/main/resources/assets/overdrive_that_matters/textures/block/decorative/computer_screen/blue.png
new file mode 100644
index 000000000..5982686e9
Binary files /dev/null and b/src/main/resources/assets/overdrive_that_matters/textures/block/decorative/computer_screen/blue.png differ
diff --git a/src/main/resources/assets/overdrive_that_matters/textures/block/decorative/computer_screen/brown.png b/src/main/resources/assets/overdrive_that_matters/textures/block/decorative/computer_screen/brown.png
new file mode 100644
index 000000000..1ca3a44fa
Binary files /dev/null and b/src/main/resources/assets/overdrive_that_matters/textures/block/decorative/computer_screen/brown.png differ
diff --git a/src/main/resources/assets/overdrive_that_matters/textures/block/decorative/computer_screen/cyan.png b/src/main/resources/assets/overdrive_that_matters/textures/block/decorative/computer_screen/cyan.png
new file mode 100644
index 000000000..009b412a1
Binary files /dev/null and b/src/main/resources/assets/overdrive_that_matters/textures/block/decorative/computer_screen/cyan.png differ
diff --git a/src/main/resources/assets/overdrive_that_matters/textures/block/decorative/computer_screen/gray.png b/src/main/resources/assets/overdrive_that_matters/textures/block/decorative/computer_screen/gray.png
new file mode 100644
index 000000000..c7819f625
Binary files /dev/null and b/src/main/resources/assets/overdrive_that_matters/textures/block/decorative/computer_screen/gray.png differ
diff --git a/src/main/resources/assets/overdrive_that_matters/textures/block/decorative/computer_screen/green.png b/src/main/resources/assets/overdrive_that_matters/textures/block/decorative/computer_screen/green.png
new file mode 100644
index 000000000..9c5aa0878
Binary files /dev/null and b/src/main/resources/assets/overdrive_that_matters/textures/block/decorative/computer_screen/green.png differ
diff --git a/src/main/resources/assets/overdrive_that_matters/textures/block/decorative/computer_screen/light_blue.png b/src/main/resources/assets/overdrive_that_matters/textures/block/decorative/computer_screen/light_blue.png
new file mode 100644
index 000000000..2fa096ec1
Binary files /dev/null and b/src/main/resources/assets/overdrive_that_matters/textures/block/decorative/computer_screen/light_blue.png differ
diff --git a/src/main/resources/assets/overdrive_that_matters/textures/block/decorative/computer_screen/light_gray.png b/src/main/resources/assets/overdrive_that_matters/textures/block/decorative/computer_screen/light_gray.png
new file mode 100644
index 000000000..4e0d35bcc
Binary files /dev/null and b/src/main/resources/assets/overdrive_that_matters/textures/block/decorative/computer_screen/light_gray.png differ
diff --git a/src/main/resources/assets/overdrive_that_matters/textures/block/decorative/computer_screen/lime.png b/src/main/resources/assets/overdrive_that_matters/textures/block/decorative/computer_screen/lime.png
new file mode 100644
index 000000000..a9148179c
Binary files /dev/null and b/src/main/resources/assets/overdrive_that_matters/textures/block/decorative/computer_screen/lime.png differ
diff --git a/src/main/resources/assets/overdrive_that_matters/textures/block/decorative/computer_screen/magenta.png b/src/main/resources/assets/overdrive_that_matters/textures/block/decorative/computer_screen/magenta.png
new file mode 100644
index 000000000..41e60ce05
Binary files /dev/null and b/src/main/resources/assets/overdrive_that_matters/textures/block/decorative/computer_screen/magenta.png differ
diff --git a/src/main/resources/assets/overdrive_that_matters/textures/block/decorative/computer_screen/orange.png b/src/main/resources/assets/overdrive_that_matters/textures/block/decorative/computer_screen/orange.png
new file mode 100644
index 000000000..c18fed45a
Binary files /dev/null and b/src/main/resources/assets/overdrive_that_matters/textures/block/decorative/computer_screen/orange.png differ
diff --git a/src/main/resources/assets/overdrive_that_matters/textures/block/decorative/computer_screen/pink.png b/src/main/resources/assets/overdrive_that_matters/textures/block/decorative/computer_screen/pink.png
new file mode 100644
index 000000000..538d8935c
Binary files /dev/null and b/src/main/resources/assets/overdrive_that_matters/textures/block/decorative/computer_screen/pink.png differ
diff --git a/src/main/resources/assets/overdrive_that_matters/textures/block/decorative/computer_screen/purple.png b/src/main/resources/assets/overdrive_that_matters/textures/block/decorative/computer_screen/purple.png
new file mode 100644
index 000000000..633223a8c
Binary files /dev/null and b/src/main/resources/assets/overdrive_that_matters/textures/block/decorative/computer_screen/purple.png differ
diff --git a/src/main/resources/assets/overdrive_that_matters/textures/block/decorative/computer_screen/red.png b/src/main/resources/assets/overdrive_that_matters/textures/block/decorative/computer_screen/red.png
new file mode 100644
index 000000000..d47c0b77e
Binary files /dev/null and b/src/main/resources/assets/overdrive_that_matters/textures/block/decorative/computer_screen/red.png differ
diff --git a/src/main/resources/assets/overdrive_that_matters/textures/block/decorative/computer_screen/white.png b/src/main/resources/assets/overdrive_that_matters/textures/block/decorative/computer_screen/white.png
new file mode 100644
index 000000000..d8db3b421
Binary files /dev/null and b/src/main/resources/assets/overdrive_that_matters/textures/block/decorative/computer_screen/white.png differ
diff --git a/src/main/resources/assets/overdrive_that_matters/textures/block/decorative/computer_screen/yellow.png b/src/main/resources/assets/overdrive_that_matters/textures/block/decorative/computer_screen/yellow.png
new file mode 100644
index 000000000..4cf7e4819
Binary files /dev/null and b/src/main/resources/assets/overdrive_that_matters/textures/block/decorative/computer_screen/yellow.png differ
diff --git a/src/main/resources/assets/overdrive_that_matters/textures/block/decorative/computer_screen_mask.png b/src/main/resources/assets/overdrive_that_matters/textures/block/decorative/computer_screen_mask.png
new file mode 100644
index 000000000..067bd8810
Binary files /dev/null and b/src/main/resources/assets/overdrive_that_matters/textures/block/decorative/computer_screen_mask.png differ