diff --git a/build.gradle b/build.gradle
index 07408da842..4faebe05fc 100644
--- a/build.gradle
+++ b/build.gradle
@@ -22,7 +22,7 @@ boolean dev = System.getenv('RELEASE') == null || System.getenv('RELEASE').equal
 ext.buildnumber = 0
 project.buildnumber = System.getenv('BUILD_NUMBER') != null ? System.getenv('BUILD_NUMBER') : "custom"
 
-version = "mc${minecraft_version}_v${mod_version}" + (dev ? "+${buildnumber}" : '')
+version = "mc${minecraft_version}_v${mod_version}"
 group = 'com.simibubi.create'
 archivesBaseName = 'create'
 
diff --git a/gradle.properties b/gradle.properties
index 97aaf8aa00..d70b89e898 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -4,7 +4,7 @@ org.gradle.jvmargs=-Xmx3G
 org.gradle.daemon=false
 
 # mod version info
-mod_version=0.3e
+mod_version=0.3.1
 minecraft_version=1.15.2
 forge_version=31.2.47
 
diff --git a/src/generated/resources/.cache/cache b/src/generated/resources/.cache/cache
index b84f93444a..ba6321208c 100644
--- a/src/generated/resources/.cache/cache
+++ b/src/generated/resources/.cache/cache
@@ -16,7 +16,7 @@ a579c40c43dc2174afb66f42d00d0c4a0efaaeee assets/create/blockstates/andesite_bric
 96b5284693da168ab8e0809d86515b5f1a7e763f assets/create/blockstates/andesite_cobblestone_stairs.json
 82bd82270aff7d51e9239680ef4dd7b5c899ceb0 assets/create/blockstates/andesite_cobblestone_wall.json
 9639b901ffdd2ecccab5575c5c9e6c7b5c901e02 assets/create/blockstates/andesite_encased_shaft.json
-11908c2f8603e61bec88010bc6d0890e6339c6b1 assets/create/blockstates/andesite_funnel.json
+7187eba21a32e6954261cc71008ec1834a2e8af7 assets/create/blockstates/andesite_funnel.json
 398922758a6219544e5b85c91c9cf8a543b437e5 assets/create/blockstates/andesite_pillar.json
 1d2d8081581e07d9be4b382aede4f2de4401cc6b assets/create/blockstates/andesite_tunnel.json
 e555e3c2b2d3f01440e48db4ba88f7e00fd99b6f assets/create/blockstates/basin.json
@@ -34,7 +34,7 @@ ee1299a15fca849eb42bf81507f85a54c167bbfe assets/create/blockstates/brass_belt_fu
 8b1dd00adcc7e74c5a9feed069e2610b15a338cb assets/create/blockstates/brass_block.json
 b8dd6e505943e06706d0718ece620ab3cf943650 assets/create/blockstates/brass_casing.json
 288bad07593a8a2c8efaf44bba0ffb0011d36cd3 assets/create/blockstates/brass_encased_shaft.json
-3057e1121117c0cd651c288cd8e2d46bdf64afb1 assets/create/blockstates/brass_funnel.json
+8b5e88dea4e10ba3c74f0f161e49fed31a376ea1 assets/create/blockstates/brass_funnel.json
 672eedcd3520c6d39603449165a23be9c612c620 assets/create/blockstates/brass_tunnel.json
 11ebdd9bd0815833e62ec1bea03a4cdd86ce00f3 assets/create/blockstates/brown_sail.json
 e81608346d43406ee72cae0f78b8bcfb37ba2d75 assets/create/blockstates/brown_seat.json
@@ -140,7 +140,7 @@ de8a40b7daf1497d5aecee47a43b3e0b1d030b00 assets/create/blockstates/fancy_scoria_
 fc9ac0a7e7191b93516719455a17177fa6524ecc assets/create/blockstates/fancy_weathered_limestone_bricks_slab.json
 b2a7c321b1795f20e7433f81a55ce4683de081b8 assets/create/blockstates/fancy_weathered_limestone_bricks_stairs.json
 6372fe02ba0065acb0758121c45a15a1a8fdc5de assets/create/blockstates/fancy_weathered_limestone_bricks_wall.json
-3d97226b5e8d8f70ed08e45e78db1faf78d5e28b assets/create/blockstates/fluid_pipe.json
+4c3e0500f9382d2e426e823fe876f57f4d7ee3b4 assets/create/blockstates/fluid_pipe.json
 f0eaab18e16c4f3f65ebf3b55b08f0dc445720fe assets/create/blockstates/fluid_tank.json
 5408d92ab02af86539ac42971d4033545970bb3a assets/create/blockstates/fluid_valve.json
 e9da1794b6ece7f9aa8bcb43d42c23a55446133b assets/create/blockstates/flywheel.json
@@ -335,7 +335,7 @@ e8b0a401c10d1ba67ed71ba31bd5f9bc28571b65 assets/create/blockstates/powered_toggl
 d06cd9a1101b18d306a786320aab12018b1325d6 assets/create/blockstates/purple_sail.json
 92957119abd5fbcca36a113b2a80255fd70fc303 assets/create/blockstates/purple_seat.json
 61035f8afe75ff7bbd291da5d8690bcbebe679eb assets/create/blockstates/purple_valve_handle.json
-8d7e653bfd9846e684a0d3725595714a19201017 assets/create/blockstates/radial_chassis.json
+89b63c6e5875da07226854651079bcea85439f5b assets/create/blockstates/radial_chassis.json
 45877c4d90a7185c2f304edbd67379d800920439 assets/create/blockstates/red_sail.json
 da1b08387af7afa0855ee8d040f620c01f20660a assets/create/blockstates/red_seat.json
 722fc77bbf387af8a4016e42cbf9501d2b968881 assets/create/blockstates/red_valve_handle.json
@@ -363,6 +363,7 @@ b6e50f46a02f833f2f2bafa8585a909b6da5e229 assets/create/blockstates/scoria_cobble
 81931eb1027dfb42ba4b2186185a4c0a36e0dbe4 assets/create/blockstates/sequenced_gearshift.json
 c4c3613ad353e721e7109628aa06ab0664d0862b assets/create/blockstates/shadow_steel_casing.json
 79ae6d86a829b9ce82fce68a6377d3810fcfcb10 assets/create/blockstates/shaft.json
+fa4ffec5eac02c0180226d994d51756e44f85674 assets/create/blockstates/smart_chute.json
 f0f72cc1faacc8f37c8ac1833c22eb910771c800 assets/create/blockstates/smart_fluid_pipe.json
 e815bfd854c2653f10828bb11950f7fb991d7efc assets/create/blockstates/speedometer.json
 1cb7cdbefa0ff199263782809287854b9d85074c assets/create/blockstates/spout.json
@@ -397,17 +398,17 @@ a3a11524cd3515fc01d905767b4b7ea782adaf03 assets/create/blockstates/yellow_seat.j
 6801fa1f466f172700e573e5b8ee8ee5f9ca4583 assets/create/blockstates/yellow_valve_handle.json
 7f39521b211441f5c3e06d60c5978cebe16cacfb assets/create/blockstates/zinc_block.json
 b7181bcd8182b2f17088e5aa881f374c9c65470c assets/create/blockstates/zinc_ore.json
-f11f6bc6d9284f3b995e5d250745d0a1194bc695 assets/create/lang/en_ud.json
-59dd1d0c9c0f412f581c699f0bf592fcf348759a assets/create/lang/en_us.json
-b7e4fc8328d3aa4ec53be9bb43c23c47100eeafc assets/create/lang/unfinished/de_de.json
-7ceceb887b54180d28226e30b8b0b1275467e184 assets/create/lang/unfinished/fr_fr.json
-9e5e930062edbfcdeaaeeb12578a07fe6bcd0e81 assets/create/lang/unfinished/it_it.json
-8166a89d96a366dfd702e166b60df7e36a76a120 assets/create/lang/unfinished/ja_jp.json
-6d1a54f08518bbf76f409b19d8f51c67cdfff4d5 assets/create/lang/unfinished/ko_kr.json
-e95942103c0ad4530dd7a919a4a3baeb66f47f51 assets/create/lang/unfinished/nl_nl.json
-44f9d40e0b762f5a83e8b7e02edc09cc2e29e8ab assets/create/lang/unfinished/pt_br.json
-7e2c09dc9dde79c98f3e7726cee803f795cfa63c assets/create/lang/unfinished/ru_ru.json
-d8207dfebabd2985b3d60c9222e7682cefaafdcb assets/create/lang/unfinished/zh_cn.json
+df67c2c11fa22487d3a0fdc9b008056e593d14e3 assets/create/lang/en_ud.json
+3ad443f44eb33fe8c3ac092d1532dcbd27e49c84 assets/create/lang/en_us.json
+612a63d73f7f4b8e79dce3f53ddbe3345f0e74d8 assets/create/lang/unfinished/de_de.json
+2e37dc718a8dea2af85daba7266c877ce80ff35b assets/create/lang/unfinished/fr_fr.json
+f843761728c403276b7a47282f4fdd039b5b6854 assets/create/lang/unfinished/it_it.json
+8b90c66fd5974c993e83bfa5733ca03187211d28 assets/create/lang/unfinished/ja_jp.json
+59db0a3cff42707ecb828b975ef1fcba2a21a521 assets/create/lang/unfinished/ko_kr.json
+b1900a6cce7216a4baa844affa169cfb32ff645c assets/create/lang/unfinished/nl_nl.json
+d3f09a37b1f4ec5d53effc2b87efbccf2df2b7c7 assets/create/lang/unfinished/pt_br.json
+16c92dab525ba20e85b65ee084f7b760432dcb73 assets/create/lang/unfinished/ru_ru.json
+c8b5c2a3a65468950aa713a56bf1c930eef81305 assets/create/lang/unfinished/zh_cn.json
 846200eb548d3bfa2e77b41039de159b4b6cfb45 assets/create/models/block/acacia_window.json
 1930fa3a3c98d53dd19e4ee7f55bc27fd47aa281 assets/create/models/block/acacia_window_pane_noside.json
 1763ea2c9b981d187f5031ba608f3d5d3be3986a assets/create/models/block/acacia_window_pane_noside_alt.json
@@ -455,8 +456,18 @@ ad255a62a5f54b578db06e89fd7160001f905675 assets/create/models/block/andesite_cob
 a033fbac3129bba9211c6c4a0e16c905643afa39 assets/create/models/block/andesite_cobblestone_stairs_outer.json
 1c574ee47aeb6fcb305bfc95dd131e153b795a0e assets/create/models/block/andesite_cobblestone_wall_post.json
 0ed983628e8868f77301bea1111570d3631f24fb assets/create/models/block/andesite_cobblestone_wall_side.json
-51e851b15870c0922cfbe911ef1a2f22062969f3 assets/create/models/block/andesite_funnel.json
-f28da6703691f1b08cfb49208f0f7bb0c5ca816d assets/create/models/block/andesite_funnel_powered.json
+7d5faceb2a8d67acddd39625da6d5853f07ea8bd assets/create/models/block/andesite_funnel_ceiling_pull.json
+82393ded7287660d16549e321317dfe4488cc81d assets/create/models/block/andesite_funnel_ceiling_pull_powered.json
+40d7adae3b5eecd8ed08445b2d7f43d7a0684837 assets/create/models/block/andesite_funnel_ceiling_push.json
+940cace1d38fef0d5d88a391b0ba8cf690b38a44 assets/create/models/block/andesite_funnel_ceiling_push_powered.json
+c77c660ea142419e93754c9702445c269dbcd0cc assets/create/models/block/andesite_funnel_floor_pull.json
+16d402c764364254a704a13736bd68455edc28ba assets/create/models/block/andesite_funnel_floor_pull_powered.json
+6a809d0e0e53b845b587276444cb7b64a1e15e81 assets/create/models/block/andesite_funnel_floor_push.json
+6eac3e4f593e4182f5c216a900136a62ea953fb5 assets/create/models/block/andesite_funnel_floor_push_powered.json
+cc187c98c62b47f5bdb6e5187f52d3d927486376 assets/create/models/block/andesite_funnel_wall_pull.json
+525cf080df53a428d1321d25c2021b5f3b80a4e6 assets/create/models/block/andesite_funnel_wall_pull_powered.json
+78fcd6a91a84f5824e3e0006609b6f01760238d4 assets/create/models/block/andesite_funnel_wall_push.json
+6c48d1a0b8cb007a6eddaa9b2f6cb8a98334d34e assets/create/models/block/andesite_funnel_wall_push_powered.json
 b1d0bb538fc8285b7d3fd77a977d78a104b83b62 assets/create/models/block/andesite_pillar.json
 aaf2e4259bcfcedd3400e9acb2d64c0cf06f7fb1 assets/create/models/block/andesite_tunnel/cross.json
 75f628178fa21a2bd301eea8d1cebf7e94f7d5cc assets/create/models/block/andesite_tunnel/straight.json
@@ -497,8 +508,18 @@ dfc6250e28e12ff193a45891978ec50c406fc0c2 assets/create/models/block/brass_belt_f
 97410a12b7c1461f88fb633f26ff566a0636b627 assets/create/models/block/brass_belt_funnel__retracted.json
 71d0ad31d89d4ea3f243c6003b17f57fd168c933 assets/create/models/block/brass_block.json
 166a5c053a81e6aadc24509ed24dc144a7255969 assets/create/models/block/brass_casing.json
-838e7ab4c0c9d89eacfa078daf64995e505db896 assets/create/models/block/brass_funnel.json
-6099ba0366065d15d3b2821474850a1ae85485ea assets/create/models/block/brass_funnel_powered.json
+f5f689dc8be53e560878d3dde7b6eda6b3bf28e3 assets/create/models/block/brass_funnel_ceiling_pull.json
+142a56e522c74268d0b418985eb3fd285e371295 assets/create/models/block/brass_funnel_ceiling_pull_powered.json
+e583d701961b68223778d28edc0e2686c1a5c5df assets/create/models/block/brass_funnel_ceiling_push.json
+ccb2b596c3f190c26fdec06dd2b53ac3e59b1ff2 assets/create/models/block/brass_funnel_ceiling_push_powered.json
+7f541d8235326fea3ecb370c4cf2913867f439ad assets/create/models/block/brass_funnel_floor_pull.json
+5277d7c614991a5bce0e9234c4094f02c6d201c2 assets/create/models/block/brass_funnel_floor_pull_powered.json
+1831d87b5a9784c12cecefbb9d3173c29f4ddc87 assets/create/models/block/brass_funnel_floor_push.json
+6aee078641719086c9a98ebd1c0d0d61cd4d33a9 assets/create/models/block/brass_funnel_floor_push_powered.json
+aa86ddeeb41aea5bd85dd488d932fbc913828b1f assets/create/models/block/brass_funnel_wall_pull.json
+161b420ee4f41d436177e20314dcbe61ecec53a8 assets/create/models/block/brass_funnel_wall_pull_powered.json
+24362e71ca3a6d0f2dbf129909eceb8b3937a66b assets/create/models/block/brass_funnel_wall_push.json
+76cdebba3116be88926d9640917e579377ef3134 assets/create/models/block/brass_funnel_wall_push_powered.json
 520087db8d479c66f85f3483af813fb668f27503 assets/create/models/block/brass_tunnel/cross.json
 347ed67bf3426e323354e2d959fc9563dc7eeecd assets/create/models/block/brass_tunnel/straight.json
 a959e03ca339badb49fe58ba53d86a84352e91f3 assets/create/models/block/brass_tunnel/t_left.json
@@ -1126,7 +1147,7 @@ d283f86cd05ed378efd82ce46cf49bc83783069b assets/create/models/item/andesite_bric
 b0f664dd6de3d0ee9afcb6223fbcd53b97fa0d65 assets/create/models/item/andesite_cobblestone_stairs.json
 4856d13a72ec0af9f10226b4a4bf0567eb580b9a assets/create/models/item/andesite_cobblestone_wall.json
 bc6e7469744604e578200ea87690e4dd3b25e447 assets/create/models/item/andesite_encased_shaft.json
-7490819e7e5445019b6b8cb2538f12a5b6717a46 assets/create/models/item/andesite_funnel.json
+a3866ea9f44e80b64989f2b5f8a9f344da959c87 assets/create/models/item/andesite_funnel.json
 75b8b00c2418b9660d35a7fabd0774925cf1c02f assets/create/models/item/andesite_pillar.json
 c0e35daccfb398947532e9499d6bda963387cd9c assets/create/models/item/andesite_tunnel.json
 54875c992ec4e314826ca37257e64a96f1c0907e assets/create/models/item/bar_of_chocolate.json
@@ -1144,7 +1165,7 @@ bec96ebf3369d3cffa9bb1b8bf9f2a5cd5d0ef96 assets/create/models/item/blue_valve_ha
 17d340c3678bd24cb085ba49490b2b4cb341a9e7 assets/create/models/item/brass_block.json
 f5a18f4279c2e845a5967b1c2f9e807c2bb77afb assets/create/models/item/brass_casing.json
 c723011e09203821b6b59cff9de22454c5e4395a assets/create/models/item/brass_encased_shaft.json
-099961ca4a75b6ecfddd1db6dd29909276759f3b assets/create/models/item/brass_funnel.json
+12781f22d9b91df903d38bc55c4fe9f75dba8867 assets/create/models/item/brass_funnel.json
 361f75a79de5007d7a99ad0a38103c9aa8c3017c assets/create/models/item/brass_hand.json
 1786bdffa2ab5a07c88d2797db3d7b54461323c4 assets/create/models/item/brass_ingot.json
 a37be4a0ec9bf6c381527403c57ced4f81abd67c assets/create/models/item/brass_nugget.json
@@ -1503,6 +1524,7 @@ b0061419cf7b7bd2dd548ff00ee28f1227ee2663 assets/create/models/item/scoria_cobble
 da72ccdc893fbdd3efa9c22143b88eb756c20e44 assets/create/models/item/shadow_steel.json
 081326d6666cfcfe34c45c1b74bfceba0b01ae6e assets/create/models/item/shadow_steel_casing.json
 106ae694f7e03a218c37003dca8291b1d39b3c55 assets/create/models/item/shaft.json
+0f6bc6a4328ef317d50903c7b50ab5f78fce37eb assets/create/models/item/smart_chute.json
 188c49e5d8d9a2d5a570dbccdf3efd1b472dae18 assets/create/models/item/smart_fluid_pipe.json
 d6fb0d38b1b5bcc199b52ac8889eaecd167f6725 assets/create/models/item/speedometer.json
 b9abe1331d49871838231f3a8e5d2973634e9325 assets/create/models/item/spout.json
@@ -1772,6 +1794,7 @@ e9faf71b9597deecd2c1fb566f3c438ddc243e82 data/create/advancements/recipes/create
 b463cf9343f8d08b8ed3e87f46a19facadd657b0 data/create/advancements/recipes/create.base/crafting/kinetics/secondary_linear_chassisfrom_conversion.json
 191213ef824e7b73d66bb3aecc3115306b445e5a data/create/advancements/recipes/create.base/crafting/kinetics/sequenced_gearshift.json
 cd8cefee21a1690f9158b8e8661a92d20ad0f535 data/create/advancements/recipes/create.base/crafting/kinetics/shaft.json
+1b460b6014cb298cbea3e658596f0e753fa8066a data/create/advancements/recipes/create.base/crafting/kinetics/smart_chute.json
 232044be44da655ff09deeb99cb220bf71e31096 data/create/advancements/recipes/create.base/crafting/kinetics/smart_fluid_pipe.json
 e8a5d924ccf30b6eae4b9ec0a8040e31f0eb165b data/create/advancements/recipes/create.base/crafting/kinetics/speedometer.json
 90ff137eb1533695d9d17296ed180c0a88ddd891 data/create/advancements/recipes/create.base/crafting/kinetics/speedometerfrom_conversion.json
@@ -2617,6 +2640,7 @@ f70c5b7e7da7abffc82e3d1828499799883bbe85 data/create/loot_tables/blocks/secondar
 e4f6dccb8bce21b5214c1d8cfb440fc0ba4159d7 data/create/loot_tables/blocks/sequenced_gearshift.json
 49f6b51c0618aa0c0133dc1f034ff6c031318cac data/create/loot_tables/blocks/shadow_steel_casing.json
 b127cb6920e6d7d9c8b2402cb186402a9a8dd3fc data/create/loot_tables/blocks/shaft.json
+22bbb9770388d2a30fa8e95e9a06b7546d66a606 data/create/loot_tables/blocks/smart_chute.json
 9e4d8220e513f5ecef27f60001681e9d66331d7b data/create/loot_tables/blocks/smart_fluid_pipe.json
 70b6e82e9198d3910877e62c2eab86d46ca27089 data/create/loot_tables/blocks/speedometer.json
 f6c497d625de67ea9377e840208b1be539d13b73 data/create/loot_tables/blocks/spout.json
@@ -2826,6 +2850,7 @@ d0d7fb94621f6f02fa3137666f20e677022d9d5b data/create/recipes/crafting/kinetics/s
 66922e18791c87fadb7629cdf32d3dd2f50ccd13 data/create/recipes/crafting/kinetics/secondary_linear_chassisfrom_conversion.json
 a17db27e61baa45f8a6ecb46a6d2a5a464704f8b data/create/recipes/crafting/kinetics/sequenced_gearshift.json
 2e36438665bfb97265fd4e6ea85505970eae67fd data/create/recipes/crafting/kinetics/shaft.json
+683c9e128a976282eaa6cdbbee3914e4c66b1676 data/create/recipes/crafting/kinetics/smart_chute.json
 319e75dc4be645efd4809dafc1331581a8022e93 data/create/recipes/crafting/kinetics/smart_fluid_pipe.json
 b1a74f0b51fa37ca1ed814266b3d69b8b7e69fa3 data/create/recipes/crafting/kinetics/speedometer.json
 8d632845deeb723e1a56083536ee5f9d60de2fcb data/create/recipes/crafting/kinetics/speedometerfrom_conversion.json
diff --git a/src/generated/resources/assets/create/blockstates/andesite_funnel.json b/src/generated/resources/assets/create/blockstates/andesite_funnel.json
index 9056622b7f..0161a17063 100644
--- a/src/generated/resources/assets/create/blockstates/andesite_funnel.json
+++ b/src/generated/resources/assets/create/blockstates/andesite_funnel.json
@@ -1,55 +1,183 @@
 {
   "variants": {
-    "facing=down,powered=false": {
-      "model": "create:block/andesite_funnel",
-      "x": 180
+    "extracting=false,face=floor,facing=north,powered=false": {
+      "model": "create:block/andesite_funnel_floor_pull"
     },
-    "facing=up,powered=false": {
-      "model": "create:block/andesite_funnel"
+    "extracting=true,face=floor,facing=north,powered=false": {
+      "model": "create:block/andesite_funnel_floor_push"
     },
-    "facing=north,powered=false": {
-      "model": "create:block/andesite_funnel",
-      "x": 90
+    "extracting=false,face=wall,facing=north,powered=false": {
+      "model": "create:block/andesite_funnel_wall_pull"
     },
-    "facing=south,powered=false": {
-      "model": "create:block/andesite_funnel",
-      "x": 90,
+    "extracting=true,face=wall,facing=north,powered=false": {
+      "model": "create:block/andesite_funnel_wall_push"
+    },
+    "extracting=false,face=ceiling,facing=north,powered=false": {
+      "model": "create:block/andesite_funnel_ceiling_pull"
+    },
+    "extracting=true,face=ceiling,facing=north,powered=false": {
+      "model": "create:block/andesite_funnel_ceiling_push"
+    },
+    "extracting=false,face=floor,facing=south,powered=false": {
+      "model": "create:block/andesite_funnel_floor_pull",
       "y": 180
     },
-    "facing=west,powered=false": {
-      "model": "create:block/andesite_funnel",
-      "x": 90,
+    "extracting=true,face=floor,facing=south,powered=false": {
+      "model": "create:block/andesite_funnel_floor_push",
+      "y": 180
+    },
+    "extracting=false,face=wall,facing=south,powered=false": {
+      "model": "create:block/andesite_funnel_wall_pull",
+      "y": 180
+    },
+    "extracting=true,face=wall,facing=south,powered=false": {
+      "model": "create:block/andesite_funnel_wall_push",
+      "y": 180
+    },
+    "extracting=false,face=ceiling,facing=south,powered=false": {
+      "model": "create:block/andesite_funnel_ceiling_pull",
+      "y": 180
+    },
+    "extracting=true,face=ceiling,facing=south,powered=false": {
+      "model": "create:block/andesite_funnel_ceiling_push",
+      "y": 180
+    },
+    "extracting=false,face=floor,facing=west,powered=false": {
+      "model": "create:block/andesite_funnel_floor_pull",
       "y": 270
     },
-    "facing=east,powered=false": {
-      "model": "create:block/andesite_funnel",
-      "x": 90,
+    "extracting=true,face=floor,facing=west,powered=false": {
+      "model": "create:block/andesite_funnel_floor_push",
+      "y": 270
+    },
+    "extracting=false,face=wall,facing=west,powered=false": {
+      "model": "create:block/andesite_funnel_wall_pull",
+      "y": 270
+    },
+    "extracting=true,face=wall,facing=west,powered=false": {
+      "model": "create:block/andesite_funnel_wall_push",
+      "y": 270
+    },
+    "extracting=false,face=ceiling,facing=west,powered=false": {
+      "model": "create:block/andesite_funnel_ceiling_pull",
+      "y": 270
+    },
+    "extracting=true,face=ceiling,facing=west,powered=false": {
+      "model": "create:block/andesite_funnel_ceiling_push",
+      "y": 270
+    },
+    "extracting=false,face=floor,facing=east,powered=false": {
+      "model": "create:block/andesite_funnel_floor_pull",
       "y": 90
     },
-    "facing=down,powered=true": {
-      "model": "create:block/andesite_funnel_powered",
-      "x": 180
+    "extracting=true,face=floor,facing=east,powered=false": {
+      "model": "create:block/andesite_funnel_floor_push",
+      "y": 90
     },
-    "facing=up,powered=true": {
-      "model": "create:block/andesite_funnel_powered"
+    "extracting=false,face=wall,facing=east,powered=false": {
+      "model": "create:block/andesite_funnel_wall_pull",
+      "y": 90
     },
-    "facing=north,powered=true": {
-      "model": "create:block/andesite_funnel_powered",
-      "x": 90
+    "extracting=true,face=wall,facing=east,powered=false": {
+      "model": "create:block/andesite_funnel_wall_push",
+      "y": 90
     },
-    "facing=south,powered=true": {
-      "model": "create:block/andesite_funnel_powered",
-      "x": 90,
+    "extracting=false,face=ceiling,facing=east,powered=false": {
+      "model": "create:block/andesite_funnel_ceiling_pull",
+      "y": 90
+    },
+    "extracting=true,face=ceiling,facing=east,powered=false": {
+      "model": "create:block/andesite_funnel_ceiling_push",
+      "y": 90
+    },
+    "extracting=false,face=floor,facing=north,powered=true": {
+      "model": "create:block/andesite_funnel_floor_pull_powered"
+    },
+    "extracting=true,face=floor,facing=north,powered=true": {
+      "model": "create:block/andesite_funnel_floor_push_powered"
+    },
+    "extracting=false,face=wall,facing=north,powered=true": {
+      "model": "create:block/andesite_funnel_wall_pull_powered"
+    },
+    "extracting=true,face=wall,facing=north,powered=true": {
+      "model": "create:block/andesite_funnel_wall_push_powered"
+    },
+    "extracting=false,face=ceiling,facing=north,powered=true": {
+      "model": "create:block/andesite_funnel_ceiling_pull_powered"
+    },
+    "extracting=true,face=ceiling,facing=north,powered=true": {
+      "model": "create:block/andesite_funnel_ceiling_push_powered"
+    },
+    "extracting=false,face=floor,facing=south,powered=true": {
+      "model": "create:block/andesite_funnel_floor_pull_powered",
       "y": 180
     },
-    "facing=west,powered=true": {
-      "model": "create:block/andesite_funnel_powered",
-      "x": 90,
+    "extracting=true,face=floor,facing=south,powered=true": {
+      "model": "create:block/andesite_funnel_floor_push_powered",
+      "y": 180
+    },
+    "extracting=false,face=wall,facing=south,powered=true": {
+      "model": "create:block/andesite_funnel_wall_pull_powered",
+      "y": 180
+    },
+    "extracting=true,face=wall,facing=south,powered=true": {
+      "model": "create:block/andesite_funnel_wall_push_powered",
+      "y": 180
+    },
+    "extracting=false,face=ceiling,facing=south,powered=true": {
+      "model": "create:block/andesite_funnel_ceiling_pull_powered",
+      "y": 180
+    },
+    "extracting=true,face=ceiling,facing=south,powered=true": {
+      "model": "create:block/andesite_funnel_ceiling_push_powered",
+      "y": 180
+    },
+    "extracting=false,face=floor,facing=west,powered=true": {
+      "model": "create:block/andesite_funnel_floor_pull_powered",
       "y": 270
     },
-    "facing=east,powered=true": {
-      "model": "create:block/andesite_funnel_powered",
-      "x": 90,
+    "extracting=true,face=floor,facing=west,powered=true": {
+      "model": "create:block/andesite_funnel_floor_push_powered",
+      "y": 270
+    },
+    "extracting=false,face=wall,facing=west,powered=true": {
+      "model": "create:block/andesite_funnel_wall_pull_powered",
+      "y": 270
+    },
+    "extracting=true,face=wall,facing=west,powered=true": {
+      "model": "create:block/andesite_funnel_wall_push_powered",
+      "y": 270
+    },
+    "extracting=false,face=ceiling,facing=west,powered=true": {
+      "model": "create:block/andesite_funnel_ceiling_pull_powered",
+      "y": 270
+    },
+    "extracting=true,face=ceiling,facing=west,powered=true": {
+      "model": "create:block/andesite_funnel_ceiling_push_powered",
+      "y": 270
+    },
+    "extracting=false,face=floor,facing=east,powered=true": {
+      "model": "create:block/andesite_funnel_floor_pull_powered",
+      "y": 90
+    },
+    "extracting=true,face=floor,facing=east,powered=true": {
+      "model": "create:block/andesite_funnel_floor_push_powered",
+      "y": 90
+    },
+    "extracting=false,face=wall,facing=east,powered=true": {
+      "model": "create:block/andesite_funnel_wall_pull_powered",
+      "y": 90
+    },
+    "extracting=true,face=wall,facing=east,powered=true": {
+      "model": "create:block/andesite_funnel_wall_push_powered",
+      "y": 90
+    },
+    "extracting=false,face=ceiling,facing=east,powered=true": {
+      "model": "create:block/andesite_funnel_ceiling_pull_powered",
+      "y": 90
+    },
+    "extracting=true,face=ceiling,facing=east,powered=true": {
+      "model": "create:block/andesite_funnel_ceiling_push_powered",
       "y": 90
     }
   }
diff --git a/src/generated/resources/assets/create/blockstates/brass_funnel.json b/src/generated/resources/assets/create/blockstates/brass_funnel.json
index bd9c613330..7458dae7c2 100644
--- a/src/generated/resources/assets/create/blockstates/brass_funnel.json
+++ b/src/generated/resources/assets/create/blockstates/brass_funnel.json
@@ -1,55 +1,183 @@
 {
   "variants": {
-    "facing=down,powered=false": {
-      "model": "create:block/brass_funnel",
-      "x": 180
+    "extracting=false,face=floor,facing=north,powered=false": {
+      "model": "create:block/brass_funnel_floor_pull"
     },
-    "facing=up,powered=false": {
-      "model": "create:block/brass_funnel"
+    "extracting=true,face=floor,facing=north,powered=false": {
+      "model": "create:block/brass_funnel_floor_push"
     },
-    "facing=north,powered=false": {
-      "model": "create:block/brass_funnel",
-      "x": 90
+    "extracting=false,face=wall,facing=north,powered=false": {
+      "model": "create:block/brass_funnel_wall_pull"
     },
-    "facing=south,powered=false": {
-      "model": "create:block/brass_funnel",
-      "x": 90,
+    "extracting=true,face=wall,facing=north,powered=false": {
+      "model": "create:block/brass_funnel_wall_push"
+    },
+    "extracting=false,face=ceiling,facing=north,powered=false": {
+      "model": "create:block/brass_funnel_ceiling_pull"
+    },
+    "extracting=true,face=ceiling,facing=north,powered=false": {
+      "model": "create:block/brass_funnel_ceiling_push"
+    },
+    "extracting=false,face=floor,facing=south,powered=false": {
+      "model": "create:block/brass_funnel_floor_pull",
       "y": 180
     },
-    "facing=west,powered=false": {
-      "model": "create:block/brass_funnel",
-      "x": 90,
+    "extracting=true,face=floor,facing=south,powered=false": {
+      "model": "create:block/brass_funnel_floor_push",
+      "y": 180
+    },
+    "extracting=false,face=wall,facing=south,powered=false": {
+      "model": "create:block/brass_funnel_wall_pull",
+      "y": 180
+    },
+    "extracting=true,face=wall,facing=south,powered=false": {
+      "model": "create:block/brass_funnel_wall_push",
+      "y": 180
+    },
+    "extracting=false,face=ceiling,facing=south,powered=false": {
+      "model": "create:block/brass_funnel_ceiling_pull",
+      "y": 180
+    },
+    "extracting=true,face=ceiling,facing=south,powered=false": {
+      "model": "create:block/brass_funnel_ceiling_push",
+      "y": 180
+    },
+    "extracting=false,face=floor,facing=west,powered=false": {
+      "model": "create:block/brass_funnel_floor_pull",
       "y": 270
     },
-    "facing=east,powered=false": {
-      "model": "create:block/brass_funnel",
-      "x": 90,
+    "extracting=true,face=floor,facing=west,powered=false": {
+      "model": "create:block/brass_funnel_floor_push",
+      "y": 270
+    },
+    "extracting=false,face=wall,facing=west,powered=false": {
+      "model": "create:block/brass_funnel_wall_pull",
+      "y": 270
+    },
+    "extracting=true,face=wall,facing=west,powered=false": {
+      "model": "create:block/brass_funnel_wall_push",
+      "y": 270
+    },
+    "extracting=false,face=ceiling,facing=west,powered=false": {
+      "model": "create:block/brass_funnel_ceiling_pull",
+      "y": 270
+    },
+    "extracting=true,face=ceiling,facing=west,powered=false": {
+      "model": "create:block/brass_funnel_ceiling_push",
+      "y": 270
+    },
+    "extracting=false,face=floor,facing=east,powered=false": {
+      "model": "create:block/brass_funnel_floor_pull",
       "y": 90
     },
-    "facing=down,powered=true": {
-      "model": "create:block/brass_funnel_powered",
-      "x": 180
+    "extracting=true,face=floor,facing=east,powered=false": {
+      "model": "create:block/brass_funnel_floor_push",
+      "y": 90
     },
-    "facing=up,powered=true": {
-      "model": "create:block/brass_funnel_powered"
+    "extracting=false,face=wall,facing=east,powered=false": {
+      "model": "create:block/brass_funnel_wall_pull",
+      "y": 90
     },
-    "facing=north,powered=true": {
-      "model": "create:block/brass_funnel_powered",
-      "x": 90
+    "extracting=true,face=wall,facing=east,powered=false": {
+      "model": "create:block/brass_funnel_wall_push",
+      "y": 90
     },
-    "facing=south,powered=true": {
-      "model": "create:block/brass_funnel_powered",
-      "x": 90,
+    "extracting=false,face=ceiling,facing=east,powered=false": {
+      "model": "create:block/brass_funnel_ceiling_pull",
+      "y": 90
+    },
+    "extracting=true,face=ceiling,facing=east,powered=false": {
+      "model": "create:block/brass_funnel_ceiling_push",
+      "y": 90
+    },
+    "extracting=false,face=floor,facing=north,powered=true": {
+      "model": "create:block/brass_funnel_floor_pull_powered"
+    },
+    "extracting=true,face=floor,facing=north,powered=true": {
+      "model": "create:block/brass_funnel_floor_push_powered"
+    },
+    "extracting=false,face=wall,facing=north,powered=true": {
+      "model": "create:block/brass_funnel_wall_pull_powered"
+    },
+    "extracting=true,face=wall,facing=north,powered=true": {
+      "model": "create:block/brass_funnel_wall_push_powered"
+    },
+    "extracting=false,face=ceiling,facing=north,powered=true": {
+      "model": "create:block/brass_funnel_ceiling_pull_powered"
+    },
+    "extracting=true,face=ceiling,facing=north,powered=true": {
+      "model": "create:block/brass_funnel_ceiling_push_powered"
+    },
+    "extracting=false,face=floor,facing=south,powered=true": {
+      "model": "create:block/brass_funnel_floor_pull_powered",
       "y": 180
     },
-    "facing=west,powered=true": {
-      "model": "create:block/brass_funnel_powered",
-      "x": 90,
+    "extracting=true,face=floor,facing=south,powered=true": {
+      "model": "create:block/brass_funnel_floor_push_powered",
+      "y": 180
+    },
+    "extracting=false,face=wall,facing=south,powered=true": {
+      "model": "create:block/brass_funnel_wall_pull_powered",
+      "y": 180
+    },
+    "extracting=true,face=wall,facing=south,powered=true": {
+      "model": "create:block/brass_funnel_wall_push_powered",
+      "y": 180
+    },
+    "extracting=false,face=ceiling,facing=south,powered=true": {
+      "model": "create:block/brass_funnel_ceiling_pull_powered",
+      "y": 180
+    },
+    "extracting=true,face=ceiling,facing=south,powered=true": {
+      "model": "create:block/brass_funnel_ceiling_push_powered",
+      "y": 180
+    },
+    "extracting=false,face=floor,facing=west,powered=true": {
+      "model": "create:block/brass_funnel_floor_pull_powered",
       "y": 270
     },
-    "facing=east,powered=true": {
-      "model": "create:block/brass_funnel_powered",
-      "x": 90,
+    "extracting=true,face=floor,facing=west,powered=true": {
+      "model": "create:block/brass_funnel_floor_push_powered",
+      "y": 270
+    },
+    "extracting=false,face=wall,facing=west,powered=true": {
+      "model": "create:block/brass_funnel_wall_pull_powered",
+      "y": 270
+    },
+    "extracting=true,face=wall,facing=west,powered=true": {
+      "model": "create:block/brass_funnel_wall_push_powered",
+      "y": 270
+    },
+    "extracting=false,face=ceiling,facing=west,powered=true": {
+      "model": "create:block/brass_funnel_ceiling_pull_powered",
+      "y": 270
+    },
+    "extracting=true,face=ceiling,facing=west,powered=true": {
+      "model": "create:block/brass_funnel_ceiling_push_powered",
+      "y": 270
+    },
+    "extracting=false,face=floor,facing=east,powered=true": {
+      "model": "create:block/brass_funnel_floor_pull_powered",
+      "y": 90
+    },
+    "extracting=true,face=floor,facing=east,powered=true": {
+      "model": "create:block/brass_funnel_floor_push_powered",
+      "y": 90
+    },
+    "extracting=false,face=wall,facing=east,powered=true": {
+      "model": "create:block/brass_funnel_wall_pull_powered",
+      "y": 90
+    },
+    "extracting=true,face=wall,facing=east,powered=true": {
+      "model": "create:block/brass_funnel_wall_push_powered",
+      "y": 90
+    },
+    "extracting=false,face=ceiling,facing=east,powered=true": {
+      "model": "create:block/brass_funnel_ceiling_pull_powered",
+      "y": 90
+    },
+    "extracting=true,face=ceiling,facing=east,powered=true": {
+      "model": "create:block/brass_funnel_ceiling_push_powered",
       "y": 90
     }
   }
diff --git a/src/generated/resources/assets/create/blockstates/smart_chute.json b/src/generated/resources/assets/create/blockstates/smart_chute.json
new file mode 100644
index 0000000000..6f7f38d807
--- /dev/null
+++ b/src/generated/resources/assets/create/blockstates/smart_chute.json
@@ -0,0 +1,10 @@
+{
+  "variants": {
+    "powered=false": {
+      "model": "create:block/smart_chute/block"
+    },
+    "powered=true": {
+      "model": "create:block/smart_chute/block_powered"
+    }
+  }
+}
\ No newline at end of file
diff --git a/src/generated/resources/assets/create/lang/en_ud.json b/src/generated/resources/assets/create/lang/en_ud.json
index 185c108ce4..b49565761f 100644
--- a/src/generated/resources/assets/create/lang/en_ud.json
+++ b/src/generated/resources/assets/create/lang/en_ud.json
@@ -364,6 +364,7 @@
   "block.create.sequenced_gearshift": "\u0287\u025F\u0131\u0265s\u0279\u0250\u01DD\u2141 p\u01DD\u0254u\u01DDnb\u01DDS",
   "block.create.shadow_steel_casing": "bu\u0131s\u0250\u0186 \u028Dop\u0250\u0265S",
   "block.create.shaft": "\u0287\u025F\u0250\u0265S",
+  "block.create.smart_chute": "\u01DD\u0287n\u0265\u0186 \u0287\u0279\u0250\u026FS",
   "block.create.smart_fluid_pipe": "\u01DDd\u0131\u0500 p\u0131n\u05DF\u2132 \u0287\u0279\u0250\u026FS",
   "block.create.speedometer": "\u0279\u01DD\u0287\u01DD\u026Fop\u01DD\u01DDdS",
   "block.create.spout": "\u0287nodS",
diff --git a/src/generated/resources/assets/create/lang/en_us.json b/src/generated/resources/assets/create/lang/en_us.json
index 55b11711df..12f1a8558f 100644
--- a/src/generated/resources/assets/create/lang/en_us.json
+++ b/src/generated/resources/assets/create/lang/en_us.json
@@ -367,6 +367,7 @@
 	"block.create.sequenced_gearshift": "Sequenced Gearshift",
 	"block.create.shadow_steel_casing": "Shadow Casing",
 	"block.create.shaft": "Shaft",
+	"block.create.smart_chute": "Smart Chute",
 	"block.create.smart_fluid_pipe": "Smart Fluid Pipe",
 	"block.create.speedometer": "Speedometer",
 	"block.create.spout": "Spout",
@@ -1082,6 +1083,7 @@
 	"create.tooltip.chute.fans_push_down": "Fans push from Above",
 	"create.tooltip.chute.fans_pull_up": "Fans pull from Above",
 	"create.tooltip.chute.fans_pull_down": "Fans pull from Below",
+	"create.tooltip.chute.contains": "Contains: %1$s x%2$s",
 
 	"create.hint.hose_pulley.title": "Bottomless Supply",
 	"create.hint.hose_pulley": "The targeted body of fluid is considered infinite.",
diff --git a/src/generated/resources/assets/create/lang/unfinished/de_de.json b/src/generated/resources/assets/create/lang/unfinished/de_de.json
index 796a6e81a6..ab2ac68519 100644
--- a/src/generated/resources/assets/create/lang/unfinished/de_de.json
+++ b/src/generated/resources/assets/create/lang/unfinished/de_de.json
@@ -1,5 +1,5 @@
 {
-	"_": "Missing Localizations: 1210",
+	"_": "Missing Localizations: 1211",
 
 	"_": "->------------------------]  Game Elements  [------------------------<-",
 
@@ -368,6 +368,7 @@
 	"block.create.sequenced_gearshift": "UNLOCALIZED: Sequenced Gearshift",
 	"block.create.shadow_steel_casing": "UNLOCALIZED: Shadow Casing",
 	"block.create.shaft": "Welle",
+	"block.create.smart_chute": "UNLOCALIZED: Smart Chute",
 	"block.create.smart_fluid_pipe": "UNLOCALIZED: Smart Fluid Pipe",
 	"block.create.speedometer": "UNLOCALIZED: Speedometer",
 	"block.create.spout": "UNLOCALIZED: Spout",
@@ -681,7 +682,6 @@
 	"create.recipe.mechanical_crafting": "UNLOCALIZED: Mechanical Crafting",
 	"create.recipe.automatic_shaped": "UNLOCALIZED: Automated Shaped Crafting",
 	"create.recipe.block_cutting": "UNLOCALIZED: Block Cutting",
-	"create.recipe.wood_cutting": "UNLOCALIZED: Wood Cutting",
 	"create.recipe.blockzapper_upgrade": "Blockpistole",
 	"create.recipe.sandpaper_polishing": "UNLOCALIZED: Sandpaper Polishing",
 	"create.recipe.mystery_conversion": "UNLOCALIZED: Mysterious Conversion",
@@ -1083,6 +1083,7 @@
 	"create.tooltip.chute.fans_push_down": "UNLOCALIZED: Fans push from Above",
 	"create.tooltip.chute.fans_pull_up": "UNLOCALIZED: Fans pull from Above",
 	"create.tooltip.chute.fans_pull_down": "UNLOCALIZED: Fans pull from Below",
+	"create.tooltip.chute.contains": "UNLOCALIZED: Contains: %1$s x%2$s",
 
 	"create.hint.hose_pulley.title": "UNLOCALIZED: Bottomless Supply",
 	"create.hint.hose_pulley": "UNLOCALIZED: The targeted body of fluid is considered infinite.",
diff --git a/src/generated/resources/assets/create/lang/unfinished/fr_fr.json b/src/generated/resources/assets/create/lang/unfinished/fr_fr.json
index 6ca43aaf87..24cd8a5b7d 100644
--- a/src/generated/resources/assets/create/lang/unfinished/fr_fr.json
+++ b/src/generated/resources/assets/create/lang/unfinished/fr_fr.json
@@ -1,5 +1,5 @@
 {
-	"_": "Missing Localizations: 861",
+	"_": "Missing Localizations: 862",
 
 	"_": "->------------------------]  Game Elements  [------------------------<-",
 
@@ -368,6 +368,7 @@
 	"block.create.sequenced_gearshift": "Décaleur de rotation séquencé",
 	"block.create.shadow_steel_casing": "UNLOCALIZED: Shadow Casing",
 	"block.create.shaft": "Arbre mécanique",
+	"block.create.smart_chute": "UNLOCALIZED: Smart Chute",
 	"block.create.smart_fluid_pipe": "UNLOCALIZED: Smart Fluid Pipe",
 	"block.create.speedometer": "Compteur de vitesse",
 	"block.create.spout": "UNLOCALIZED: Spout",
@@ -681,7 +682,6 @@
 	"create.recipe.mechanical_crafting": "Fabrication mécanique",
 	"create.recipe.automatic_shaped": "UNLOCALIZED: Automated Shaped Crafting",
 	"create.recipe.block_cutting": "Coupe de bloc",
-	"create.recipe.wood_cutting": "UNLOCALIZED: Wood Cutting",
 	"create.recipe.blockzapper_upgrade": "Blockzappeur portable",
 	"create.recipe.sandpaper_polishing": "Polissage au papier de verre",
 	"create.recipe.mystery_conversion": "Métamorphose chromatique",
@@ -1083,6 +1083,7 @@
 	"create.tooltip.chute.fans_push_down": "UNLOCALIZED: Fans push from Above",
 	"create.tooltip.chute.fans_pull_up": "UNLOCALIZED: Fans pull from Above",
 	"create.tooltip.chute.fans_pull_down": "UNLOCALIZED: Fans pull from Below",
+	"create.tooltip.chute.contains": "UNLOCALIZED: Contains: %1$s x%2$s",
 
 	"create.hint.hose_pulley.title": "UNLOCALIZED: Bottomless Supply",
 	"create.hint.hose_pulley": "UNLOCALIZED: The targeted body of fluid is considered infinite.",
diff --git a/src/generated/resources/assets/create/lang/unfinished/it_it.json b/src/generated/resources/assets/create/lang/unfinished/it_it.json
index eac6238ac8..7de389b9f0 100644
--- a/src/generated/resources/assets/create/lang/unfinished/it_it.json
+++ b/src/generated/resources/assets/create/lang/unfinished/it_it.json
@@ -1,5 +1,5 @@
 {
-	"_": "Missing Localizations: 845",
+	"_": "Missing Localizations: 846",
 
 	"_": "->------------------------]  Game Elements  [------------------------<-",
 
@@ -368,6 +368,7 @@
 	"block.create.sequenced_gearshift": "Cambio Sequenziale",
 	"block.create.shadow_steel_casing": "UNLOCALIZED: Shadow Casing",
 	"block.create.shaft": "Albero",
+	"block.create.smart_chute": "UNLOCALIZED: Smart Chute",
 	"block.create.smart_fluid_pipe": "UNLOCALIZED: Smart Fluid Pipe",
 	"block.create.speedometer": "Tachimetro",
 	"block.create.spout": "UNLOCALIZED: Spout",
@@ -681,7 +682,6 @@
 	"create.recipe.mechanical_crafting": "Creazione Meccanico",
 	"create.recipe.automatic_shaped": "UNLOCALIZED: Automated Shaped Crafting",
 	"create.recipe.block_cutting": "Taglio Blocco",
-	"create.recipe.wood_cutting": "UNLOCALIZED: Wood Cutting",
 	"create.recipe.blockzapper_upgrade": "UNLOCALIZED: Handheld Blockzapper",
 	"create.recipe.sandpaper_polishing": "Carta Vetrata Levigata",
 	"create.recipe.mystery_conversion": "Metamorfosi Cromatica",
@@ -1083,6 +1083,7 @@
 	"create.tooltip.chute.fans_push_down": "UNLOCALIZED: Fans push from Above",
 	"create.tooltip.chute.fans_pull_up": "UNLOCALIZED: Fans pull from Above",
 	"create.tooltip.chute.fans_pull_down": "UNLOCALIZED: Fans pull from Below",
+	"create.tooltip.chute.contains": "UNLOCALIZED: Contains: %1$s x%2$s",
 
 	"create.hint.hose_pulley.title": "UNLOCALIZED: Bottomless Supply",
 	"create.hint.hose_pulley": "UNLOCALIZED: The targeted body of fluid is considered infinite.",
diff --git a/src/generated/resources/assets/create/lang/unfinished/ja_jp.json b/src/generated/resources/assets/create/lang/unfinished/ja_jp.json
index a93b0045b7..9b31a93859 100644
--- a/src/generated/resources/assets/create/lang/unfinished/ja_jp.json
+++ b/src/generated/resources/assets/create/lang/unfinished/ja_jp.json
@@ -1,5 +1,5 @@
 {
-	"_": "Missing Localizations: 844",
+	"_": "Missing Localizations: 845",
 
 	"_": "->------------------------]  Game Elements  [------------------------<-",
 
@@ -368,6 +368,7 @@
 	"block.create.sequenced_gearshift": "シーケンスギアシフト",
 	"block.create.shadow_steel_casing": "UNLOCALIZED: Shadow Casing",
 	"block.create.shaft": "軸",
+	"block.create.smart_chute": "UNLOCALIZED: Smart Chute",
 	"block.create.smart_fluid_pipe": "UNLOCALIZED: Smart Fluid Pipe",
 	"block.create.speedometer": "スピードメーター",
 	"block.create.spout": "UNLOCALIZED: Spout",
@@ -681,7 +682,6 @@
 	"create.recipe.mechanical_crafting": "メカニカルクラフト",
 	"create.recipe.automatic_shaped": "UNLOCALIZED: Automated Shaped Crafting",
 	"create.recipe.block_cutting": "ブロックカット",
-	"create.recipe.wood_cutting": "UNLOCALIZED: Wood Cutting",
 	"create.recipe.blockzapper_upgrade": "携帯型ブロックザッパー",
 	"create.recipe.sandpaper_polishing": "紙やすりでの研磨",
 	"create.recipe.mystery_conversion": "色彩変態",
@@ -1083,6 +1083,7 @@
 	"create.tooltip.chute.fans_push_down": "UNLOCALIZED: Fans push from Above",
 	"create.tooltip.chute.fans_pull_up": "UNLOCALIZED: Fans pull from Above",
 	"create.tooltip.chute.fans_pull_down": "UNLOCALIZED: Fans pull from Below",
+	"create.tooltip.chute.contains": "UNLOCALIZED: Contains: %1$s x%2$s",
 
 	"create.hint.hose_pulley.title": "UNLOCALIZED: Bottomless Supply",
 	"create.hint.hose_pulley": "UNLOCALIZED: The targeted body of fluid is considered infinite.",
diff --git a/src/generated/resources/assets/create/lang/unfinished/ko_kr.json b/src/generated/resources/assets/create/lang/unfinished/ko_kr.json
index de866f2ad5..bec923df7b 100644
--- a/src/generated/resources/assets/create/lang/unfinished/ko_kr.json
+++ b/src/generated/resources/assets/create/lang/unfinished/ko_kr.json
@@ -1,5 +1,5 @@
 {
-	"_": "Missing Localizations: 51",
+	"_": "Missing Localizations: 52",
 
 	"_": "->------------------------]  Game Elements  [------------------------<-",
 
@@ -368,6 +368,7 @@
 	"block.create.sequenced_gearshift": "순서 기어쉬프트",
 	"block.create.shadow_steel_casing": "그림자 케이스",
 	"block.create.shaft": "축",
+	"block.create.smart_chute": "UNLOCALIZED: Smart Chute",
 	"block.create.smart_fluid_pipe": "스마트 액체 파이프",
 	"block.create.speedometer": "속도 계측기",
 	"block.create.spout": "수도꼭지",
@@ -681,7 +682,6 @@
 	"create.recipe.mechanical_crafting": "기계 조합",
 	"create.recipe.automatic_shaped": "유형 자동 조합",
 	"create.recipe.block_cutting": "블 절단",
-	"create.recipe.wood_cutting": "UNLOCALIZED: Wood Cutting",
 	"create.recipe.blockzapper_upgrade": "휴대용 블록발사기 업그레이드",
 	"create.recipe.sandpaper_polishing": "사포질",
 	"create.recipe.mystery_conversion": "?",
@@ -1083,6 +1083,7 @@
 	"create.tooltip.chute.fans_push_down": "선풍기가 위에서 밈",
 	"create.tooltip.chute.fans_pull_up": "선풍기가 위에서 당김",
 	"create.tooltip.chute.fans_pull_down": "선풍기가 아래에서 당김",
+	"create.tooltip.chute.contains": "UNLOCALIZED: Contains: %1$s x%2$s",
 
 	"create.hint.hose_pulley.title": "UNLOCALIZED: Bottomless Supply",
 	"create.hint.hose_pulley": "UNLOCALIZED: The targeted body of fluid is considered infinite.",
diff --git a/src/generated/resources/assets/create/lang/unfinished/nl_nl.json b/src/generated/resources/assets/create/lang/unfinished/nl_nl.json
index 44b05e2ff8..0b8b4afb2d 100644
--- a/src/generated/resources/assets/create/lang/unfinished/nl_nl.json
+++ b/src/generated/resources/assets/create/lang/unfinished/nl_nl.json
@@ -1,5 +1,5 @@
 {
-	"_": "Missing Localizations: 1151",
+	"_": "Missing Localizations: 1152",
 
 	"_": "->------------------------]  Game Elements  [------------------------<-",
 
@@ -368,6 +368,7 @@
 	"block.create.sequenced_gearshift": "UNLOCALIZED: Sequenced Gearshift",
 	"block.create.shadow_steel_casing": "UNLOCALIZED: Shadow Casing",
 	"block.create.shaft": "Drijfas",
+	"block.create.smart_chute": "UNLOCALIZED: Smart Chute",
 	"block.create.smart_fluid_pipe": "UNLOCALIZED: Smart Fluid Pipe",
 	"block.create.speedometer": "Snelheidsmeter",
 	"block.create.spout": "UNLOCALIZED: Spout",
@@ -681,7 +682,6 @@
 	"create.recipe.mechanical_crafting": "UNLOCALIZED: Mechanical Crafting",
 	"create.recipe.automatic_shaped": "UNLOCALIZED: Automated Shaped Crafting",
 	"create.recipe.block_cutting": "Blok Zagen",
-	"create.recipe.wood_cutting": "UNLOCALIZED: Wood Cutting",
 	"create.recipe.blockzapper_upgrade": "Blokzapper",
 	"create.recipe.sandpaper_polishing": "UNLOCALIZED: Sandpaper Polishing",
 	"create.recipe.mystery_conversion": "UNLOCALIZED: Mysterious Conversion",
@@ -1083,6 +1083,7 @@
 	"create.tooltip.chute.fans_push_down": "UNLOCALIZED: Fans push from Above",
 	"create.tooltip.chute.fans_pull_up": "UNLOCALIZED: Fans pull from Above",
 	"create.tooltip.chute.fans_pull_down": "UNLOCALIZED: Fans pull from Below",
+	"create.tooltip.chute.contains": "UNLOCALIZED: Contains: %1$s x%2$s",
 
 	"create.hint.hose_pulley.title": "UNLOCALIZED: Bottomless Supply",
 	"create.hint.hose_pulley": "UNLOCALIZED: The targeted body of fluid is considered infinite.",
diff --git a/src/generated/resources/assets/create/lang/unfinished/pt_br.json b/src/generated/resources/assets/create/lang/unfinished/pt_br.json
index 260acf9c5b..e0eb5b8796 100644
--- a/src/generated/resources/assets/create/lang/unfinished/pt_br.json
+++ b/src/generated/resources/assets/create/lang/unfinished/pt_br.json
@@ -1,5 +1,5 @@
 {
-	"_": "Missing Localizations: 1217",
+	"_": "Missing Localizations: 1218",
 
 	"_": "->------------------------]  Game Elements  [------------------------<-",
 
@@ -368,6 +368,7 @@
 	"block.create.sequenced_gearshift": "UNLOCALIZED: Sequenced Gearshift",
 	"block.create.shadow_steel_casing": "UNLOCALIZED: Shadow Casing",
 	"block.create.shaft": "Eixo",
+	"block.create.smart_chute": "UNLOCALIZED: Smart Chute",
 	"block.create.smart_fluid_pipe": "UNLOCALIZED: Smart Fluid Pipe",
 	"block.create.speedometer": "UNLOCALIZED: Speedometer",
 	"block.create.spout": "UNLOCALIZED: Spout",
@@ -681,7 +682,6 @@
 	"create.recipe.mechanical_crafting": "UNLOCALIZED: Mechanical Crafting",
 	"create.recipe.automatic_shaped": "UNLOCALIZED: Automated Shaped Crafting",
 	"create.recipe.block_cutting": "UNLOCALIZED: Block Cutting",
-	"create.recipe.wood_cutting": "UNLOCALIZED: Wood Cutting",
 	"create.recipe.blockzapper_upgrade": "Blockzapper Portátil",
 	"create.recipe.sandpaper_polishing": "UNLOCALIZED: Sandpaper Polishing",
 	"create.recipe.mystery_conversion": "UNLOCALIZED: Mysterious Conversion",
@@ -1083,6 +1083,7 @@
 	"create.tooltip.chute.fans_push_down": "UNLOCALIZED: Fans push from Above",
 	"create.tooltip.chute.fans_pull_up": "UNLOCALIZED: Fans pull from Above",
 	"create.tooltip.chute.fans_pull_down": "UNLOCALIZED: Fans pull from Below",
+	"create.tooltip.chute.contains": "UNLOCALIZED: Contains: %1$s x%2$s",
 
 	"create.hint.hose_pulley.title": "UNLOCALIZED: Bottomless Supply",
 	"create.hint.hose_pulley": "UNLOCALIZED: The targeted body of fluid is considered infinite.",
diff --git a/src/generated/resources/assets/create/lang/unfinished/ru_ru.json b/src/generated/resources/assets/create/lang/unfinished/ru_ru.json
index 46eb0c3e97..2085aa34a2 100644
--- a/src/generated/resources/assets/create/lang/unfinished/ru_ru.json
+++ b/src/generated/resources/assets/create/lang/unfinished/ru_ru.json
@@ -1,5 +1,5 @@
 {
-	"_": "Missing Localizations: 1",
+	"_": "Missing Localizations: 2",
 
 	"_": "->------------------------]  Game Elements  [------------------------<-",
 
@@ -368,6 +368,7 @@
 	"block.create.sequenced_gearshift": "Последовательный переключатель передач",
 	"block.create.shadow_steel_casing": "Теневой кожух",
 	"block.create.shaft": "Вал",
+	"block.create.smart_chute": "UNLOCALIZED: Smart Chute",
 	"block.create.smart_fluid_pipe": "Умная жидкостная труба",
 	"block.create.speedometer": "Спидометр",
 	"block.create.spout": "Слив",
@@ -681,7 +682,6 @@
 	"create.recipe.mechanical_crafting": "Механическое создание",
 	"create.recipe.automatic_shaped": "Автоматическая форменная сборка",
 	"create.recipe.block_cutting": "Резка блока",
-	"create.recipe.wood_cutting": "UNLOCALIZED: Wood Cutting",
 	"create.recipe.blockzapper_upgrade": "Ручная блоковая пушка",
 	"create.recipe.sandpaper_polishing": "Полировка наждачной бумагой",
 	"create.recipe.mystery_conversion": "Хроматический метаморфоз",
@@ -1083,6 +1083,7 @@
 	"create.tooltip.chute.fans_push_down": "Вентилятор толкает сверху",
 	"create.tooltip.chute.fans_pull_up": "Вентилятор тянет сверху",
 	"create.tooltip.chute.fans_pull_down": "Вентилятор тянет снизу",
+	"create.tooltip.chute.contains": "UNLOCALIZED: Contains: %1$s x%2$s",
 
 	"create.hint.hose_pulley.title": "Безграничное снабжение",
 	"create.hint.hose_pulley": "Целевой водный резервуар считается бесконечным.",
diff --git a/src/generated/resources/assets/create/lang/unfinished/zh_cn.json b/src/generated/resources/assets/create/lang/unfinished/zh_cn.json
index dcba9794b7..783cb9fb2d 100644
--- a/src/generated/resources/assets/create/lang/unfinished/zh_cn.json
+++ b/src/generated/resources/assets/create/lang/unfinished/zh_cn.json
@@ -1,5 +1,5 @@
 {
-	"_": "Missing Localizations: 4",
+	"_": "Missing Localizations: 5",
 
 	"_": "->------------------------]  Game Elements  [------------------------<-",
 
@@ -368,6 +368,7 @@
 	"block.create.sequenced_gearshift": "可编程齿轮箱",
 	"block.create.shadow_steel_casing": "暗影机壳",
 	"block.create.shaft": "传动杆",
+	"block.create.smart_chute": "UNLOCALIZED: Smart Chute",
 	"block.create.smart_fluid_pipe": "智能流体管道",
 	"block.create.speedometer": "速度表",
 	"block.create.spout": "注液器",
@@ -681,7 +682,6 @@
 	"create.recipe.mechanical_crafting": "自动合成",
 	"create.recipe.automatic_shaped": "自动合成",
 	"create.recipe.block_cutting": "方块切割",
-	"create.recipe.wood_cutting": "UNLOCALIZED: Wood Cutting",
 	"create.recipe.blockzapper_upgrade": "手持式方块放置器",
 	"create.recipe.sandpaper_polishing": "砂纸打磨",
 	"create.recipe.mystery_conversion": "神秘转化",
@@ -1083,6 +1083,7 @@
 	"create.tooltip.chute.fans_push_down": "鼓风机从上方进行推动",
 	"create.tooltip.chute.fans_pull_up": "鼓风机从下方进行吸引",
 	"create.tooltip.chute.fans_pull_down": "鼓风机从上方进行吸引",
+	"create.tooltip.chute.contains": "UNLOCALIZED: Contains: %1$s x%2$s",
 
 	"create.hint.hose_pulley.title": "UNLOCALIZED: Bottomless Supply",
 	"create.hint.hose_pulley": "UNLOCALIZED: The targeted body of fluid is considered infinite.",
diff --git a/src/generated/resources/assets/create/models/block/andesite_funnel.json b/src/generated/resources/assets/create/models/block/andesite_funnel.json
deleted file mode 100644
index 1161539b16..0000000000
--- a/src/generated/resources/assets/create/models/block/andesite_funnel.json
+++ /dev/null
@@ -1,9 +0,0 @@
-{
-  "parent": "create:block/funnel/block",
-  "textures": {
-    "0": "create:block/andesite_funnel_plating",
-    "1": "create:block/andesite_casing",
-    "2": "create:block/andesite_funnel",
-    "3": "create:block/andesite_funnel_back"
-  }
-}
\ No newline at end of file
diff --git a/src/generated/resources/assets/create/models/block/andesite_funnel_ceiling_pull.json b/src/generated/resources/assets/create/models/block/andesite_funnel_ceiling_pull.json
new file mode 100644
index 0000000000..bdbb2623f9
--- /dev/null
+++ b/src/generated/resources/assets/create/models/block/andesite_funnel_ceiling_pull.json
@@ -0,0 +1,11 @@
+{
+  "parent": "create:block/funnel/block_ceiling",
+  "textures": {
+    "particle": "create:block/andesite_casing",
+    "7": "create:block/andesite_funnel_plating",
+    "6": "create:block/andesite_funnel",
+    "5": "create:block/andesite_funnel_tall",
+    "2_2": "create:block/andesite_funnel_pull",
+    "3": "create:block/andesite_funnel_back"
+  }
+}
\ No newline at end of file
diff --git a/src/generated/resources/assets/create/models/block/andesite_funnel_ceiling_pull_powered.json b/src/generated/resources/assets/create/models/block/andesite_funnel_ceiling_pull_powered.json
new file mode 100644
index 0000000000..f66c6e8f32
--- /dev/null
+++ b/src/generated/resources/assets/create/models/block/andesite_funnel_ceiling_pull_powered.json
@@ -0,0 +1,11 @@
+{
+  "parent": "create:block/funnel/block_ceiling",
+  "textures": {
+    "particle": "create:block/andesite_casing",
+    "7": "create:block/andesite_funnel_plating",
+    "6": "create:block/andesite_funnel_powered",
+    "5": "create:block/andesite_funnel_tall_powered",
+    "2_2": "create:block/andesite_funnel_pull",
+    "3": "create:block/andesite_funnel_back"
+  }
+}
\ No newline at end of file
diff --git a/src/generated/resources/assets/create/models/block/andesite_funnel_ceiling_push.json b/src/generated/resources/assets/create/models/block/andesite_funnel_ceiling_push.json
new file mode 100644
index 0000000000..8217c6b7ae
--- /dev/null
+++ b/src/generated/resources/assets/create/models/block/andesite_funnel_ceiling_push.json
@@ -0,0 +1,11 @@
+{
+  "parent": "create:block/funnel/block_ceiling",
+  "textures": {
+    "particle": "create:block/andesite_casing",
+    "7": "create:block/andesite_funnel_plating",
+    "6": "create:block/andesite_funnel",
+    "5": "create:block/andesite_funnel_tall",
+    "2_2": "create:block/andesite_funnel_push",
+    "3": "create:block/andesite_funnel_back"
+  }
+}
\ No newline at end of file
diff --git a/src/generated/resources/assets/create/models/block/andesite_funnel_ceiling_push_powered.json b/src/generated/resources/assets/create/models/block/andesite_funnel_ceiling_push_powered.json
new file mode 100644
index 0000000000..ff4df04939
--- /dev/null
+++ b/src/generated/resources/assets/create/models/block/andesite_funnel_ceiling_push_powered.json
@@ -0,0 +1,11 @@
+{
+  "parent": "create:block/funnel/block_ceiling",
+  "textures": {
+    "particle": "create:block/andesite_casing",
+    "7": "create:block/andesite_funnel_plating",
+    "6": "create:block/andesite_funnel_powered",
+    "5": "create:block/andesite_funnel_tall_powered",
+    "2_2": "create:block/andesite_funnel_push",
+    "3": "create:block/andesite_funnel_back"
+  }
+}
\ No newline at end of file
diff --git a/src/generated/resources/assets/create/models/block/andesite_funnel_floor_pull.json b/src/generated/resources/assets/create/models/block/andesite_funnel_floor_pull.json
new file mode 100644
index 0000000000..6079531b30
--- /dev/null
+++ b/src/generated/resources/assets/create/models/block/andesite_funnel_floor_pull.json
@@ -0,0 +1,11 @@
+{
+  "parent": "create:block/funnel/block_floor",
+  "textures": {
+    "particle": "create:block/andesite_casing",
+    "7": "create:block/andesite_funnel_plating",
+    "6": "create:block/andesite_funnel",
+    "5": "create:block/andesite_funnel_tall",
+    "2_2": "create:block/andesite_funnel_pull",
+    "3": "create:block/andesite_funnel_back"
+  }
+}
\ No newline at end of file
diff --git a/src/generated/resources/assets/create/models/block/andesite_funnel_floor_pull_powered.json b/src/generated/resources/assets/create/models/block/andesite_funnel_floor_pull_powered.json
new file mode 100644
index 0000000000..5ac3f88c71
--- /dev/null
+++ b/src/generated/resources/assets/create/models/block/andesite_funnel_floor_pull_powered.json
@@ -0,0 +1,11 @@
+{
+  "parent": "create:block/funnel/block_floor",
+  "textures": {
+    "particle": "create:block/andesite_casing",
+    "7": "create:block/andesite_funnel_plating",
+    "6": "create:block/andesite_funnel_powered",
+    "5": "create:block/andesite_funnel_tall_powered",
+    "2_2": "create:block/andesite_funnel_pull",
+    "3": "create:block/andesite_funnel_back"
+  }
+}
\ No newline at end of file
diff --git a/src/generated/resources/assets/create/models/block/andesite_funnel_floor_push.json b/src/generated/resources/assets/create/models/block/andesite_funnel_floor_push.json
new file mode 100644
index 0000000000..21b19aa78e
--- /dev/null
+++ b/src/generated/resources/assets/create/models/block/andesite_funnel_floor_push.json
@@ -0,0 +1,11 @@
+{
+  "parent": "create:block/funnel/block_floor",
+  "textures": {
+    "particle": "create:block/andesite_casing",
+    "7": "create:block/andesite_funnel_plating",
+    "6": "create:block/andesite_funnel",
+    "5": "create:block/andesite_funnel_tall",
+    "2_2": "create:block/andesite_funnel_push",
+    "3": "create:block/andesite_funnel_back"
+  }
+}
\ No newline at end of file
diff --git a/src/generated/resources/assets/create/models/block/andesite_funnel_floor_push_powered.json b/src/generated/resources/assets/create/models/block/andesite_funnel_floor_push_powered.json
new file mode 100644
index 0000000000..8a8f6a8def
--- /dev/null
+++ b/src/generated/resources/assets/create/models/block/andesite_funnel_floor_push_powered.json
@@ -0,0 +1,11 @@
+{
+  "parent": "create:block/funnel/block_floor",
+  "textures": {
+    "particle": "create:block/andesite_casing",
+    "7": "create:block/andesite_funnel_plating",
+    "6": "create:block/andesite_funnel_powered",
+    "5": "create:block/andesite_funnel_tall_powered",
+    "2_2": "create:block/andesite_funnel_push",
+    "3": "create:block/andesite_funnel_back"
+  }
+}
\ No newline at end of file
diff --git a/src/generated/resources/assets/create/models/block/andesite_funnel_powered.json b/src/generated/resources/assets/create/models/block/andesite_funnel_powered.json
deleted file mode 100644
index a2a4517159..0000000000
--- a/src/generated/resources/assets/create/models/block/andesite_funnel_powered.json
+++ /dev/null
@@ -1,9 +0,0 @@
-{
-  "parent": "create:block/funnel/block",
-  "textures": {
-    "0": "create:block/andesite_funnel_plating",
-    "1": "create:block/andesite_casing",
-    "2": "create:block/andesite_funnel_powered",
-    "3": "create:block/andesite_funnel_back"
-  }
-}
\ No newline at end of file
diff --git a/src/generated/resources/assets/create/models/block/andesite_funnel_wall_pull.json b/src/generated/resources/assets/create/models/block/andesite_funnel_wall_pull.json
new file mode 100644
index 0000000000..e8343d6823
--- /dev/null
+++ b/src/generated/resources/assets/create/models/block/andesite_funnel_wall_pull.json
@@ -0,0 +1,11 @@
+{
+  "parent": "create:block/funnel/block_wall",
+  "textures": {
+    "particle": "create:block/andesite_casing",
+    "7": "create:block/andesite_funnel_plating",
+    "6": "create:block/andesite_funnel",
+    "5": "create:block/andesite_funnel_tall",
+    "2_2": "create:block/andesite_funnel_pull",
+    "3": "create:block/andesite_funnel_back"
+  }
+}
\ No newline at end of file
diff --git a/src/generated/resources/assets/create/models/block/andesite_funnel_wall_pull_powered.json b/src/generated/resources/assets/create/models/block/andesite_funnel_wall_pull_powered.json
new file mode 100644
index 0000000000..e71c4c17c2
--- /dev/null
+++ b/src/generated/resources/assets/create/models/block/andesite_funnel_wall_pull_powered.json
@@ -0,0 +1,11 @@
+{
+  "parent": "create:block/funnel/block_wall",
+  "textures": {
+    "particle": "create:block/andesite_casing",
+    "7": "create:block/andesite_funnel_plating",
+    "6": "create:block/andesite_funnel_powered",
+    "5": "create:block/andesite_funnel_tall_powered",
+    "2_2": "create:block/andesite_funnel_pull",
+    "3": "create:block/andesite_funnel_back"
+  }
+}
\ No newline at end of file
diff --git a/src/generated/resources/assets/create/models/block/andesite_funnel_wall_push.json b/src/generated/resources/assets/create/models/block/andesite_funnel_wall_push.json
new file mode 100644
index 0000000000..4b56f936a4
--- /dev/null
+++ b/src/generated/resources/assets/create/models/block/andesite_funnel_wall_push.json
@@ -0,0 +1,11 @@
+{
+  "parent": "create:block/funnel/block_wall",
+  "textures": {
+    "particle": "create:block/andesite_casing",
+    "7": "create:block/andesite_funnel_plating",
+    "6": "create:block/andesite_funnel",
+    "5": "create:block/andesite_funnel_tall",
+    "2_2": "create:block/andesite_funnel_push",
+    "3": "create:block/andesite_funnel_back"
+  }
+}
\ No newline at end of file
diff --git a/src/generated/resources/assets/create/models/block/andesite_funnel_wall_push_powered.json b/src/generated/resources/assets/create/models/block/andesite_funnel_wall_push_powered.json
new file mode 100644
index 0000000000..b9f6af0dcc
--- /dev/null
+++ b/src/generated/resources/assets/create/models/block/andesite_funnel_wall_push_powered.json
@@ -0,0 +1,11 @@
+{
+  "parent": "create:block/funnel/block_wall",
+  "textures": {
+    "particle": "create:block/andesite_casing",
+    "7": "create:block/andesite_funnel_plating",
+    "6": "create:block/andesite_funnel_powered",
+    "5": "create:block/andesite_funnel_tall_powered",
+    "2_2": "create:block/andesite_funnel_push",
+    "3": "create:block/andesite_funnel_back"
+  }
+}
\ No newline at end of file
diff --git a/src/generated/resources/assets/create/models/block/brass_funnel.json b/src/generated/resources/assets/create/models/block/brass_funnel.json
deleted file mode 100644
index 82a6b28f3b..0000000000
--- a/src/generated/resources/assets/create/models/block/brass_funnel.json
+++ /dev/null
@@ -1,9 +0,0 @@
-{
-  "parent": "create:block/funnel/block",
-  "textures": {
-    "0": "create:block/brass_funnel_plating",
-    "1": "create:block/brass_casing",
-    "2": "create:block/brass_funnel",
-    "3": "create:block/brass_funnel_back"
-  }
-}
\ No newline at end of file
diff --git a/src/generated/resources/assets/create/models/block/brass_funnel_ceiling_pull.json b/src/generated/resources/assets/create/models/block/brass_funnel_ceiling_pull.json
new file mode 100644
index 0000000000..04fb853baf
--- /dev/null
+++ b/src/generated/resources/assets/create/models/block/brass_funnel_ceiling_pull.json
@@ -0,0 +1,11 @@
+{
+  "parent": "create:block/funnel/block_ceiling",
+  "textures": {
+    "particle": "create:block/brass_casing",
+    "7": "create:block/brass_funnel_plating",
+    "6": "create:block/brass_funnel",
+    "5": "create:block/brass_funnel_tall",
+    "2_2": "create:block/brass_funnel_pull",
+    "3": "create:block/brass_funnel_back"
+  }
+}
\ No newline at end of file
diff --git a/src/generated/resources/assets/create/models/block/brass_funnel_ceiling_pull_powered.json b/src/generated/resources/assets/create/models/block/brass_funnel_ceiling_pull_powered.json
new file mode 100644
index 0000000000..4a0c7c1d26
--- /dev/null
+++ b/src/generated/resources/assets/create/models/block/brass_funnel_ceiling_pull_powered.json
@@ -0,0 +1,11 @@
+{
+  "parent": "create:block/funnel/block_ceiling",
+  "textures": {
+    "particle": "create:block/brass_casing",
+    "7": "create:block/brass_funnel_plating",
+    "6": "create:block/brass_funnel_powered",
+    "5": "create:block/brass_funnel_tall_powered",
+    "2_2": "create:block/brass_funnel_pull",
+    "3": "create:block/brass_funnel_back"
+  }
+}
\ No newline at end of file
diff --git a/src/generated/resources/assets/create/models/block/brass_funnel_ceiling_push.json b/src/generated/resources/assets/create/models/block/brass_funnel_ceiling_push.json
new file mode 100644
index 0000000000..c1595bbd83
--- /dev/null
+++ b/src/generated/resources/assets/create/models/block/brass_funnel_ceiling_push.json
@@ -0,0 +1,11 @@
+{
+  "parent": "create:block/funnel/block_ceiling",
+  "textures": {
+    "particle": "create:block/brass_casing",
+    "7": "create:block/brass_funnel_plating",
+    "6": "create:block/brass_funnel",
+    "5": "create:block/brass_funnel_tall",
+    "2_2": "create:block/brass_funnel_push",
+    "3": "create:block/brass_funnel_back"
+  }
+}
\ No newline at end of file
diff --git a/src/generated/resources/assets/create/models/block/brass_funnel_ceiling_push_powered.json b/src/generated/resources/assets/create/models/block/brass_funnel_ceiling_push_powered.json
new file mode 100644
index 0000000000..e4b8a8e160
--- /dev/null
+++ b/src/generated/resources/assets/create/models/block/brass_funnel_ceiling_push_powered.json
@@ -0,0 +1,11 @@
+{
+  "parent": "create:block/funnel/block_ceiling",
+  "textures": {
+    "particle": "create:block/brass_casing",
+    "7": "create:block/brass_funnel_plating",
+    "6": "create:block/brass_funnel_powered",
+    "5": "create:block/brass_funnel_tall_powered",
+    "2_2": "create:block/brass_funnel_push",
+    "3": "create:block/brass_funnel_back"
+  }
+}
\ No newline at end of file
diff --git a/src/generated/resources/assets/create/models/block/brass_funnel_floor_pull.json b/src/generated/resources/assets/create/models/block/brass_funnel_floor_pull.json
new file mode 100644
index 0000000000..02c4f87439
--- /dev/null
+++ b/src/generated/resources/assets/create/models/block/brass_funnel_floor_pull.json
@@ -0,0 +1,11 @@
+{
+  "parent": "create:block/funnel/block_floor",
+  "textures": {
+    "particle": "create:block/brass_casing",
+    "7": "create:block/brass_funnel_plating",
+    "6": "create:block/brass_funnel",
+    "5": "create:block/brass_funnel_tall",
+    "2_2": "create:block/brass_funnel_pull",
+    "3": "create:block/brass_funnel_back"
+  }
+}
\ No newline at end of file
diff --git a/src/generated/resources/assets/create/models/block/brass_funnel_floor_pull_powered.json b/src/generated/resources/assets/create/models/block/brass_funnel_floor_pull_powered.json
new file mode 100644
index 0000000000..c16f1f997c
--- /dev/null
+++ b/src/generated/resources/assets/create/models/block/brass_funnel_floor_pull_powered.json
@@ -0,0 +1,11 @@
+{
+  "parent": "create:block/funnel/block_floor",
+  "textures": {
+    "particle": "create:block/brass_casing",
+    "7": "create:block/brass_funnel_plating",
+    "6": "create:block/brass_funnel_powered",
+    "5": "create:block/brass_funnel_tall_powered",
+    "2_2": "create:block/brass_funnel_pull",
+    "3": "create:block/brass_funnel_back"
+  }
+}
\ No newline at end of file
diff --git a/src/generated/resources/assets/create/models/block/brass_funnel_floor_push.json b/src/generated/resources/assets/create/models/block/brass_funnel_floor_push.json
new file mode 100644
index 0000000000..642f3480b3
--- /dev/null
+++ b/src/generated/resources/assets/create/models/block/brass_funnel_floor_push.json
@@ -0,0 +1,11 @@
+{
+  "parent": "create:block/funnel/block_floor",
+  "textures": {
+    "particle": "create:block/brass_casing",
+    "7": "create:block/brass_funnel_plating",
+    "6": "create:block/brass_funnel",
+    "5": "create:block/brass_funnel_tall",
+    "2_2": "create:block/brass_funnel_push",
+    "3": "create:block/brass_funnel_back"
+  }
+}
\ No newline at end of file
diff --git a/src/generated/resources/assets/create/models/block/brass_funnel_floor_push_powered.json b/src/generated/resources/assets/create/models/block/brass_funnel_floor_push_powered.json
new file mode 100644
index 0000000000..1e1c451486
--- /dev/null
+++ b/src/generated/resources/assets/create/models/block/brass_funnel_floor_push_powered.json
@@ -0,0 +1,11 @@
+{
+  "parent": "create:block/funnel/block_floor",
+  "textures": {
+    "particle": "create:block/brass_casing",
+    "7": "create:block/brass_funnel_plating",
+    "6": "create:block/brass_funnel_powered",
+    "5": "create:block/brass_funnel_tall_powered",
+    "2_2": "create:block/brass_funnel_push",
+    "3": "create:block/brass_funnel_back"
+  }
+}
\ No newline at end of file
diff --git a/src/generated/resources/assets/create/models/block/brass_funnel_powered.json b/src/generated/resources/assets/create/models/block/brass_funnel_powered.json
deleted file mode 100644
index 6085c2466d..0000000000
--- a/src/generated/resources/assets/create/models/block/brass_funnel_powered.json
+++ /dev/null
@@ -1,9 +0,0 @@
-{
-  "parent": "create:block/funnel/block",
-  "textures": {
-    "0": "create:block/brass_funnel_plating",
-    "1": "create:block/brass_casing",
-    "2": "create:block/brass_funnel_powered",
-    "3": "create:block/brass_funnel_back"
-  }
-}
\ No newline at end of file
diff --git a/src/generated/resources/assets/create/models/block/brass_funnel_wall_pull.json b/src/generated/resources/assets/create/models/block/brass_funnel_wall_pull.json
new file mode 100644
index 0000000000..9b0bae0f10
--- /dev/null
+++ b/src/generated/resources/assets/create/models/block/brass_funnel_wall_pull.json
@@ -0,0 +1,11 @@
+{
+  "parent": "create:block/funnel/block_wall",
+  "textures": {
+    "particle": "create:block/brass_casing",
+    "7": "create:block/brass_funnel_plating",
+    "6": "create:block/brass_funnel",
+    "5": "create:block/brass_funnel_tall",
+    "2_2": "create:block/brass_funnel_pull",
+    "3": "create:block/brass_funnel_back"
+  }
+}
\ No newline at end of file
diff --git a/src/generated/resources/assets/create/models/block/brass_funnel_wall_pull_powered.json b/src/generated/resources/assets/create/models/block/brass_funnel_wall_pull_powered.json
new file mode 100644
index 0000000000..03dc68716a
--- /dev/null
+++ b/src/generated/resources/assets/create/models/block/brass_funnel_wall_pull_powered.json
@@ -0,0 +1,11 @@
+{
+  "parent": "create:block/funnel/block_wall",
+  "textures": {
+    "particle": "create:block/brass_casing",
+    "7": "create:block/brass_funnel_plating",
+    "6": "create:block/brass_funnel_powered",
+    "5": "create:block/brass_funnel_tall_powered",
+    "2_2": "create:block/brass_funnel_pull",
+    "3": "create:block/brass_funnel_back"
+  }
+}
\ No newline at end of file
diff --git a/src/generated/resources/assets/create/models/block/brass_funnel_wall_push.json b/src/generated/resources/assets/create/models/block/brass_funnel_wall_push.json
new file mode 100644
index 0000000000..f2f3bd1585
--- /dev/null
+++ b/src/generated/resources/assets/create/models/block/brass_funnel_wall_push.json
@@ -0,0 +1,11 @@
+{
+  "parent": "create:block/funnel/block_wall",
+  "textures": {
+    "particle": "create:block/brass_casing",
+    "7": "create:block/brass_funnel_plating",
+    "6": "create:block/brass_funnel",
+    "5": "create:block/brass_funnel_tall",
+    "2_2": "create:block/brass_funnel_push",
+    "3": "create:block/brass_funnel_back"
+  }
+}
\ No newline at end of file
diff --git a/src/generated/resources/assets/create/models/block/brass_funnel_wall_push_powered.json b/src/generated/resources/assets/create/models/block/brass_funnel_wall_push_powered.json
new file mode 100644
index 0000000000..1a27b7333a
--- /dev/null
+++ b/src/generated/resources/assets/create/models/block/brass_funnel_wall_push_powered.json
@@ -0,0 +1,11 @@
+{
+  "parent": "create:block/funnel/block_wall",
+  "textures": {
+    "particle": "create:block/brass_casing",
+    "7": "create:block/brass_funnel_plating",
+    "6": "create:block/brass_funnel_powered",
+    "5": "create:block/brass_funnel_tall_powered",
+    "2_2": "create:block/brass_funnel_push",
+    "3": "create:block/brass_funnel_back"
+  }
+}
\ No newline at end of file
diff --git a/src/generated/resources/assets/create/models/item/andesite_funnel.json b/src/generated/resources/assets/create/models/item/andesite_funnel.json
index f0e8e84813..6cb095db37 100644
--- a/src/generated/resources/assets/create/models/item/andesite_funnel.json
+++ b/src/generated/resources/assets/create/models/item/andesite_funnel.json
@@ -1,9 +1,11 @@
 {
   "parent": "create:block/funnel/item",
   "textures": {
-    "0": "create:block/andesite_funnel_plating",
-    "1": "create:block/andesite_casing",
-    "2": "create:block/andesite_funnel",
+    "particle": "create:block/andesite_casing",
+    "7": "create:block/andesite_funnel_plating",
+    "2": "create:block/andesite_funnel_neutral",
+    "6": "create:block/andesite_funnel",
+    "5": "create:block/andesite_funnel_tall",
     "3": "create:block/andesite_funnel_back"
   }
 }
\ No newline at end of file
diff --git a/src/generated/resources/assets/create/models/item/brass_funnel.json b/src/generated/resources/assets/create/models/item/brass_funnel.json
index 82e8d4035c..5a1542acb7 100644
--- a/src/generated/resources/assets/create/models/item/brass_funnel.json
+++ b/src/generated/resources/assets/create/models/item/brass_funnel.json
@@ -1,9 +1,11 @@
 {
   "parent": "create:block/funnel/item",
   "textures": {
-    "0": "create:block/brass_funnel_plating",
-    "1": "create:block/brass_casing",
-    "2": "create:block/brass_funnel",
+    "particle": "create:block/brass_casing",
+    "7": "create:block/brass_funnel_plating",
+    "2": "create:block/brass_funnel_neutral",
+    "6": "create:block/brass_funnel",
+    "5": "create:block/brass_funnel_tall",
     "3": "create:block/brass_funnel_back"
   }
 }
\ No newline at end of file
diff --git a/src/generated/resources/assets/create/models/item/smart_chute.json b/src/generated/resources/assets/create/models/item/smart_chute.json
new file mode 100644
index 0000000000..c0a19c1e09
--- /dev/null
+++ b/src/generated/resources/assets/create/models/item/smart_chute.json
@@ -0,0 +1,3 @@
+{
+  "parent": "create:block/smart_chute/block"
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/create/advancements/recipes/create.base/crafting/kinetics/smart_chute.json b/src/generated/resources/data/create/advancements/recipes/create.base/crafting/kinetics/smart_chute.json
new file mode 100644
index 0000000000..1f12438333
--- /dev/null
+++ b/src/generated/resources/data/create/advancements/recipes/create.base/crafting/kinetics/smart_chute.json
@@ -0,0 +1,32 @@
+{
+  "parent": "minecraft:recipes/root",
+  "rewards": {
+    "recipes": [
+      "create:crafting/kinetics/smart_chute"
+    ]
+  },
+  "criteria": {
+    "has_item": {
+      "trigger": "minecraft:inventory_changed",
+      "conditions": {
+        "items": [
+          {
+            "item": "create:chute"
+          }
+        ]
+      }
+    },
+    "has_the_recipe": {
+      "trigger": "minecraft:recipe_unlocked",
+      "conditions": {
+        "recipe": "create:crafting/kinetics/smart_chute"
+      }
+    }
+  },
+  "requirements": [
+    [
+      "has_item",
+      "has_the_recipe"
+    ]
+  ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/create/loot_tables/blocks/smart_chute.json b/src/generated/resources/data/create/loot_tables/blocks/smart_chute.json
new file mode 100644
index 0000000000..f3e3c62ea8
--- /dev/null
+++ b/src/generated/resources/data/create/loot_tables/blocks/smart_chute.json
@@ -0,0 +1,19 @@
+{
+  "type": "minecraft:block",
+  "pools": [
+    {
+      "rolls": 1,
+      "entries": [
+        {
+          "type": "minecraft:item",
+          "name": "create:smart_chute"
+        }
+      ],
+      "conditions": [
+        {
+          "condition": "minecraft:survives_explosion"
+        }
+      ]
+    }
+  ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/create/recipes/crafting/kinetics/smart_chute.json b/src/generated/resources/data/create/recipes/crafting/kinetics/smart_chute.json
new file mode 100644
index 0000000000..8ce8d11795
--- /dev/null
+++ b/src/generated/resources/data/create/recipes/crafting/kinetics/smart_chute.json
@@ -0,0 +1,22 @@
+{
+  "type": "minecraft:crafting_shaped",
+  "pattern": [
+    "I",
+    "S",
+    "P"
+  ],
+  "key": {
+    "P": {
+      "item": "create:electron_tube"
+    },
+    "S": {
+      "item": "create:chute"
+    },
+    "I": {
+      "tag": "forge:plates/brass"
+    }
+  },
+  "result": {
+    "item": "create:smart_chute"
+  }
+}
\ No newline at end of file
diff --git a/src/main/java/com/simibubi/create/AllBlockPartials.java b/src/main/java/com/simibubi/create/AllBlockPartials.java
index ddb43ea202..ebc1b33895 100644
--- a/src/main/java/com/simibubi/create/AllBlockPartials.java
+++ b/src/main/java/com/simibubi/create/AllBlockPartials.java
@@ -58,7 +58,8 @@ public class AllBlockPartials {
 		HARVESTER_BLADE = get("mechanical_harvester/blade"), DEPLOYER_POLE = get("deployer/pole"),
 		DEPLOYER_HAND_POINTING = get("deployer/hand_pointing"), DEPLOYER_HAND_PUNCHING = get("deployer/hand_punching"),
 		DEPLOYER_HAND_HOLDING = get("deployer/hand_holding"), ANALOG_LEVER_HANDLE = get("analog_lever/handle"),
-		ANALOG_LEVER_INDICATOR = get("analog_lever/indicator"), BELT_FUNNEL_FLAP = get("belt_funnel/flap"),
+		ANALOG_LEVER_INDICATOR = get("analog_lever/indicator"), FUNNEL_FLAP = get("funnel/flap"), 
+		BELT_FUNNEL_FLAP = get("belt_funnel/flap"),
 		BELT_TUNNEL_FLAP = get("belt_tunnel/flap"), FLEXPEATER_INDICATOR = get("diodes/indicator"),
 		FLYWHEEL = get("flywheel/wheel"), FLYWHEEL_UPPER_ROTATING = get("flywheel/upper_rotating_connector"),
 
diff --git a/src/main/java/com/simibubi/create/AllBlocks.java b/src/main/java/com/simibubi/create/AllBlocks.java
index 561fff1832..c254513c02 100644
--- a/src/main/java/com/simibubi/create/AllBlocks.java
+++ b/src/main/java/com/simibubi/create/AllBlocks.java
@@ -117,6 +117,7 @@ import com.simibubi.create.content.logistics.block.belts.tunnel.BrassTunnelCTBeh
 import com.simibubi.create.content.logistics.block.chute.ChuteBlock;
 import com.simibubi.create.content.logistics.block.chute.ChuteGenerator;
 import com.simibubi.create.content.logistics.block.chute.ChuteItem;
+import com.simibubi.create.content.logistics.block.chute.SmartChuteBlock;
 import com.simibubi.create.content.logistics.block.depot.DepotBlock;
 import com.simibubi.create.content.logistics.block.diodes.AbstractDiodeGenerator;
 import com.simibubi.create.content.logistics.block.diodes.AdjustableRepeaterBlock;
@@ -127,10 +128,9 @@ import com.simibubi.create.content.logistics.block.diodes.PulseRepeaterBlock;
 import com.simibubi.create.content.logistics.block.diodes.PulseRepeaterGenerator;
 import com.simibubi.create.content.logistics.block.diodes.ToggleLatchBlock;
 import com.simibubi.create.content.logistics.block.diodes.ToggleLatchGenerator;
-import com.simibubi.create.content.logistics.block.funnel.AndesiteBeltFunnelBlock;
 import com.simibubi.create.content.logistics.block.funnel.AndesiteFunnelBlock;
+import com.simibubi.create.content.logistics.block.funnel.BeltFunnelBlock;
 import com.simibubi.create.content.logistics.block.funnel.BeltFunnelGenerator;
-import com.simibubi.create.content.logistics.block.funnel.BrassBeltFunnelBlock;
 import com.simibubi.create.content.logistics.block.funnel.BrassFunnelBlock;
 import com.simibubi.create.content.logistics.block.funnel.FunnelMovementBehaviour;
 import com.simibubi.create.content.logistics.block.inventories.AdjustableCrateBlock;
@@ -298,7 +298,8 @@ public class AllBlocks {
 			.blockstate((c, p) -> new EncasedBeltGenerator((state, suffix) -> {
 				String powered = state.get(AdjustablePulleyBlock.POWERED) ? "_powered" : "";
 				return p.models()
-					.withExistingParent(c.getName() + "_" + suffix + powered, p.modLoc("block/encased_chain_drive/" + suffix))
+					.withExistingParent(c.getName() + "_" + suffix + powered,
+						p.modLoc("block/encased_chain_drive/" + suffix))
 					.texture("side", p.modLoc("block/" + c.getName() + powered));
 			}).generate(c, p))
 			.item()
@@ -479,6 +480,13 @@ public class AllBlocks {
 		.transform(customItemModel("_", "block"))
 		.register();
 
+	public static final BlockEntry<SmartChuteBlock> SMART_CHUTE = REGISTRATE.block("smart_chute", SmartChuteBlock::new)
+		.initialProperties(SharedProperties::softMetal)
+		.blockstate((c, p) -> BlockStateGen.simpleBlock(c, p, AssetLookup.forPowered(c, p)))
+		.item()
+		.transform(customItemModel("_", "block"))
+		.register();
+
 	public static final BlockEntry<GaugeBlock> SPEEDOMETER = REGISTRATE.block("speedometer", GaugeBlock::speed)
 		.initialProperties(SharedProperties::wooden)
 		.transform(StressConfigDefaults.setNoImpact())
@@ -1042,8 +1050,8 @@ public class AllBlocks {
 			.transform(BuilderTransformers.funnel("andesite", Create.asResource("block/andesite_casing")))
 			.register();
 
-	public static final BlockEntry<AndesiteBeltFunnelBlock> ANDESITE_BELT_FUNNEL =
-		REGISTRATE.block("andesite_belt_funnel", AndesiteBeltFunnelBlock::new)
+	public static final BlockEntry<BeltFunnelBlock> ANDESITE_BELT_FUNNEL =
+		REGISTRATE.block("andesite_belt_funnel", p -> new BeltFunnelBlock(AllBlocks.ANDESITE_FUNNEL, p))
 			.initialProperties(SharedProperties::stone)
 			.tag(AllBlockTags.SAFE_NBT.tag)
 			.blockstate(new BeltFunnelGenerator("andesite", new ResourceLocation("block/polished_andesite"))::generate)
@@ -1058,8 +1066,8 @@ public class AllBlocks {
 			.transform(BuilderTransformers.funnel("brass", Create.asResource("block/brass_casing")))
 			.register();
 
-	public static final BlockEntry<BrassBeltFunnelBlock> BRASS_BELT_FUNNEL =
-		REGISTRATE.block("brass_belt_funnel", BrassBeltFunnelBlock::new)
+	public static final BlockEntry<BeltFunnelBlock> BRASS_BELT_FUNNEL =
+		REGISTRATE.block("brass_belt_funnel", p -> new BeltFunnelBlock(AllBlocks.BRASS_FUNNEL, p))
 			.initialProperties(SharedProperties::softMetal)
 			.tag(AllBlockTags.SAFE_NBT.tag)
 			.blockstate(new BeltFunnelGenerator("brass", Create.asResource("block/brass_block"))::generate)
diff --git a/src/main/java/com/simibubi/create/AllShapes.java b/src/main/java/com/simibubi/create/AllShapes.java
index be8672704c..ee77c574d5 100644
--- a/src/main/java/com/simibubi/create/AllShapes.java
+++ b/src/main/java/com/simibubi/create/AllShapes.java
@@ -68,34 +68,26 @@ public class AllShapes {
 		NIXIE_TUBE_CEILING = shape(0, 12, 0, 16, 16, 16).add(9, 1, 5, 15, 16, 11)
 			.add(1, 1, 5, 7, 16, 11)
 			.forHorizontalAxis(),
-		FUNNEL = shape(2, -2, 2, 14, 2, 14).add(3, 2, 3, 13, 6, 13)
-			.add(2, 6, 2, 14, 10, 14)
-			.add(0, 10, 0, 16, 16, 16)
-			.forDirectional(UP),
-		FUNNEL_COLLISION = shape(2, -2, 2, 14, 2, 14).add(3, 2, 3, 13, 6, 13)
-			.add(2, 6, 2, 14, 10, 14)
-			.add(0, 10, 0, 16, 13, 16)
-			.forDirectional(UP),
+		FUNNEL_COLLISION = shape(0, 0, 0, 16, 4, 16).forDirectional(UP),
 		BELT_FUNNEL_RETRACTED = shape(2, -2, 14, 14, 14, 18).add(0, -5, 8, 16, 16, 14)
 			.forHorizontal(NORTH),
 		BELT_FUNNEL_EXTENDED = shape(2, -2, 14, 14, 14, 18).add(3, -4, 10, 13, 13, 14)
 			.add(2, -4, 6, 14, 14, 10)
 			.add(0, -5, 0, 16, 16, 6)
 			.forHorizontal(NORTH),
-		BELT_FUNNEL_PERPENDICULAR = 
-			shape(2, -2, 14, 14, 14, 18)
-			.add(1, 8, 12, 15, 15, 14)
+		BELT_FUNNEL_PERPENDICULAR = shape(2, -2, 14, 14, 14, 18).add(1, 8, 12, 15, 15, 14)
 			.add(0.1, 13, 7, 15.9, 15, 11)
 			.add(0.1, 9, 8, 15.9, 13, 12)
 			.add(0.1, 5, 9, 15.9, 9, 13)
 			.add(0.1, 1, 10, 15.9, 5, 14)
 			.add(0.1, -3, 11, 15.9, 1, 15)
 			.forHorizontal(NORTH),
-		BELT_FUNNEL_CONNECTED = 
-			shape(2, -2, 14, 14, 14, 18)
-			.add(0, -5, 5, 16, 16, 11)
-			.add(2, -4, 2, 14, 14, -2)
-			.add(3, -2, 0, 13, 13, 16)
+		FUNNEL = shape(2, 2, 14, 14, 14, 18).add(1, 8, 12, 15, 15, 14)
+			.add(0.1, 13, 7, 15.9, 15, 11)
+			.add(0.1, 9, 8, 15.9, 13, 12)
+			.add(0.1, 5, 9, 15.9, 9, 13)
+			.add(0.1, 1, 10, 15.9, 5, 14)
+			.add(0.1, -1, 11, 15.9, 1, 15)
 			.forHorizontal(NORTH),
 		FLUID_VALVE = shape(3, -1, 3, 13, 17, 13).add(2, 2, 2, 14, 14, 14)
 			.forAxis(),
@@ -183,6 +175,9 @@ public class AllShapes {
 			.build(),
 		CHUTE = shape(1, 8, 1, 15, 16, 15).add(2, 0, 2, 14, 8, 14)
 			.build(),
+		SMART_CHUTE = shape(0, 0, 0, 16, 5, 16).add(0, 9, 0, 16, 15, 16)
+			.add(1, 0, 1, 15, 16, 15)
+			.build(),
 		TANK = shape(1, 0, 1, 15, 16, 15).build(), TANK_TOP = shape(TANK_TOP_LID).add(TANK)
 			.build(),
 		TANK_BOTTOM = shape(TANK_BOTTOM_LID).add(TANK)
@@ -190,6 +185,12 @@ public class AllShapes {
 		TANK_TOP_BOTTOM = shape(TANK_BOTTOM_LID).add(TANK_TOP_LID)
 			.add(TANK)
 			.build(),
+		FUNNEL_FLOOR = shape(2, -2, 2, 14, 8, 14).add(1, 2, 1, 15, 8, 15)
+			.add(0, 4, 0, 16, 10, 16)
+			.build(),
+		FUNNEL_CEILING = shape(2, 8, 2, 14, 18, 14).add(1, 8, 1, 15, 14, 15)
+			.add(0, 6, 0, 16, 12, 16)
+			.build(),
 		DEPOT = shape(CASING_11PX.get(Direction.UP)).add(1, 11, 1, 15, 13, 15)
 			.build()
 
diff --git a/src/main/java/com/simibubi/create/AllTileEntities.java b/src/main/java/com/simibubi/create/AllTileEntities.java
index 55b71eaeef..bc644e746f 100644
--- a/src/main/java/com/simibubi/create/AllTileEntities.java
+++ b/src/main/java/com/simibubi/create/AllTileEntities.java
@@ -90,6 +90,8 @@ import com.simibubi.create.content.logistics.block.belts.tunnel.BeltTunnelTileEn
 import com.simibubi.create.content.logistics.block.belts.tunnel.BrassTunnelTileEntity;
 import com.simibubi.create.content.logistics.block.chute.ChuteRenderer;
 import com.simibubi.create.content.logistics.block.chute.ChuteTileEntity;
+import com.simibubi.create.content.logistics.block.chute.SmartChuteRenderer;
+import com.simibubi.create.content.logistics.block.chute.SmartChuteTileEntity;
 import com.simibubi.create.content.logistics.block.depot.DepotRenderer;
 import com.simibubi.create.content.logistics.block.depot.DepotTileEntity;
 import com.simibubi.create.content.logistics.block.diodes.AdjustablePulseRepeaterTileEntity;
@@ -277,6 +279,12 @@ public class AllTileEntities {
 		.validBlocks(AllBlocks.CHUTE)
 		.renderer(() -> ChuteRenderer::new)
 		.register();
+	
+	public static final TileEntityEntry<SmartChuteTileEntity> SMART_CHUTE = Create.registrate()
+		.tileEntity("smart_chute", SmartChuteTileEntity::new)
+		.validBlocks(AllBlocks.SMART_CHUTE)
+		.renderer(() -> SmartChuteRenderer::new)
+		.register();
 
 	public static final TileEntityEntry<BeltTunnelTileEntity> ANDESITE_TUNNEL = Create.registrate()
 		.tileEntity("andesite_tunnel", BeltTunnelTileEntity::new)
diff --git a/src/main/java/com/simibubi/create/Create.java b/src/main/java/com/simibubi/create/Create.java
index 26e6eb0382..a48b534926 100644
--- a/src/main/java/com/simibubi/create/Create.java
+++ b/src/main/java/com/simibubi/create/Create.java
@@ -50,7 +50,7 @@ public class Create {
 
 	public static final String ID = "create";
 	public static final String NAME = "Create";
-	public static final String VERSION = "0.3";
+	public static final String VERSION = "0.3.1";
 
 	public static Logger logger = LogManager.getLogger();
 	public static ItemGroup baseCreativeTab = new CreateItemGroup();
diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/fan/EncasedFanBlock.java b/src/main/java/com/simibubi/create/content/contraptions/components/fan/EncasedFanBlock.java
index 3f912e71e1..27e3107b77 100644
--- a/src/main/java/com/simibubi/create/content/contraptions/components/fan/EncasedFanBlock.java
+++ b/src/main/java/com/simibubi/create/content/contraptions/components/fan/EncasedFanBlock.java
@@ -3,6 +3,7 @@ package com.simibubi.create.content.contraptions.components.fan;
 import com.simibubi.create.AllBlocks;
 import com.simibubi.create.AllTileEntities;
 import com.simibubi.create.content.contraptions.base.DirectionalKineticBlock;
+import com.simibubi.create.content.logistics.block.chute.AbstractChuteBlock;
 import com.simibubi.create.foundation.block.ITE;
 import com.simibubi.create.foundation.utility.worldWrappers.WrappedWorld;
 
@@ -57,9 +58,9 @@ public class EncasedFanBlock extends DirectionalKineticBlock implements ITE<Enca
 
 		BlockState placedOn = world.getBlockState(pos.offset(face.getOpposite()));
 		BlockState placedOnOpposite = world.getBlockState(pos.offset(face));
-		if (AllBlocks.CHUTE.has(placedOn))
+		if (AbstractChuteBlock.isChute(placedOn))
 			return getDefaultState().with(FACING, face.getOpposite());
-		if (AllBlocks.CHUTE.has(placedOnOpposite))
+		if (AbstractChuteBlock.isChute(placedOnOpposite))
 			return getDefaultState().with(FACING, face);
 
 		Direction preferredFacing = getPreferredFacing(context);
diff --git a/src/main/java/com/simibubi/create/content/logistics/block/chute/AbstractChuteBlock.java b/src/main/java/com/simibubi/create/content/logistics/block/chute/AbstractChuteBlock.java
new file mode 100644
index 0000000000..513a0c4545
--- /dev/null
+++ b/src/main/java/com/simibubi/create/content/logistics/block/chute/AbstractChuteBlock.java
@@ -0,0 +1,214 @@
+package com.simibubi.create.content.logistics.block.chute;
+
+import javax.annotation.Nullable;
+
+import com.simibubi.create.content.contraptions.wrench.IWrenchable;
+import com.simibubi.create.foundation.block.ITE;
+import com.simibubi.create.foundation.tileEntity.TileEntityBehaviour;
+import com.simibubi.create.foundation.tileEntity.behaviour.belt.DirectBeltInputBehaviour;
+import com.simibubi.create.foundation.utility.BlockHelper;
+import com.simibubi.create.foundation.utility.Iterate;
+
+import net.minecraft.block.Block;
+import net.minecraft.block.BlockState;
+import net.minecraft.client.particle.ParticleManager;
+import net.minecraft.entity.Entity;
+import net.minecraft.entity.item.ItemEntity;
+import net.minecraft.entity.player.PlayerEntity;
+import net.minecraft.item.ItemStack;
+import net.minecraft.tileentity.TileEntity;
+import net.minecraft.util.ActionResultType;
+import net.minecraft.util.Direction;
+import net.minecraft.util.Hand;
+import net.minecraft.util.math.BlockPos;
+import net.minecraft.util.math.BlockRayTraceResult;
+import net.minecraft.util.math.shapes.ISelectionContext;
+import net.minecraft.util.math.shapes.VoxelShape;
+import net.minecraft.world.IBlockReader;
+import net.minecraft.world.IWorld;
+import net.minecraft.world.World;
+import net.minecraftforge.api.distmarker.Dist;
+import net.minecraftforge.api.distmarker.OnlyIn;
+
+public abstract class AbstractChuteBlock extends Block implements IWrenchable, ITE<ChuteTileEntity> {
+
+	public AbstractChuteBlock(Properties p_i48440_1_) {
+		super(p_i48440_1_);
+	}
+
+	@Override
+	public boolean hasTileEntity(BlockState state) {
+		return true;
+	}
+
+	public static boolean isChute(BlockState state) {
+		return state.getBlock() instanceof AbstractChuteBlock;
+	}
+
+	public static boolean isOpenChute(BlockState state) {
+		return isChute(state) && ((AbstractChuteBlock) state.getBlock()).isOpen(state);
+	}
+	
+	public static boolean isTransparentChute(BlockState state) {
+		return isChute(state) && ((AbstractChuteBlock) state.getBlock()).isTransparent(state);
+	}
+
+	@Nullable
+	public static Direction getChuteFacing(BlockState state) {
+		return !isChute(state) ? null : ((AbstractChuteBlock) state.getBlock()).getFacing(state);
+	}
+
+	public Direction getFacing(BlockState state) {
+		return Direction.DOWN;
+	}
+
+	public boolean isOpen(BlockState state) {
+		return true;
+	}
+	
+	public boolean isTransparent(BlockState state) {
+		return false;
+	}
+
+	@Override
+	public abstract TileEntity createTileEntity(BlockState state, IBlockReader world);
+
+	@Override
+	public void onLanded(IBlockReader worldIn, Entity entityIn) {
+		super.onLanded(worldIn, entityIn);
+		if (!(entityIn instanceof ItemEntity))
+			return;
+		if (entityIn.world.isRemote)
+			return;
+		if (!entityIn.isAlive())
+			return;
+		DirectBeltInputBehaviour input = TileEntityBehaviour.get(entityIn.world, new BlockPos(entityIn.getPositionVec()
+			.add(0, 0.5f, 0)).down(), DirectBeltInputBehaviour.TYPE);
+		if (input == null)
+			return;
+		if (!input.canInsertFromSide(Direction.UP))
+			return;
+
+		ItemEntity itemEntity = (ItemEntity) entityIn;
+		ItemStack toInsert = itemEntity.getItem();
+		ItemStack remainder = input.handleInsertion(toInsert, Direction.UP, false);
+
+		if (remainder.isEmpty())
+			itemEntity.remove();
+		if (remainder.getCount() < toInsert.getCount())
+			itemEntity.setItem(remainder);
+	}
+
+	@Override
+	public void onBlockAdded(BlockState state, World world, BlockPos pos, BlockState p_220082_4_, boolean p_220082_5_) {
+		withTileEntityDo(world, pos, ChuteTileEntity::onAdded);
+		if (p_220082_5_)
+			return;
+		updateDiagonalNeighbour(state, world, pos);
+	}
+
+	protected void updateDiagonalNeighbour(BlockState state, World world, BlockPos pos) {
+		if (!isChute(state))
+			return;
+		AbstractChuteBlock block = (AbstractChuteBlock) state.getBlock();
+		Direction facing = block.getFacing(state);
+		BlockPos toUpdate = pos.down();
+		if (facing.getAxis()
+			.isHorizontal())
+			toUpdate = toUpdate.offset(facing.getOpposite());
+
+		BlockState stateToUpdate = world.getBlockState(toUpdate);
+		BlockState updated = updateChuteState(stateToUpdate, world.getBlockState(toUpdate.up()), world, toUpdate);
+		if (stateToUpdate != updated && !world.isRemote)
+			world.setBlockState(toUpdate, updated);
+	}
+
+	@Override
+	public void onReplaced(BlockState state, World world, BlockPos pos, BlockState p_196243_4_, boolean p_196243_5_) {
+		boolean differentBlock = state.getBlock() != p_196243_4_.getBlock();
+		if (state.hasTileEntity() && (differentBlock || !p_196243_4_.hasTileEntity())) {
+			withTileEntityDo(world, pos, c -> c.onRemoved(state));
+			world.removeTileEntity(pos);
+		}
+		if (p_196243_5_ || !differentBlock)
+			return;
+
+		updateDiagonalNeighbour(state, world, pos);
+
+		for (Direction direction : Iterate.horizontalDirections) {
+			BlockPos toUpdate = pos.up()
+				.offset(direction);
+			BlockState stateToUpdate = world.getBlockState(toUpdate);
+			BlockState updated = updateChuteState(stateToUpdate, world.getBlockState(toUpdate.up()), world, toUpdate);
+			if (stateToUpdate != updated && !world.isRemote)
+				world.setBlockState(toUpdate, updated);
+		}
+	}
+
+	@Override
+	public BlockState updatePostPlacement(BlockState state, Direction direction, BlockState above, IWorld world,
+		BlockPos pos, BlockPos p_196271_6_) {
+		if (direction != Direction.UP)
+			return state;
+		return updateChuteState(state, above, world, pos);
+	}
+
+	@Override
+	public void neighborChanged(BlockState p_220069_1_, World world, BlockPos pos, Block p_220069_4_,
+		BlockPos neighbourPos, boolean p_220069_6_) {
+		if (pos.down()
+			.equals(neighbourPos))
+			withTileEntityDo(world, pos, ChuteTileEntity::blockBelowChanged);
+	}
+
+	public abstract BlockState updateChuteState(BlockState state, BlockState above, IBlockReader world, BlockPos pos);
+
+	@Override
+	@OnlyIn(Dist.CLIENT)
+	public boolean addDestroyEffects(BlockState state, World world, BlockPos pos, ParticleManager manager) {
+		BlockHelper.addReducedDestroyEffects(state, world, pos, manager);
+		return true;
+	}
+	
+	@Override
+	public VoxelShape getShape(BlockState p_220053_1_, IBlockReader p_220053_2_, BlockPos p_220053_3_,
+		ISelectionContext p_220053_4_) {
+		return ChuteShapes.getShape(p_220053_1_);
+	}
+	
+	@Override
+	public VoxelShape getCollisionShape(BlockState p_220071_1_, IBlockReader p_220071_2_, BlockPos p_220071_3_,
+		ISelectionContext p_220071_4_) {
+		return ChuteShapes.getCollisionShape(p_220071_1_);
+	}
+
+	@Override
+	public Class<ChuteTileEntity> getTileEntityClass() {
+		return ChuteTileEntity.class;
+	}
+
+	@Override
+	public ActionResultType onUse(BlockState p_225533_1_, World world, BlockPos pos, PlayerEntity player, Hand hand,
+		BlockRayTraceResult p_225533_6_) {
+		if (!player.getHeldItem(hand)
+			.isEmpty())
+			return ActionResultType.PASS;
+		if (world.isRemote)
+			return ActionResultType.SUCCESS;
+		try {
+			ChuteTileEntity te = getTileEntity(world, pos);
+			if (te == null)
+				return ActionResultType.PASS;
+			if (te.item.isEmpty())
+				return ActionResultType.PASS;
+			player.inventory.placeItemBackInInventory(world, te.item);
+			te.setItem(ItemStack.EMPTY);
+			return ActionResultType.SUCCESS;
+
+		} catch (TileEntityException e) {
+			e.printStackTrace();
+		}
+		return ActionResultType.PASS;
+	}
+
+}
diff --git a/src/main/java/com/simibubi/create/content/logistics/block/chute/ChuteBlock.java b/src/main/java/com/simibubi/create/content/logistics/block/chute/ChuteBlock.java
index c1de7792b6..bb76d62d12 100644
--- a/src/main/java/com/simibubi/create/content/logistics/block/chute/ChuteBlock.java
+++ b/src/main/java/com/simibubi/create/content/logistics/block/chute/ChuteBlock.java
@@ -4,23 +4,13 @@ import java.util.HashMap;
 import java.util.Map;
 
 import com.simibubi.create.AllTileEntities;
-import com.simibubi.create.content.contraptions.wrench.IWrenchable;
 import com.simibubi.create.content.logistics.block.funnel.FunnelBlock;
-import com.simibubi.create.foundation.block.ITE;
-import com.simibubi.create.foundation.tileEntity.TileEntityBehaviour;
-import com.simibubi.create.foundation.tileEntity.behaviour.belt.DirectBeltInputBehaviour;
-import com.simibubi.create.foundation.utility.BlockHelper;
 import com.simibubi.create.foundation.utility.Iterate;
 import com.simibubi.create.foundation.utility.Lang;
 
 import net.minecraft.block.Block;
 import net.minecraft.block.BlockState;
-import net.minecraft.client.particle.ParticleManager;
-import net.minecraft.entity.Entity;
-import net.minecraft.entity.item.ItemEntity;
-import net.minecraft.entity.player.PlayerEntity;
 import net.minecraft.item.BlockItemUseContext;
-import net.minecraft.item.ItemStack;
 import net.minecraft.item.ItemUseContext;
 import net.minecraft.state.DirectionProperty;
 import net.minecraft.state.EnumProperty;
@@ -30,20 +20,20 @@ import net.minecraft.state.properties.BlockStateProperties;
 import net.minecraft.tileentity.TileEntity;
 import net.minecraft.util.ActionResultType;
 import net.minecraft.util.Direction;
-import net.minecraft.util.Hand;
 import net.minecraft.util.IStringSerializable;
 import net.minecraft.util.math.BlockPos;
-import net.minecraft.util.math.BlockRayTraceResult;
-import net.minecraft.util.math.shapes.ISelectionContext;
-import net.minecraft.util.math.shapes.VoxelShape;
 import net.minecraft.world.IBlockReader;
-import net.minecraft.world.IWorld;
 import net.minecraft.world.IWorldReader;
 import net.minecraft.world.World;
-import net.minecraftforge.api.distmarker.Dist;
-import net.minecraftforge.api.distmarker.OnlyIn;
 
-public class ChuteBlock extends Block implements IWrenchable, ITE<ChuteTileEntity> {
+public class ChuteBlock extends AbstractChuteBlock {
+
+	public ChuteBlock(Properties p_i48440_1_) {
+		super(p_i48440_1_);
+		setDefaultState(getDefaultState().with(SHAPE, Shape.NORMAL)
+			.with(FACING, Direction.DOWN));
+	}
+
 	public static final IProperty<Shape> SHAPE = EnumProperty.create("shape", Shape.class);
 	public static final DirectionProperty FACING = BlockStateProperties.FACING_EXCEPT_UP;
 
@@ -56,112 +46,36 @@ public class ChuteBlock extends Block implements IWrenchable, ITE<ChuteTileEntit
 		}
 	}
 
-	@Override
-	public boolean hasTileEntity(BlockState state) {
-		return true;
-	}
-
 	@Override
 	public TileEntity createTileEntity(BlockState state, IBlockReader world) {
 		return AllTileEntities.CHUTE.create();
 	}
 
-	public ChuteBlock(Properties p_i48440_1_) {
-		super(p_i48440_1_);
-		setDefaultState(getDefaultState().with(SHAPE, Shape.NORMAL)
-			.with(FACING, Direction.DOWN));
+	@Override
+	public Direction getFacing(BlockState state) {
+		return state.get(FACING);
 	}
 
 	@Override
-	public void onLanded(IBlockReader worldIn, Entity entityIn) {
-		super.onLanded(worldIn, entityIn);
-		if (!(entityIn instanceof ItemEntity))
-			return;
-		if (entityIn.world.isRemote)
-			return;
-		if (!entityIn.isAlive())
-			return;
-		DirectBeltInputBehaviour input = TileEntityBehaviour.get(entityIn.world, new BlockPos(entityIn.getPositionVec()
-			.add(0, 0.5f, 0)).down(), DirectBeltInputBehaviour.TYPE);
-		if (input == null)
-			return;
-		if (!input.canInsertFromSide(Direction.UP))
-			return;
-
-		ItemEntity itemEntity = (ItemEntity) entityIn;
-		ItemStack toInsert = itemEntity.getItem();
-		ItemStack remainder = input.handleInsertion(toInsert, Direction.UP, false);
-
-		if (remainder.isEmpty())
-			itemEntity.remove();
-		if (remainder.getCount() < toInsert.getCount())
-			itemEntity.setItem(remainder);
+	public boolean isOpen(BlockState state) {
+		return state.get(FACING) == Direction.DOWN || state.get(SHAPE) == Shape.INTERSECTION;
 	}
 
 	@Override
-	public void onBlockAdded(BlockState state, World world, BlockPos pos, BlockState p_220082_4_, boolean p_220082_5_) {
-		withTileEntityDo(world, pos, ChuteTileEntity::onAdded);
-		if (p_220082_5_)
-			return;
-		updateDiagonalNeighbour(state, world, pos);
-	}
-
-	protected void updateDiagonalNeighbour(BlockState state, World world, BlockPos pos) {
-		Direction facing = state.get(FACING);
-		BlockPos toUpdate = pos.down();
-		if (facing.getAxis()
-			.isHorizontal())
-			toUpdate = toUpdate.offset(facing.getOpposite());
-
-		BlockState stateToUpdate = world.getBlockState(toUpdate);
-		BlockState updated = updateDiagonalState(stateToUpdate, world.getBlockState(toUpdate.up()), world, toUpdate);
-		if (stateToUpdate != updated && !world.isRemote)
-			world.setBlockState(toUpdate, updated);
+	public boolean isTransparent(BlockState state) {
+		return state.get(SHAPE) == Shape.WINDOW;
 	}
 
 	@Override
-	public void onReplaced(BlockState state, World world, BlockPos pos, BlockState p_196243_4_, boolean p_196243_5_) {
-		boolean differentBlock = state.getBlock() != p_196243_4_.getBlock();
-		if (state.hasTileEntity() && (differentBlock || !p_196243_4_.hasTileEntity())) {
-			withTileEntityDo(world, pos, c -> c.onRemoved(state));
-			world.removeTileEntity(pos);
+	public ActionResultType onWrenched(BlockState state, ItemUseContext context) {
+		Shape shape = state.get(SHAPE);
+		boolean down = state.get(FACING) == Direction.DOWN;
+		if (!context.getWorld().isRemote && down && shape != Shape.INTERSECTION) {
+			context.getWorld()
+				.setBlockState(context.getPos(),
+					state.with(SHAPE, shape == Shape.WINDOW ? Shape.NORMAL : Shape.WINDOW));
 		}
-		if (p_196243_5_ || !differentBlock)
-			return;
-
-		updateDiagonalNeighbour(state, world, pos);
-
-		for (Direction direction : Iterate.horizontalDirections) {
-			BlockPos toUpdate = pos.up()
-				.offset(direction);
-			BlockState stateToUpdate = world.getBlockState(toUpdate);
-			BlockState updated =
-				updateDiagonalState(stateToUpdate, world.getBlockState(toUpdate.up()), world, toUpdate);
-			if (stateToUpdate != updated && !world.isRemote)
-				world.setBlockState(toUpdate, updated);
-		}
-	}
-
-	@Override
-	public BlockState updatePostPlacement(BlockState state, Direction direction, BlockState above, IWorld world,
-		BlockPos pos, BlockPos p_196271_6_) {
-		if (direction != Direction.UP)
-			return state;
-		return updateDiagonalState(state, above, world, pos);
-	}
-
-	@Override
-	public void neighborChanged(BlockState p_220069_1_, World world, BlockPos pos, Block p_220069_4_,
-		BlockPos neighbourPos, boolean p_220069_6_) {
-		if (pos.down()
-			.equals(neighbourPos))
-			withTileEntityDo(world, pos, ChuteTileEntity::blockBelowChanged);
-	}
-
-	@Override
-	public boolean isValidPosition(BlockState state, IWorldReader world, BlockPos pos) {
-		BlockState above = world.getBlockState(pos.up());
-		return !(above.getBlock() instanceof ChuteBlock) || above.get(FACING) == Direction.DOWN;
+		return ActionResultType.SUCCESS;
 	}
 
 	@Override
@@ -172,12 +86,24 @@ public class ChuteBlock extends Block implements IWrenchable, ITE<ChuteTileEntit
 			.isHorizontal() && !ctx.shouldCancelInteraction()) {
 			World world = ctx.getWorld();
 			BlockPos pos = ctx.getPos();
-			return updateDiagonalState(state.with(FACING, face), world.getBlockState(pos.up()), world, pos);
+			return updateChuteState(state.with(FACING, face), world.getBlockState(pos.up()), world, pos);
 		}
 		return state;
 	}
 
-	public static BlockState updateDiagonalState(BlockState state, BlockState above, IBlockReader world, BlockPos pos) {
+	@Override
+	protected void fillStateContainer(Builder<Block, BlockState> p_206840_1_) {
+		super.fillStateContainer(p_206840_1_.add(SHAPE, FACING));
+	}
+
+	@Override
+	public boolean isValidPosition(BlockState state, IWorldReader world, BlockPos pos) {
+		BlockState above = world.getBlockState(pos.up());
+		return !isChute(above) || getChuteFacing(above) == Direction.DOWN;
+	}
+
+	@Override
+	public BlockState updateChuteState(BlockState state, BlockState above, IBlockReader world, BlockPos pos) {
 		if (!(state.getBlock() instanceof ChuteBlock))
 			return state;
 
@@ -189,7 +115,7 @@ public class ChuteBlock extends Block implements IWrenchable, ITE<ChuteTileEntit
 		if (!vertical) {
 			BlockState target = world.getBlockState(pos.down()
 				.offset(facing.getOpposite()));
-			if (!(target.getBlock() instanceof ChuteBlock))
+			if (!isChute(target))
 				return state.with(FACING, Direction.DOWN)
 					.with(SHAPE, Shape.NORMAL);
 		}
@@ -214,78 +140,10 @@ public class ChuteBlock extends Block implements IWrenchable, ITE<ChuteTileEntit
 			return state.with(SHAPE, Shape.INTERSECTION);
 		if (connections.get(Direction.EAST) && connections.get(Direction.WEST))
 			return state.with(SHAPE, Shape.INTERSECTION);
-		if (amtConnections == 1 && connections.get(facing)
-			&& !(above.getBlock() instanceof ChuteBlock && above.get(FACING) == Direction.DOWN)
-			&& !(above.getBlock() instanceof FunnelBlock && FunnelBlock.getFunnelFacing(above)
-				.getAxis()
-				.isVertical()))
+		if (amtConnections == 1 && connections.get(facing) && !(getChuteFacing(above) == Direction.DOWN)
+			&& !(above.getBlock() instanceof FunnelBlock && FunnelBlock.getFunnelFacing(above) == Direction.DOWN))
 			return state.with(SHAPE, Shape.NORMAL);
 		return state.with(SHAPE, Shape.INTERSECTION);
 	}
 
-	@Override
-	public ActionResultType onWrenched(BlockState state, ItemUseContext context) {
-		Shape shape = state.get(SHAPE);
-		boolean down = state.get(FACING) == Direction.DOWN;
-		if (!context.getWorld().isRemote && down && shape != Shape.INTERSECTION) {
-			context.getWorld()
-				.setBlockState(context.getPos(),
-					state.with(SHAPE, shape == Shape.WINDOW ? Shape.NORMAL : Shape.WINDOW));
-		}
-		return ActionResultType.SUCCESS;
-	}
-
-	@Override
-	public VoxelShape getShape(BlockState p_220053_1_, IBlockReader p_220053_2_, BlockPos p_220053_3_,
-		ISelectionContext p_220053_4_) {
-		return ChuteShapes.getShape(p_220053_1_);
-	}
-
-	@Override
-	@OnlyIn(Dist.CLIENT)
-	public boolean addDestroyEffects(BlockState state, World world, BlockPos pos, ParticleManager manager) {
-		BlockHelper.addReducedDestroyEffects(state, world, pos, manager);
-		return true;
-	}
-
-	@Override
-	public VoxelShape getCollisionShape(BlockState p_220071_1_, IBlockReader p_220071_2_, BlockPos p_220071_3_,
-		ISelectionContext p_220071_4_) {
-		return ChuteShapes.getCollisionShape(p_220071_1_);
-	}
-
-	@Override
-	protected void fillStateContainer(Builder<Block, BlockState> p_206840_1_) {
-		super.fillStateContainer(p_206840_1_.add(SHAPE, FACING));
-	}
-
-	@Override
-	public Class<ChuteTileEntity> getTileEntityClass() {
-		return ChuteTileEntity.class;
-	}
-
-	@Override
-	public ActionResultType onUse(BlockState p_225533_1_, World world, BlockPos pos, PlayerEntity player, Hand hand,
-		BlockRayTraceResult p_225533_6_) {
-		if (!player.getHeldItem(hand)
-			.isEmpty())
-			return ActionResultType.PASS;
-		if (world.isRemote)
-			return ActionResultType.SUCCESS;
-		try {
-			ChuteTileEntity te = getTileEntity(world, pos);
-			if (te == null)
-				return ActionResultType.PASS;
-			if (te.item.isEmpty())
-				return ActionResultType.PASS;
-			player.inventory.placeItemBackInInventory(world, te.item);
-			te.setItem(ItemStack.EMPTY);
-			return ActionResultType.SUCCESS;
-
-		} catch (TileEntityException e) {
-			e.printStackTrace();
-		}
-		return ActionResultType.PASS;
-	}
-
 }
diff --git a/src/main/java/com/simibubi/create/content/logistics/block/chute/ChuteItem.java b/src/main/java/com/simibubi/create/content/logistics/block/chute/ChuteItem.java
index 2659298207..9cc13fc309 100644
--- a/src/main/java/com/simibubi/create/content/logistics/block/chute/ChuteItem.java
+++ b/src/main/java/com/simibubi/create/content/logistics/block/chute/ChuteItem.java
@@ -23,7 +23,7 @@ public class ChuteItem extends BlockItem {
 		World world = context.getWorld();
 		BlockState placedOnState = world.getBlockState(placedOnPos);
 
-		if (!(placedOnState.getBlock() instanceof ChuteBlock) || context.shouldCancelInteraction())
+		if (!AbstractChuteBlock.isChute(placedOnState) || context.shouldCancelInteraction())
 			return super.tryPlace(context);
 		if (face.getAxis()
 			.isVertical())
@@ -37,13 +37,13 @@ public class ChuteItem extends BlockItem {
 			.isReplaceable())
 			context = BlockItemUseContext.func_221536_a(context, correctPos, face);
 		else {
-			if (blockState.getBlock() instanceof ChuteBlock && blockState.get(ChuteBlock.FACING) == Direction.DOWN) {
-				if (!world.isRemote) {
-					world.setBlockState(correctPos,
-						ChuteBlock.updateDiagonalState(blockState.with(ChuteBlock.FACING, face),
-							world.getBlockState(correctPos.up()), world, correctPos));
-					return ActionResultType.SUCCESS;
-				}
+			if (!(blockState.getBlock() instanceof ChuteBlock) || world.isRemote)
+				return ActionResultType.FAIL;
+			AbstractChuteBlock block = (AbstractChuteBlock) blockState.getBlock();
+			if (block.getFacing(blockState) == Direction.DOWN) {
+				world.setBlockState(correctPos, block.updateChuteState(blockState.with(ChuteBlock.FACING, face),
+					world.getBlockState(correctPos.up()), world, correctPos));
+				return ActionResultType.SUCCESS;
 			}
 			return ActionResultType.FAIL;
 		}
diff --git a/src/main/java/com/simibubi/create/content/logistics/block/chute/ChuteItemHandler.java b/src/main/java/com/simibubi/create/content/logistics/block/chute/ChuteItemHandler.java
index bb4b3dad8e..4188d2816a 100644
--- a/src/main/java/com/simibubi/create/content/logistics/block/chute/ChuteItemHandler.java
+++ b/src/main/java/com/simibubi/create/content/logistics/block/chute/ChuteItemHandler.java
@@ -23,7 +23,7 @@ public class ChuteItemHandler implements IItemHandler {
 
 	@Override
 	public ItemStack insertItem(int slot, ItemStack stack, boolean simulate) {
-		if (!te.item.isEmpty())
+		if (!te.canAcceptItem(stack))
 			return stack;
 		if (!simulate) 
 			te.setItem(stack);
diff --git a/src/main/java/com/simibubi/create/content/logistics/block/chute/ChuteRenderer.java b/src/main/java/com/simibubi/create/content/logistics/block/chute/ChuteRenderer.java
index db4e6d833b..4d1540b686 100644
--- a/src/main/java/com/simibubi/create/content/logistics/block/chute/ChuteRenderer.java
+++ b/src/main/java/com/simibubi/create/content/logistics/block/chute/ChuteRenderer.java
@@ -31,6 +31,11 @@ public class ChuteRenderer extends SafeTileEntityRenderer<ChuteTileEntity> {
 			&& (te.bottomPullDistance == 0 || te.itemPosition.get(partialTicks) > .5f))
 			return;
 
+		renderItem(te, partialTicks, ms, buffer, light, overlay);
+	}
+
+	public static void renderItem(ChuteTileEntity te, float partialTicks, MatrixStack ms, IRenderTypeBuffer buffer,
+		int light, int overlay) {
 		ItemRenderer itemRenderer = Minecraft.getInstance()
 			.getItemRenderer();
 		MatrixStacker msr = MatrixStacker.of(ms);
diff --git a/src/main/java/com/simibubi/create/content/logistics/block/chute/ChuteShapes.java b/src/main/java/com/simibubi/create/content/logistics/block/chute/ChuteShapes.java
index aa8710fbba..6e069aeae1 100644
--- a/src/main/java/com/simibubi/create/content/logistics/block/chute/ChuteShapes.java
+++ b/src/main/java/com/simibubi/create/content/logistics/block/chute/ChuteShapes.java
@@ -3,6 +3,7 @@ package com.simibubi.create.content.logistics.block.chute;
 import java.util.HashMap;
 import java.util.Map;
 
+import com.simibubi.create.AllBlocks;
 import com.simibubi.create.AllShapes;
 import com.simibubi.create.content.logistics.block.chute.ChuteBlock.Shape;
 
@@ -22,6 +23,9 @@ public class ChuteShapes {
 	public static final VoxelShape COLLISION_MASK = Block.makeCuboidShape(0, 0, 0, 16, 24, 16);
 
 	public static VoxelShape createShape(BlockState state) {
+		if (AllBlocks.SMART_CHUTE.has(state))
+			return AllShapes.SMART_CHUTE;
+		
 		Direction direction = state.get(ChuteBlock.FACING);
 		Shape shape = state.get(ChuteBlock.SHAPE);
 
diff --git a/src/main/java/com/simibubi/create/content/logistics/block/chute/ChuteTileEntity.java b/src/main/java/com/simibubi/create/content/logistics/block/chute/ChuteTileEntity.java
index fcbfef9116..0060977156 100644
--- a/src/main/java/com/simibubi/create/content/logistics/block/chute/ChuteTileEntity.java
+++ b/src/main/java/com/simibubi/create/content/logistics/block/chute/ChuteTileEntity.java
@@ -13,9 +13,6 @@ import com.simibubi.create.content.contraptions.components.fan.EncasedFanBlock;
 import com.simibubi.create.content.contraptions.components.fan.EncasedFanTileEntity;
 import com.simibubi.create.content.contraptions.goggles.IHaveGoggleInformation;
 import com.simibubi.create.content.contraptions.particle.AirParticleData;
-import com.simibubi.create.content.logistics.block.chute.ChuteBlock.Shape;
-import com.simibubi.create.content.logistics.block.funnel.BrassFunnelBlock;
-import com.simibubi.create.content.logistics.block.funnel.FunnelBlock;
 import com.simibubi.create.foundation.advancement.AllTriggers;
 import com.simibubi.create.foundation.config.AllConfigs;
 import com.simibubi.create.foundation.gui.widgets.InterpolatedValue;
@@ -48,6 +45,7 @@ import net.minecraft.util.math.BlockPos;
 import net.minecraft.util.math.MathHelper;
 import net.minecraft.util.math.Vec3d;
 import net.minecraft.util.text.TextFormatting;
+import net.minecraft.util.text.TranslationTextComponent;
 import net.minecraftforge.common.capabilities.Capability;
 import net.minecraftforge.common.util.LazyOptional;
 import net.minecraftforge.items.CapabilityItemHandler;
@@ -110,14 +108,13 @@ public class ChuteTileEntity extends SmartTileEntity implements IHaveGoggleInfor
 	private boolean canDirectlyInsert() {
 		BlockState blockState = getBlockState();
 		BlockState blockStateAbove = world.getBlockState(pos.up());
-		if (!AllBlocks.CHUTE.has(blockState))
+		if (!AbstractChuteBlock.isChute(blockState))
 			return false;
-		if (AllBlocks.CHUTE.has(blockStateAbove) && blockStateAbove.get(ChuteBlock.FACING) == Direction.DOWN)
+		if (AbstractChuteBlock.getChuteFacing(blockStateAbove) == Direction.DOWN)
 			return false;
 		if (getItemMotion() > 0 && getInputChutes().isEmpty())
 			return false;
-		return blockState.get(ChuteBlock.FACING) == Direction.DOWN
-			|| blockState.get(ChuteBlock.SHAPE) == Shape.INTERSECTION;
+		return AbstractChuteBlock.isOpenChute(blockState);
 	}
 
 	@Override
@@ -195,7 +192,7 @@ public class ChuteTileEntity extends SmartTileEntity implements IHaveGoggleInfor
 			else
 				maxPullDistance = MathHelper.lerp(speed / 32, 0, 1);
 
-			if (AllBlocks.CHUTE.has(world.getBlockState(pos.down())))
+			if (AbstractChuteBlock.isChute(world.getBlockState(pos.down())))
 				maxPullDistance = 0;
 			float flowLimit = maxPullDistance;
 			if (flowLimit > 0)
@@ -220,14 +217,17 @@ public class ChuteTileEntity extends SmartTileEntity implements IHaveGoggleInfor
 //			airCurrent.findEntities();
 		if (bottomPullDistance <= 0 && !getItem().isEmpty() || itemSpeed <= 0 || world == null || world.isRemote)
 			return;
+		if (!canCollectItemsFromBelow())
+			return;
 		Vec3d center = VecHelper.getCenterOf(pos);
 		AxisAlignedBB searchArea =
 			new AxisAlignedBB(center.add(0, -bottomPullDistance - 0.5, 0), center.add(0, -0.5, 0)).grow(.45f);
 		for (ItemEntity itemEntity : world.getEntitiesWithinAABB(ItemEntity.class, searchArea)) {
-			setItem(itemEntity.getItem()
-				.copy(),
-				(float) (itemEntity.getBoundingBox()
-					.getCenter().y - pos.getY()));
+			ItemStack entityItem = itemEntity.getItem();
+			if (!canAcceptItem(entityItem))
+				continue;
+			setItem(entityItem.copy(), (float) (itemEntity.getBoundingBox()
+				.getCenter().y - pos.getY()));
 			itemEntity.remove();
 			AllTriggers.triggerForNearbyPlayers(AllTriggers.UPWARD_CHUTE, world, pos, 5);
 			break;
@@ -239,7 +239,7 @@ public class ChuteTileEntity extends SmartTileEntity implements IHaveGoggleInfor
 			return;
 		if (getItem().isEmpty() && beltBelow != null) {
 			beltBelow.handleCenteredProcessingOnAllItems(.5f, ts -> {
-				if (getItem().isEmpty()) {
+				if (canAcceptItem(ts.stack)) {
 					setItem(ts.stack.copy(), -beltBelowOffset);
 					return TransportedResult.removeItem();
 				}
@@ -279,27 +279,24 @@ public class ChuteTileEntity extends SmartTileEntity implements IHaveGoggleInfor
 		BlockState blockState = getBlockState();
 		boolean up = itemMotion > 0;
 		float absMotion = up ? itemMotion : -itemMotion;
-		if (blockState == null || !(blockState.getBlock() instanceof ChuteBlock))
+		if (blockState == null || !AbstractChuteBlock.isChute(blockState))
 			return;
 		if (push == 0 && pull == 0)
 			return;
 
-		if (up
-			&& (blockState.get(ChuteBlock.FACING) == Direction.DOWN
-				|| blockState.get(ChuteBlock.SHAPE) == Shape.INTERSECTION)
-			&& BlockHelper.noCollisionInSpace(world, pos.up()))
+		if (up && AbstractChuteBlock.isOpenChute(blockState) && BlockHelper.noCollisionInSpace(world, pos.up()))
 			spawnAirFlow(1, 2, absMotion, .5f);
 
-		if (blockState.get(ChuteBlock.FACING) != Direction.DOWN)
+		if (AbstractChuteBlock.getChuteFacing(blockState) != Direction.DOWN)
 			return;
 
-		if (blockState.get(ChuteBlock.SHAPE) == Shape.WINDOW)
+		if (AbstractChuteBlock.isTransparentChute(blockState))
 			spawnAirFlow(up ? 0 : 1, up ? 1 : 0, absMotion, 1);
 
 		if (!up && BlockHelper.noCollisionInSpace(world, pos.down()))
 			spawnAirFlow(0, -1, absMotion, .5f);
 
-		if (up && bottomPullDistance > 0) {
+		if (up && canCollectItemsFromBelow() && bottomPullDistance > 0) {
 			spawnAirFlow(-bottomPullDistance, 0, absMotion, 2);
 			spawnAirFlow(-bottomPullDistance, 0, absMotion, 2);
 		}
@@ -322,24 +319,52 @@ public class ChuteTileEntity extends SmartTileEntity implements IHaveGoggleInfor
 	private void handleInputFromAbove() {
 		if (!capAbove.isPresent())
 			capAbove = grabCapability(Direction.UP);
-		if (capAbove.isPresent())
-			item = ItemHelper.extract(capAbove.orElse(null), stack -> true, ExtractionCountMode.UPTO, 16, false);
+		if (capAbove.isPresent()) {
+			int count = getExtractionAmount();
+			if (count == 0)
+				item =
+					ItemHelper.extract(capAbove.orElse(null), this::canAcceptItem, ExtractionCountMode.UPTO, 16, false);
+			else
+				item = ItemHelper.extract(capAbove.orElse(null), this::canAcceptItem, ExtractionCountMode.EXACTLY,
+					count, false);
+		}
 	}
 
 	private void handleInputFromBelow() {
 		if (!capBelow.isPresent())
 			capBelow = grabCapability(Direction.DOWN);
-		if (capBelow.isPresent())
-			item = ItemHelper.extract(capBelow.orElse(null), stack -> true, ExtractionCountMode.UPTO, 16, false);
+		if (capBelow.isPresent()) {
+			int count = getExtractionAmount();
+			if (count == 0)
+				item =
+					ItemHelper.extract(capBelow.orElse(null), this::canAcceptItem, ExtractionCountMode.UPTO, 16, false);
+			else
+				item = ItemHelper.extract(capBelow.orElse(null), this::canAcceptItem, ExtractionCountMode.EXACTLY,
+					count, false);
+		}
 	}
 
 	private boolean handleDownwardOutput(boolean simulate) {
 		BlockState blockState = getBlockState();
 		ChuteTileEntity targetChute = getTargetChute(blockState);
-		Direction direction = blockState.get(ChuteBlock.FACING);
+		Direction direction = AbstractChuteBlock.getChuteFacing(blockState);
+
+		if (world == null)
+			return false;
+		if (!capBelow.isPresent())
+			capBelow = grabCapability(Direction.DOWN);
+		if (capBelow.isPresent()) {
+			ItemStack remainder = ItemHandlerHelper.insertItemStacked(capBelow.orElse(null), item, simulate);
+			if (!simulate)
+				setItem(remainder);
+			if (remainder.isEmpty())
+				return true;
+			if (direction == Direction.DOWN)
+				return false;
+		}
 
 		if (targetChute != null) {
-			boolean canInsert = targetChute.item.isEmpty();
+			boolean canInsert = targetChute.canAcceptItem(item);
 			if (!simulate && canInsert) {
 				targetChute.setItem(item, direction == Direction.DOWN ? 1 : .51f);
 				setItem(ItemStack.EMPTY);
@@ -347,42 +372,33 @@ public class ChuteTileEntity extends SmartTileEntity implements IHaveGoggleInfor
 			return canInsert;
 		}
 
-		// Diagonal chutes can only insert into other chutes
-		if (world == null || direction.getAxis()
+		// Diagonal chutes cannot drop items
+		if (direction.getAxis()
 			.isHorizontal())
 			return false;
 
-		BlockState stateBelow = world.getBlockState(pos.down());
-		if (stateBelow.getBlock() instanceof FunnelBlock) {
-			if (stateBelow.has(BrassFunnelBlock.POWERED) && stateBelow.get(BrassFunnelBlock.POWERED))
-				return false;
-			if (stateBelow.get(BrassFunnelBlock.FACING) != Direction.UP)
-				return false;
-			ItemStack remainder = FunnelBlock.tryInsert(world, pos.down(), item, simulate);
-			if (!simulate)
-				setItem(remainder);
-			return remainder.isEmpty();
-		}
-
-		DirectBeltInputBehaviour directInput =
-			TileEntityBehaviour.get(world, pos.down(), DirectBeltInputBehaviour.TYPE);
-		if (directInput != null) {
-			if (!directInput.canInsertFromSide(Direction.UP))
-				return false;
-			ItemStack remainder = directInput.handleInsertion(item, Direction.UP, simulate);
-			if (!simulate)
-				setItem(remainder);
-			return remainder.isEmpty();
-		}
-
-		if (!capBelow.isPresent())
-			capBelow = grabCapability(Direction.DOWN);
-		if (capBelow.isPresent()) {
-			ItemStack remainder = ItemHandlerHelper.insertItemStacked(capBelow.orElse(null), item, simulate);
-			if (!simulate)
-				setItem(ItemStack.EMPTY);
-			return remainder.isEmpty();
-		}
+//		BlockState stateBelow = world.getBlockState(pos.down());
+//		if (stateBelow.getBlock() instanceof FunnelBlock) {
+//			if (stateBelow.has(BrassFunnelBlock.POWERED) && stateBelow.get(BrassFunnelBlock.POWERED))
+//				return false;
+//			if (stateBelow.get(BrassFunnelBlock.FACING) != Direction.UP)
+//				return false;
+//			ItemStack remainder = FunnelBlock.tryInsert(world, pos.down(), item, simulate);
+//			if (!simulate)
+//				setItem(remainder);
+//			return remainder.isEmpty();
+//		}
+//
+//		DirectBeltInputBehaviour directInput =
+//			TileEntityBehaviour.get(world, pos.down(), DirectBeltInputBehaviour.TYPE);
+//		if (directInput != null) {
+//			if (!directInput.canInsertFromSide(Direction.UP))
+//				return false;
+//			ItemStack remainder = directInput.handleInsertion(item, Direction.UP, simulate);
+//			if (!simulate)
+//				setItem(remainder);
+//			return remainder.isEmpty();
+//		}
 
 		if (Block.hasSolidSideOnTop(world, pos.down()))
 			return false;
@@ -402,22 +418,36 @@ public class ChuteTileEntity extends SmartTileEntity implements IHaveGoggleInfor
 
 	private boolean handleUpwardOutput(boolean simulate) {
 		BlockState stateAbove = world.getBlockState(pos.up());
-		if (stateAbove.getBlock() instanceof FunnelBlock) {
-			boolean powered = stateAbove.has(BrassFunnelBlock.POWERED) && stateAbove.get(BrassFunnelBlock.POWERED);
-			if (!powered && stateAbove.get(BrassFunnelBlock.FACING) == Direction.DOWN) {
-				ItemStack remainder = FunnelBlock.tryInsert(world, pos.up(), item, simulate);
-				if (remainder.isEmpty()) {
-					if (!simulate)
-						setItem(remainder);
-					return true;
-				}
+//		if (stateAbove.getBlock() instanceof FunnelBlock) {
+//			boolean powered = stateAbove.has(BrassFunnelBlock.POWERED) && stateAbove.get(BrassFunnelBlock.POWERED);
+//			if (!powered && stateAbove.get(BrassFunnelBlock.FACING) == Direction.DOWN) {
+//				ItemStack remainder = FunnelBlock.tryInsert(world, pos.up(), item, simulate);
+//				if (remainder.isEmpty()) {
+//					if (!simulate)
+//						setItem(remainder);
+//					return true;
+//				}
+//			}
+//		}
+
+		if (world == null)
+			return false;
+
+		if (AbstractChuteBlock.isOpenChute(getBlockState())) {
+			if (!capAbove.isPresent())
+				capAbove = grabCapability(Direction.UP);
+			if (capAbove.isPresent()) {
+				ItemStack remainder = ItemHandlerHelper.insertItemStacked(capAbove.orElse(null), item, simulate);
+				if (!simulate)
+					setItem(ItemStack.EMPTY);
+				return remainder.isEmpty();
 			}
 		}
 
 		ChuteTileEntity bestOutput = null;
 		List<ChuteTileEntity> inputChutes = getInputChutes();
 		for (ChuteTileEntity targetChute : inputChutes) {
-			if (!targetChute.item.isEmpty())
+			if (!targetChute.canAcceptItem(item))
 				continue;
 			float itemMotion = targetChute.getItemMotion();
 			if (itemMotion < 0)
@@ -435,15 +465,6 @@ public class ChuteTileEntity extends SmartTileEntity implements IHaveGoggleInfor
 			return true;
 		}
 
-		if (!capAbove.isPresent())
-			capAbove = grabCapability(Direction.UP);
-		if (capAbove.isPresent()) {
-			ItemStack remainder = ItemHandlerHelper.insertItemStacked(capAbove.orElse(null), item, simulate);
-			if (!simulate)
-				setItem(ItemStack.EMPTY);
-			return remainder.isEmpty();
-		}
-
 		if (Block.hasSolidSide(stateAbove, world, pos.up(), Direction.DOWN))
 			return false;
 		if (!inputChutes.isEmpty())
@@ -461,12 +482,25 @@ public class ChuteTileEntity extends SmartTileEntity implements IHaveGoggleInfor
 		return true;
 	}
 
+	protected boolean canAcceptItem(ItemStack stack) {
+		return item.isEmpty();
+	}
+
+	protected int getExtractionAmount() {
+		return 0;
+	}
+
+	protected boolean canCollectItemsFromBelow() {
+		return true;
+	}
+
 	private LazyOptional<IItemHandler> grabCapability(Direction side) {
 		BlockPos pos = this.pos.offset(side);
 		if (world == null)
 			return LazyOptional.empty();
 		TileEntity te = world.getTileEntity(pos);
-		if (te == null || te instanceof ChuteTileEntity)
+		if (te == null
+			|| (te instanceof ChuteTileEntity) && (side != Direction.DOWN || !(te instanceof SmartChuteTileEntity)))
 			return LazyOptional.empty();
 		return te.getCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY, side.getOpposite());
 	}
@@ -626,13 +660,15 @@ public class ChuteTileEntity extends SmartTileEntity implements IHaveGoggleInfor
 	private ChuteTileEntity getTargetChute(BlockState state) {
 		if (world == null)
 			return null;
-		Direction targetDirection = state.get(ChuteBlock.FACING);
+		Direction targetDirection = AbstractChuteBlock.getChuteFacing(state);
+		if (targetDirection == null)
+			return null;
 		BlockPos chutePos = pos.down();
 		if (targetDirection.getAxis()
 			.isHorizontal())
 			chutePos = chutePos.offset(targetDirection.getOpposite());
 		BlockState chuteState = world.getBlockState(chutePos);
-		if (!AllBlocks.CHUTE.has(chuteState))
+		if (!AbstractChuteBlock.isChute(chuteState))
 			return null;
 		TileEntity te = world.getTileEntity(chutePos);
 		if (te instanceof ChuteTileEntity)
@@ -661,7 +697,8 @@ public class ChuteTileEntity extends SmartTileEntity implements IHaveGoggleInfor
 			.isHorizontal())
 			chutePos = chutePos.offset(direction);
 		BlockState chuteState = world.getBlockState(chutePos);
-		if (!AllBlocks.CHUTE.has(chuteState) || chuteState.get(ChuteBlock.FACING) != direction)
+		Direction chuteFacing = AbstractChuteBlock.getChuteFacing(chuteState);
+		if (chuteFacing != direction)
 			return null;
 		TileEntity te = world.getTileEntity(chutePos);
 		if (te instanceof ChuteTileEntity && !te.isRemoved())
@@ -683,6 +720,13 @@ public class ChuteTileEntity extends SmartTileEntity implements IHaveGoggleInfor
 				+ Lang.translate("tooltip.chute.fans_" + (push > 0 ? "push_up" : "pull_down")));
 		tooltip.add(spacing + TextFormatting.YELLOW + "-> "
 			+ Lang.translate("tooltip.chute.items_move_" + (downward ? "down" : "up")));
+		if (!item.isEmpty()) {
+			tooltip.add(spacing + TextFormatting.GREEN
+				+ Lang.translate("tooltip.chute.contains",
+					TextFormatting.RESET + new TranslationTextComponent(item.getItem()
+						.getTranslationKey(item)).getString(),
+					item.getCount()));
+		}
 		return true;
 	}
 
diff --git a/src/main/java/com/simibubi/create/content/logistics/block/chute/SmartChuteBlock.java b/src/main/java/com/simibubi/create/content/logistics/block/chute/SmartChuteBlock.java
new file mode 100644
index 0000000000..eadcd71fae
--- /dev/null
+++ b/src/main/java/com/simibubi/create/content/logistics/block/chute/SmartChuteBlock.java
@@ -0,0 +1,63 @@
+package com.simibubi.create.content.logistics.block.chute;
+
+import com.simibubi.create.AllTileEntities;
+
+import net.minecraft.block.Block;
+import net.minecraft.block.BlockState;
+import net.minecraft.item.BlockItemUseContext;
+import net.minecraft.state.BooleanProperty;
+import net.minecraft.state.StateContainer.Builder;
+import net.minecraft.state.properties.BlockStateProperties;
+import net.minecraft.tileentity.TileEntity;
+import net.minecraft.util.math.BlockPos;
+import net.minecraft.world.IBlockReader;
+import net.minecraft.world.IWorldReader;
+import net.minecraft.world.World;
+
+public class SmartChuteBlock extends AbstractChuteBlock {
+
+	public SmartChuteBlock(Properties p_i48440_1_) {
+		super(p_i48440_1_);
+		setDefaultState(getDefaultState().with(POWERED, true));
+	}
+
+	public static final BooleanProperty POWERED = BlockStateProperties.POWERED;
+
+	@Override
+	public void neighborChanged(BlockState state, World worldIn, BlockPos pos, Block blockIn, BlockPos fromPos,
+		boolean isMoving) {
+		super.neighborChanged(state, worldIn, pos, blockIn, fromPos, isMoving);
+		if (worldIn.isRemote)
+			return;
+		boolean previouslyPowered = state.get(POWERED);
+		if (previouslyPowered != worldIn.isBlockPowered(pos))
+			worldIn.setBlockState(pos, state.cycle(POWERED), 2);
+	}
+
+	@Override
+	public BlockState getStateForPlacement(BlockItemUseContext p_196258_1_) {
+		return super.getStateForPlacement(p_196258_1_).with(POWERED, p_196258_1_.getWorld()
+			.isBlockPowered(p_196258_1_.getPos()));
+	}
+
+	@Override
+	public boolean isValidPosition(BlockState state, IWorldReader world, BlockPos pos) {
+		return true;
+	}
+
+	@Override
+	public TileEntity createTileEntity(BlockState state, IBlockReader world) {
+		return AllTileEntities.SMART_CHUTE.create();
+	}
+
+	@Override
+	protected void fillStateContainer(Builder<Block, BlockState> p_206840_1_) {
+		super.fillStateContainer(p_206840_1_.add(POWERED));
+	}
+
+	@Override
+	public BlockState updateChuteState(BlockState state, BlockState above, IBlockReader world, BlockPos pos) {
+		return state;
+	}
+
+}
diff --git a/src/main/java/com/simibubi/create/content/logistics/block/chute/SmartChuteFilterSlotPositioning.java b/src/main/java/com/simibubi/create/content/logistics/block/chute/SmartChuteFilterSlotPositioning.java
new file mode 100644
index 0000000000..7be5fd0673
--- /dev/null
+++ b/src/main/java/com/simibubi/create/content/logistics/block/chute/SmartChuteFilterSlotPositioning.java
@@ -0,0 +1,33 @@
+package com.simibubi.create.content.logistics.block.chute;
+
+import com.simibubi.create.foundation.tileEntity.behaviour.ValueBoxTransform;
+import com.simibubi.create.foundation.utility.AngleHelper;
+import com.simibubi.create.foundation.utility.VecHelper;
+
+import net.minecraft.block.BlockState;
+import net.minecraft.util.Direction;
+import net.minecraft.util.Direction.Axis;
+import net.minecraft.util.math.Vec3d;
+
+public class SmartChuteFilterSlotPositioning extends ValueBoxTransform.Sided {
+
+	@Override
+	protected Vec3d getLocalOffset(BlockState state) {
+		Direction side = getSide();
+		float horizontalAngle = AngleHelper.horizontalAngle(side);
+		Vec3d southLocation = VecHelper.voxelSpace(8, 12, 15.5f);
+		return VecHelper.rotateCentered(southLocation, horizontalAngle, Axis.Y);
+	}
+
+	@Override
+	protected boolean isSideActive(BlockState state, Direction direction) {
+		return direction.getAxis()
+			.isHorizontal();
+	}
+
+	@Override
+	protected Vec3d getSouthLocation() {
+		return Vec3d.ZERO;
+	}
+
+}
diff --git a/src/main/java/com/simibubi/create/content/logistics/block/chute/SmartChuteRenderer.java b/src/main/java/com/simibubi/create/content/logistics/block/chute/SmartChuteRenderer.java
new file mode 100644
index 0000000000..2098babf7f
--- /dev/null
+++ b/src/main/java/com/simibubi/create/content/logistics/block/chute/SmartChuteRenderer.java
@@ -0,0 +1,26 @@
+package com.simibubi.create.content.logistics.block.chute;
+
+import com.mojang.blaze3d.matrix.MatrixStack;
+import com.simibubi.create.foundation.tileEntity.renderer.SmartTileEntityRenderer;
+
+import net.minecraft.client.renderer.IRenderTypeBuffer;
+import net.minecraft.client.renderer.tileentity.TileEntityRendererDispatcher;
+
+public class SmartChuteRenderer extends SmartTileEntityRenderer<SmartChuteTileEntity> {
+
+	public SmartChuteRenderer(TileEntityRendererDispatcher dispatcher) {
+		super(dispatcher);
+	}
+	
+	@Override
+	protected void renderSafe(SmartChuteTileEntity tileEntityIn, float partialTicks, MatrixStack ms,
+		IRenderTypeBuffer buffer, int light, int overlay) {
+		super.renderSafe(tileEntityIn, partialTicks, ms, buffer, light, overlay);
+		if (tileEntityIn.item.isEmpty())
+			return;
+		if (tileEntityIn.itemPosition.get(partialTicks) > 0)
+			return;
+		ChuteRenderer.renderItem(tileEntityIn, partialTicks, ms, buffer, light, overlay);
+	}
+
+}
diff --git a/src/main/java/com/simibubi/create/content/logistics/block/chute/SmartChuteTileEntity.java b/src/main/java/com/simibubi/create/content/logistics/block/chute/SmartChuteTileEntity.java
new file mode 100644
index 0000000000..d2ba5c271e
--- /dev/null
+++ b/src/main/java/com/simibubi/create/content/logistics/block/chute/SmartChuteTileEntity.java
@@ -0,0 +1,53 @@
+package com.simibubi.create.content.logistics.block.chute;
+
+import java.util.List;
+
+import com.simibubi.create.foundation.tileEntity.TileEntityBehaviour;
+import com.simibubi.create.foundation.tileEntity.behaviour.filtering.FilteringBehaviour;
+
+import net.minecraft.block.BlockState;
+import net.minecraft.item.ItemStack;
+import net.minecraft.tileentity.TileEntityType;
+import net.minecraft.util.Direction;
+import net.minecraft.util.math.BlockPos;
+
+public class SmartChuteTileEntity extends ChuteTileEntity {
+
+	FilteringBehaviour filtering;
+
+	public SmartChuteTileEntity(TileEntityType<?> tileEntityTypeIn) {
+		super(tileEntityTypeIn);
+	}
+
+	@Override
+	protected boolean canAcceptItem(ItemStack stack) {
+		return super.canAcceptItem(stack) && canCollectItemsFromBelow();
+	}
+
+	@Override
+	protected int getExtractionAmount() {
+		return filtering.isCountVisible() ? filtering.getAmount() : 0;
+	}
+
+	@Override
+	protected boolean canCollectItemsFromBelow() {
+		BlockState blockState = getBlockState();
+		return blockState.has(SmartChuteBlock.POWERED) && !blockState.get(SmartChuteBlock.POWERED);
+	}
+
+	@Override
+	public void addBehaviours(List<TileEntityBehaviour> behaviours) {
+		behaviours.add(filtering =
+			new FilteringBehaviour(this, new SmartChuteFilterSlotPositioning()).showCountWhen(this::isExtracting));
+		super.addBehaviours(behaviours);
+	}
+
+	private boolean isExtracting() {
+		boolean up = getItemMotion() < 0;
+		BlockPos chutePos = pos.offset(up ? Direction.UP : Direction.DOWN);
+		BlockState blockState = world.getBlockState(chutePos);
+		return !AbstractChuteBlock.isChute(blockState) && !blockState.getMaterial()
+			.isReplaceable();
+	}
+
+}
diff --git a/src/main/java/com/simibubi/create/content/logistics/block/funnel/AbstractFunnelBlock.java b/src/main/java/com/simibubi/create/content/logistics/block/funnel/AbstractFunnelBlock.java
new file mode 100644
index 0000000000..758ee24178
--- /dev/null
+++ b/src/main/java/com/simibubi/create/content/logistics/block/funnel/AbstractFunnelBlock.java
@@ -0,0 +1,142 @@
+package com.simibubi.create.content.logistics.block.funnel;
+
+import javax.annotation.Nullable;
+
+import com.simibubi.create.AllTileEntities;
+import com.simibubi.create.content.contraptions.wrench.IWrenchable;
+import com.simibubi.create.foundation.block.ITE;
+import com.simibubi.create.foundation.tileEntity.TileEntityBehaviour;
+import com.simibubi.create.foundation.tileEntity.behaviour.filtering.FilteringBehaviour;
+import com.simibubi.create.foundation.tileEntity.behaviour.inventory.InvManipulationBehaviour;
+import com.simibubi.create.foundation.utility.BlockHelper;
+
+import net.minecraft.block.Block;
+import net.minecraft.block.BlockState;
+import net.minecraft.block.HorizontalBlock;
+import net.minecraft.client.particle.ParticleManager;
+import net.minecraft.item.BlockItemUseContext;
+import net.minecraft.item.ItemStack;
+import net.minecraft.state.BooleanProperty;
+import net.minecraft.state.StateContainer.Builder;
+import net.minecraft.state.properties.BlockStateProperties;
+import net.minecraft.tileentity.TileEntity;
+import net.minecraft.util.Direction;
+import net.minecraft.util.math.BlockPos;
+import net.minecraft.world.IBlockReader;
+import net.minecraft.world.IWorldReader;
+import net.minecraft.world.World;
+import net.minecraftforge.api.distmarker.Dist;
+import net.minecraftforge.api.distmarker.OnlyIn;
+
+public abstract class AbstractFunnelBlock extends HorizontalBlock implements ITE<FunnelTileEntity>, IWrenchable {
+
+	public static final BooleanProperty POWERED = BlockStateProperties.POWERED;
+
+	protected AbstractFunnelBlock(Properties p_i48377_1_) {
+		super(p_i48377_1_);
+		setDefaultState(getDefaultState().with(POWERED, false));
+	}
+
+	@Override
+	public BlockState getStateForPlacement(BlockItemUseContext context) {
+		Direction facing = context.getPlacementHorizontalFacing()
+			.getOpposite();
+		return getDefaultState().with(HORIZONTAL_FACING, facing)
+			.with(POWERED, context.getWorld()
+				.isBlockPowered(context.getPos()));
+	}
+
+	@Override
+	protected void fillStateContainer(Builder<Block, BlockState> builder) {
+		super.fillStateContainer(builder.add(POWERED, HORIZONTAL_FACING));
+	}
+
+	@Override
+	@OnlyIn(Dist.CLIENT)
+	public boolean addDestroyEffects(BlockState state, World world, BlockPos pos, ParticleManager manager) {
+		BlockHelper.addReducedDestroyEffects(state, world, pos, manager);
+		return true;
+	}
+
+	@Override
+	public void neighborChanged(BlockState state, World worldIn, BlockPos pos, Block blockIn, BlockPos fromPos,
+		boolean isMoving) {
+		if (worldIn.isRemote)
+			return;
+		boolean previouslyPowered = state.get(POWERED);
+		if (previouslyPowered != worldIn.isBlockPowered(pos))
+			worldIn.setBlockState(pos, state.cycle(POWERED), 2);
+	}
+
+	public static ItemStack tryInsert(World worldIn, BlockPos pos, ItemStack toInsert, boolean simulate) {
+		FilteringBehaviour filter = TileEntityBehaviour.get(worldIn, pos, FilteringBehaviour.TYPE);
+		InvManipulationBehaviour inserter = TileEntityBehaviour.get(worldIn, pos, InvManipulationBehaviour.TYPE);
+		if (inserter == null)
+			return toInsert;
+		if (filter != null && !filter.test(toInsert))
+			return toInsert;
+		if (simulate)
+			inserter.simulate();
+		ItemStack insert = inserter.insert(toInsert);
+
+		if (!simulate && insert.getCount() != toInsert.getCount()) {
+			TileEntity tileEntity = worldIn.getTileEntity(pos);
+			if (tileEntity instanceof FunnelTileEntity) {
+				FunnelTileEntity funnelTileEntity = (FunnelTileEntity) tileEntity;
+				funnelTileEntity.onTransfer(toInsert);
+				if (funnelTileEntity.hasFlap())
+					funnelTileEntity.flap(true);
+			}
+		}
+		return insert;
+	}
+
+	@Override
+	public boolean hasTileEntity(BlockState state) {
+		return true;
+	}
+
+	@Override
+	public TileEntity createTileEntity(BlockState state, IBlockReader world) {
+		return AllTileEntities.FUNNEL.create();
+	}
+
+	@Override
+	public boolean isValidPosition(BlockState state, IWorldReader world, BlockPos pos) {
+		Block block = world.getBlockState(pos.offset(getFunnelFacing(state).getOpposite()))
+			.getBlock();
+		return !(block instanceof AbstractFunnelBlock);
+	}
+
+	@Nullable
+	public static boolean isFunnel(BlockState state) {
+		return state.getBlock() instanceof AbstractFunnelBlock;
+	}
+
+	@Nullable
+	public static Direction getFunnelFacing(BlockState state) {
+		if (!(state.getBlock() instanceof AbstractFunnelBlock))
+			return null;
+		return ((AbstractFunnelBlock) state.getBlock()).getFacing(state);
+	}
+
+	protected Direction getFacing(BlockState state) {
+		return state.get(BlockStateProperties.HORIZONTAL_FACING);
+	}
+
+	@Override
+	public void onReplaced(BlockState p_196243_1_, World p_196243_2_, BlockPos p_196243_3_, BlockState p_196243_4_,
+		boolean p_196243_5_) {
+		if (p_196243_1_.hasTileEntity() && (p_196243_1_.getBlock() != p_196243_4_.getBlock() && !isFunnel(p_196243_4_)
+			|| !p_196243_4_.hasTileEntity())) {
+			TileEntityBehaviour.destroy(p_196243_2_, p_196243_3_, FilteringBehaviour.TYPE);
+			p_196243_2_.removeTileEntity(p_196243_3_);
+		}
+	}
+
+	@Override
+	public Class<FunnelTileEntity> getTileEntityClass() {
+		return FunnelTileEntity.class;
+	}
+
+}
diff --git a/src/main/java/com/simibubi/create/content/logistics/block/funnel/AndesiteBeltFunnelBlock.java b/src/main/java/com/simibubi/create/content/logistics/block/funnel/AndesiteBeltFunnelBlock.java
deleted file mode 100644
index 9bf729408a..0000000000
--- a/src/main/java/com/simibubi/create/content/logistics/block/funnel/AndesiteBeltFunnelBlock.java
+++ /dev/null
@@ -1,16 +0,0 @@
-package com.simibubi.create.content.logistics.block.funnel;
-
-import com.simibubi.create.AllBlocks;
-
-public class AndesiteBeltFunnelBlock extends BeltFunnelBlock {
-
-	public AndesiteBeltFunnelBlock(Properties p_i48377_1_) {
-		super(AllBlocks.ANDESITE_FUNNEL, p_i48377_1_);
-	}
-
-	@Override
-	public boolean hasPoweredProperty() {
-		return true;
-	}
-
-}
diff --git a/src/main/java/com/simibubi/create/content/logistics/block/funnel/AndesiteFunnelBlock.java b/src/main/java/com/simibubi/create/content/logistics/block/funnel/AndesiteFunnelBlock.java
index b4389e5ab9..6db0b2b2f3 100644
--- a/src/main/java/com/simibubi/create/content/logistics/block/funnel/AndesiteFunnelBlock.java
+++ b/src/main/java/com/simibubi/create/content/logistics/block/funnel/AndesiteFunnelBlock.java
@@ -15,7 +15,7 @@ public class AndesiteFunnelBlock extends FunnelBlock {
 
 	@Override
 	public BlockState getEquivalentBeltFunnel(IBlockReader world, BlockPos pos, BlockState state) {
-		Direction facing = state.get(FACING);
+		Direction facing = state.get(HORIZONTAL_FACING);
 		return AllBlocks.ANDESITE_BELT_FUNNEL.getDefaultState()
 			.with(BeltFunnelBlock.HORIZONTAL_FACING, facing)
 			.with(POWERED, state.get(POWERED));
diff --git a/src/main/java/com/simibubi/create/content/logistics/block/funnel/BeltFunnelBlock.java b/src/main/java/com/simibubi/create/content/logistics/block/funnel/BeltFunnelBlock.java
index 6f4061b7c2..40c6de55a0 100644
--- a/src/main/java/com/simibubi/create/content/logistics/block/funnel/BeltFunnelBlock.java
+++ b/src/main/java/com/simibubi/create/content/logistics/block/funnel/BeltFunnelBlock.java
@@ -2,35 +2,27 @@ package com.simibubi.create.content.logistics.block.funnel;
 
 import com.simibubi.create.AllBlocks;
 import com.simibubi.create.AllShapes;
-import com.simibubi.create.AllTileEntities;
 import com.simibubi.create.content.contraptions.relays.belt.BeltBlock;
 import com.simibubi.create.content.contraptions.relays.belt.BeltSlope;
-import com.simibubi.create.content.contraptions.wrench.IWrenchable;
 import com.simibubi.create.content.schematics.ISpecialBlockItemRequirement;
 import com.simibubi.create.content.schematics.ItemRequirement;
 import com.simibubi.create.foundation.advancement.AllTriggers;
 import com.simibubi.create.foundation.tileEntity.TileEntityBehaviour;
 import com.simibubi.create.foundation.tileEntity.behaviour.belt.DirectBeltInputBehaviour;
-import com.simibubi.create.foundation.tileEntity.behaviour.filtering.FilteringBehaviour;
-import com.simibubi.create.foundation.utility.BlockHelper;
 import com.simibubi.create.foundation.utility.Lang;
 import com.simibubi.create.foundation.utility.VoxelShaper;
 import com.tterrag.registrate.util.entry.BlockEntry;
 
 import net.minecraft.block.Block;
 import net.minecraft.block.BlockState;
-import net.minecraft.block.HorizontalBlock;
-import net.minecraft.client.particle.ParticleManager;
+import net.minecraft.entity.item.ItemEntity;
 import net.minecraft.entity.player.PlayerEntity;
 import net.minecraft.item.BlockItemUseContext;
 import net.minecraft.item.ItemStack;
 import net.minecraft.item.ItemUseContext;
-import net.minecraft.state.BooleanProperty;
 import net.minecraft.state.EnumProperty;
 import net.minecraft.state.IProperty;
 import net.minecraft.state.StateContainer.Builder;
-import net.minecraft.state.properties.BlockStateProperties;
-import net.minecraft.tileentity.TileEntity;
 import net.minecraft.util.ActionResultType;
 import net.minecraft.util.Direction;
 import net.minecraft.util.IStringSerializable;
@@ -42,14 +34,10 @@ import net.minecraft.world.IBlockReader;
 import net.minecraft.world.IWorld;
 import net.minecraft.world.IWorldReader;
 import net.minecraft.world.World;
-import net.minecraftforge.api.distmarker.Dist;
-import net.minecraftforge.api.distmarker.OnlyIn;
 
-public abstract class BeltFunnelBlock extends HorizontalBlock implements IWrenchable, ISpecialBlockItemRequirement {
+public class BeltFunnelBlock extends AbstractFunnelBlock implements ISpecialBlockItemRequirement {
 
 	private BlockEntry<? extends FunnelBlock> parent;
-
-	public static final BooleanProperty POWERED = BlockStateProperties.POWERED;
 	public static final IProperty<Shape> SHAPE = EnumProperty.create("shape", Shape.class);
 
 	public enum Shape implements IStringSerializable {
@@ -57,7 +45,6 @@ public abstract class BeltFunnelBlock extends HorizontalBlock implements IWrench
 		EXTENDED(AllShapes.BELT_FUNNEL_EXTENDED),
 		PUSHING(AllShapes.BELT_FUNNEL_PERPENDICULAR),
 		PULLING(AllShapes.BELT_FUNNEL_PERPENDICULAR);
-//		CONNECTED(AllShapes.BELT_FUNNEL_CONNECTED); 
 
 		VoxelShaper shaper;
 
@@ -74,29 +61,12 @@ public abstract class BeltFunnelBlock extends HorizontalBlock implements IWrench
 	public BeltFunnelBlock(BlockEntry<? extends FunnelBlock> parent, Properties p_i48377_1_) {
 		super(p_i48377_1_);
 		this.parent = parent;
-		BlockState defaultState = getDefaultState().with(SHAPE, Shape.RETRACTED);
-		if (hasPoweredProperty())
-			defaultState = defaultState.with(POWERED, false);
-		setDefaultState(defaultState);
-	}
-
-	public abstract boolean hasPoweredProperty();
-
-	@Override
-	public boolean hasTileEntity(BlockState state) {
-		return true;
-	}
-
-	@Override
-	public TileEntity createTileEntity(BlockState state, IBlockReader world) {
-		return AllTileEntities.FUNNEL.create();
+		setDefaultState(getDefaultState().with(SHAPE, Shape.RETRACTED));
 	}
 
 	@Override
 	protected void fillStateContainer(Builder<Block, BlockState> p_206840_1_) {
-		if (hasPoweredProperty())
-			p_206840_1_.add(POWERED);
-		super.fillStateContainer(p_206840_1_.add(HORIZONTAL_FACING, SHAPE));
+		super.fillStateContainer(p_206840_1_.add(SHAPE));
 	}
 
 	@Override
@@ -105,46 +75,38 @@ public abstract class BeltFunnelBlock extends HorizontalBlock implements IWrench
 		return state.get(SHAPE).shaper.get(state.get(HORIZONTAL_FACING));
 	}
 
+	@Override
+	public VoxelShape getCollisionShape(BlockState p_220071_1_, IBlockReader p_220071_2_, BlockPos p_220071_3_,
+		ISelectionContext p_220071_4_) {
+		if (p_220071_4_.getEntity() instanceof ItemEntity
+			&& (p_220071_1_.get(SHAPE) == Shape.PULLING || p_220071_1_.get(SHAPE) == Shape.PUSHING))
+			return AllShapes.FUNNEL_COLLISION.get(getFacing(p_220071_1_));
+		return getShape(p_220071_1_, p_220071_2_, p_220071_3_, p_220071_4_);
+	}
+
 	@Override
 	public BlockState getStateForPlacement(BlockItemUseContext ctx) {
 		BlockState stateForPlacement = super.getStateForPlacement(ctx);
 		BlockPos pos = ctx.getPos();
 		World world = ctx.getWorld();
-		Direction facing = ctx.getPlayer() == null || ctx.getPlayer()
-			.isSneaking() ? ctx.getFace()
-				: ctx.getNearestLookingDirection()
-					.getOpposite();
-
-		if (hasPoweredProperty())
-			stateForPlacement = stateForPlacement.with(POWERED, world.isBlockPowered(pos));
+		Direction facing = ctx.getFace()
+			.getAxis()
+			.isHorizontal() ? ctx.getFace() : ctx.getPlacementHorizontalFacing();
 
 		BlockState state = stateForPlacement.with(HORIZONTAL_FACING, facing);
-		return state.with(SHAPE, getShapeForPosition(world, pos, facing));
+		boolean sneaking = ctx.getPlayer() != null && ctx.getPlayer()
+			.isSneaking();
+		return state.with(SHAPE, getShapeForPosition(world, pos, facing, !sneaking));
 	}
 
-	public static Shape getShapeForPosition(IBlockReader world, BlockPos pos, Direction facing) {
+	public static Shape getShapeForPosition(IBlockReader world, BlockPos pos, Direction facing, boolean extracting) {
 		BlockPos posBelow = pos.down();
 		BlockState stateBelow = world.getBlockState(posBelow);
+		Shape perpendicularState = extracting ? Shape.PUSHING : Shape.PULLING;
 		if (!AllBlocks.BELT.has(stateBelow))
-			return Shape.PUSHING;
+			return perpendicularState;
 		Direction movementFacing = stateBelow.get(BeltBlock.HORIZONTAL_FACING);
-		return movementFacing.getAxis() != facing.getAxis() ? Shape.PUSHING : Shape.RETRACTED;
-	}
-
-	@Override
-	public void onReplaced(BlockState state, World world, BlockPos pos, BlockState newState, boolean isMoving) {
-		if (state.hasTileEntity() && (state.getBlock() != newState.getBlock() && !FunnelBlock.isFunnel(newState)
-			|| !newState.hasTileEntity())) {
-			TileEntityBehaviour.destroy(world, pos, FilteringBehaviour.TYPE);
-			world.removeTileEntity(pos);
-		}
-	}
-
-	@Override
-	@OnlyIn(Dist.CLIENT)
-	public boolean addDestroyEffects(BlockState state, World world, BlockPos pos, ParticleManager manager) {
-		BlockHelper.addReducedDestroyEffects(state, world, pos, manager);
-		return true;
+		return movementFacing.getAxis() != facing.getAxis() ? perpendicularState : Shape.RETRACTED;
 	}
 
 	@Override
@@ -160,9 +122,12 @@ public abstract class BeltFunnelBlock extends HorizontalBlock implements IWrench
 			BlockState parentState = parent.getDefaultState();
 			if (state.has(POWERED) && state.get(POWERED))
 				parentState = parentState.with(POWERED, true);
-			return parentState.with(FunnelBlock.FACING, state.get(HORIZONTAL_FACING));
+			if (state.get(SHAPE) == Shape.PUSHING)
+				parentState = parentState.with(FunnelBlock.EXTRACTING, true);
+			return parentState.with(FunnelBlock.HORIZONTAL_FACING, state.get(HORIZONTAL_FACING));
 		}
-		Shape updatedShape = getShapeForPosition(world, pos, state.get(HORIZONTAL_FACING));
+		Shape updatedShape =
+			getShapeForPosition(world, pos, state.get(HORIZONTAL_FACING), state.get(SHAPE) == Shape.PUSHING);
 		Shape currentShape = state.get(SHAPE);
 		if (updatedShape == currentShape)
 			return state;
@@ -185,19 +150,6 @@ public abstract class BeltFunnelBlock extends HorizontalBlock implements IWrench
 		if (directBeltInputBehaviour == null)
 			return false;
 		return directBeltInputBehaviour.canSupportBeltFunnels();
-
-	}
-
-	@Override
-	public void neighborChanged(BlockState state, World worldIn, BlockPos pos, Block blockIn, BlockPos fromPos,
-		boolean isMoving) {
-		if (!hasPoweredProperty())
-			return;
-		if (worldIn.isRemote)
-			return;
-		boolean previouslyPowered = state.get(POWERED);
-		if (previouslyPowered != worldIn.isBlockPowered(pos))
-			worldIn.setBlockState(pos, state.cycle(POWERED), 2);
 	}
 
 	@Override
@@ -238,7 +190,7 @@ public abstract class BeltFunnelBlock extends HorizontalBlock implements IWrench
 		}
 		return ActionResultType.SUCCESS;
 	}
-	
+
 	@Override
 	public ItemRequirement getRequiredItems(BlockState state) {
 		return ItemRequirement.of(parent.getDefaultState());
diff --git a/src/main/java/com/simibubi/create/content/logistics/block/funnel/BrassBeltFunnelBlock.java b/src/main/java/com/simibubi/create/content/logistics/block/funnel/BrassBeltFunnelBlock.java
deleted file mode 100644
index 17dae6807b..0000000000
--- a/src/main/java/com/simibubi/create/content/logistics/block/funnel/BrassBeltFunnelBlock.java
+++ /dev/null
@@ -1,16 +0,0 @@
-package com.simibubi.create.content.logistics.block.funnel;
-
-import com.simibubi.create.AllBlocks;
-
-public class BrassBeltFunnelBlock extends BeltFunnelBlock {
-
-	public BrassBeltFunnelBlock(Properties p_i48377_1_) {
-		super(AllBlocks.BRASS_FUNNEL, p_i48377_1_);
-	}
-
-	@Override
-	public boolean hasPoweredProperty() {
-		return true;
-	}
-
-}
diff --git a/src/main/java/com/simibubi/create/content/logistics/block/funnel/BrassFunnelBlock.java b/src/main/java/com/simibubi/create/content/logistics/block/funnel/BrassFunnelBlock.java
index 6ad5e81f06..290c441542 100644
--- a/src/main/java/com/simibubi/create/content/logistics/block/funnel/BrassFunnelBlock.java
+++ b/src/main/java/com/simibubi/create/content/logistics/block/funnel/BrassFunnelBlock.java
@@ -15,7 +15,7 @@ public class BrassFunnelBlock extends FunnelBlock {
 
 	@Override
 	public BlockState getEquivalentBeltFunnel(IBlockReader world, BlockPos pos, BlockState state) {
-		Direction facing = state.get(FACING);
+		Direction facing = state.get(HORIZONTAL_FACING);
 		return AllBlocks.BRASS_BELT_FUNNEL.getDefaultState()
 			.with(BeltFunnelBlock.HORIZONTAL_FACING, facing)
 			.with(POWERED, state.get(POWERED));
diff --git a/src/main/java/com/simibubi/create/content/logistics/block/funnel/FunnelBlock.java b/src/main/java/com/simibubi/create/content/logistics/block/funnel/FunnelBlock.java
index c1cef9f52a..6f7da79858 100644
--- a/src/main/java/com/simibubi/create/content/logistics/block/funnel/FunnelBlock.java
+++ b/src/main/java/com/simibubi/create/content/logistics/block/funnel/FunnelBlock.java
@@ -1,15 +1,8 @@
 package com.simibubi.create.content.logistics.block.funnel;
 
-import javax.annotation.Nullable;
-
 import com.simibubi.create.AllBlocks;
+import com.simibubi.create.AllItems;
 import com.simibubi.create.AllShapes;
-import com.simibubi.create.AllTileEntities;
-import com.simibubi.create.foundation.block.ITE;
-import com.simibubi.create.foundation.block.ProperDirectionalBlock;
-import com.simibubi.create.foundation.tileEntity.TileEntityBehaviour;
-import com.simibubi.create.foundation.tileEntity.behaviour.filtering.FilteringBehaviour;
-import com.simibubi.create.foundation.tileEntity.behaviour.inventory.InvManipulationBehaviour;
 import com.simibubi.create.foundation.utility.VecHelper;
 
 import net.minecraft.block.Block;
@@ -19,10 +12,12 @@ import net.minecraft.entity.item.ItemEntity;
 import net.minecraft.entity.player.PlayerEntity;
 import net.minecraft.item.BlockItemUseContext;
 import net.minecraft.item.ItemStack;
+import net.minecraft.item.ItemUseContext;
 import net.minecraft.state.BooleanProperty;
+import net.minecraft.state.EnumProperty;
 import net.minecraft.state.StateContainer.Builder;
+import net.minecraft.state.properties.AttachFace;
 import net.minecraft.state.properties.BlockStateProperties;
-import net.minecraft.tileentity.TileEntity;
 import net.minecraft.util.ActionResultType;
 import net.minecraft.util.Direction;
 import net.minecraft.util.Direction.AxisDirection;
@@ -34,42 +29,47 @@ import net.minecraft.util.math.shapes.ISelectionContext;
 import net.minecraft.util.math.shapes.VoxelShape;
 import net.minecraft.world.IBlockReader;
 import net.minecraft.world.IWorld;
-import net.minecraft.world.IWorldReader;
 import net.minecraft.world.World;
 
-public abstract class FunnelBlock extends ProperDirectionalBlock implements ITE<FunnelTileEntity> {
+public abstract class FunnelBlock extends AbstractFunnelBlock {
 
-	public static final BooleanProperty POWERED = BlockStateProperties.POWERED;
+	public static final EnumProperty<AttachFace> FACE = BlockStateProperties.FACE;
+	public static final BooleanProperty EXTRACTING = BooleanProperty.create("extracting");
 
 	public FunnelBlock(Properties p_i48415_1_) {
 		super(p_i48415_1_);
-		setDefaultState(getDefaultState().with(POWERED, false));
+		setDefaultState(getDefaultState().with(FACE, AttachFace.WALL)
+			.with(EXTRACTING, false));
 	}
 
+	public abstract BlockState getEquivalentBeltFunnel(IBlockReader world, BlockPos pos, BlockState state);
+
 	@Override
 	public BlockState getStateForPlacement(BlockItemUseContext context) {
-		Direction facing = context.getPlayer() == null || context.getPlayer()
-			.isSneaking() ? context.getFace()
-				: context.getNearestLookingDirection()
-					.getOpposite();
-		return getDefaultState().with(FACING, facing)
-			.with(POWERED, context.getWorld()
-				.isBlockPowered(context.getPos()));
+		BlockState state = super.getStateForPlacement(context);
+
+		boolean sneak = context.getPlayer() != null && context.getPlayer()
+			.isSneaking();
+		state = state.with(EXTRACTING, !sneak);
+
+		for (Direction direction : context.getNearestLookingDirections()) {
+			BlockState blockstate;
+			if (direction.getAxis() == Direction.Axis.Y)
+				blockstate = state.with(FACE, direction == Direction.UP ? AttachFace.CEILING : AttachFace.FLOOR)
+					.with(HORIZONTAL_FACING, context.getPlacementHorizontalFacing());
+			else
+				blockstate = state.with(FACE, AttachFace.WALL)
+					.with(HORIZONTAL_FACING, direction.getOpposite());
+			if (blockstate.isValidPosition(context.getWorld(), context.getPos()))
+				return blockstate.with(POWERED, state.get(POWERED));
+		}
+
+		return state;
 	}
 
 	@Override
 	protected void fillStateContainer(Builder<Block, BlockState> builder) {
-		super.fillStateContainer(builder.add(POWERED));
-	}
-
-	@Override
-	public void neighborChanged(BlockState state, World worldIn, BlockPos pos, Block blockIn, BlockPos fromPos,
-		boolean isMoving) {
-		if (worldIn.isRemote)
-			return;
-		boolean previouslyPowered = state.get(POWERED);
-		if (previouslyPowered != worldIn.isBlockPowered(pos))
-			worldIn.setBlockState(pos, state.cycle(POWERED), 2);
+		super.fillStateContainer(builder.add(FACE, EXTRACTING));
 	}
 
 	@Override
@@ -79,6 +79,9 @@ public abstract class FunnelBlock extends ProperDirectionalBlock implements ITE<
 		ItemStack heldItem = player.getHeldItem(handIn);
 		boolean shouldntInsertItem = AllBlocks.MECHANICAL_ARM.isIn(heldItem) || !canInsertIntoFunnel(state);
 
+		if (AllItems.WRENCH.isIn(heldItem))
+			return ActionResultType.PASS;
+
 		if (hit.getFace() == getFunnelFacing(state) && !shouldntInsertItem) {
 			if (!worldIn.isRemote)
 				withTileEntityDo(worldIn, pos, te -> {
@@ -93,6 +96,14 @@ public abstract class FunnelBlock extends ProperDirectionalBlock implements ITE<
 		return ActionResultType.PASS;
 	}
 
+	@Override
+	public ActionResultType onWrenched(BlockState state, ItemUseContext context) {
+		World world = context.getWorld();
+		if (!world.isRemote)
+			world.setBlockState(context.getPos(), state.cycle(EXTRACTING));
+		return ActionResultType.SUCCESS;
+	}
+
 	@Override
 	public void onEntityCollision(BlockState state, World worldIn, BlockPos pos, Entity entityIn) {
 		if (worldIn.isRemote)
@@ -105,7 +116,7 @@ public abstract class FunnelBlock extends ProperDirectionalBlock implements ITE<
 			return;
 		ItemEntity itemEntity = (ItemEntity) entityIn;
 
-		Direction direction = state.get(FACING);
+		Direction direction = getFunnelFacing(state);
 		Vec3d diff = entityIn.getPositionVec()
 			.subtract(VecHelper.getCenterOf(pos));
 		double projectedDiff = direction.getAxis()
@@ -122,105 +133,44 @@ public abstract class FunnelBlock extends ProperDirectionalBlock implements ITE<
 			itemEntity.setItem(remainder);
 	}
 
-	public static ItemStack tryInsert(World worldIn, BlockPos pos, ItemStack toInsert, boolean simulate) {
-		FilteringBehaviour filter = TileEntityBehaviour.get(worldIn, pos, FilteringBehaviour.TYPE);
-		InvManipulationBehaviour inserter = TileEntityBehaviour.get(worldIn, pos, InvManipulationBehaviour.TYPE);
-		if (inserter == null)
-			return toInsert;
-		if (filter != null && !filter.test(toInsert))
-			return toInsert;
-		if (simulate)
-			inserter.simulate();
-		ItemStack insert = inserter.insert(toInsert);
-
-		if (!simulate && insert.getCount() != toInsert.getCount()) {
-			TileEntity tileEntity = worldIn.getTileEntity(pos);
-			if (tileEntity instanceof FunnelTileEntity)
-				((FunnelTileEntity) tileEntity).onTransfer(toInsert);
-		}
-
-		return insert;
+	protected boolean canInsertIntoFunnel(BlockState state) {
+		return !state.get(POWERED) && !state.get(EXTRACTING);
 	}
 
 	@Override
-	public boolean hasTileEntity(BlockState state) {
-		return true;
-	}
-
-	@Override
-	public TileEntity createTileEntity(BlockState state, IBlockReader world) {
-		return AllTileEntities.FUNNEL.create();
+	protected Direction getFacing(BlockState state) {
+		if (state.get(FACE) == AttachFace.CEILING)
+			return Direction.DOWN;
+		if (state.get(FACE) == AttachFace.FLOOR)
+			return Direction.UP;
+		return super.getFacing(state);
 	}
 
 	@Override
 	public VoxelShape getShape(BlockState state, IBlockReader world, BlockPos pos, ISelectionContext context) {
-		return AllShapes.FUNNEL.get(state.get(FACING));
+		AttachFace attachFace = state.get(FACE);
+		return attachFace == AttachFace.CEILING ? AllShapes.FUNNEL_CEILING
+			: attachFace == AttachFace.FLOOR ? AllShapes.FUNNEL_FLOOR
+				: AllShapes.FUNNEL.get(state.get(HORIZONTAL_FACING));
 	}
 
 	@Override
 	public VoxelShape getCollisionShape(BlockState state, IBlockReader world, BlockPos pos, ISelectionContext context) {
-		if (context.getEntity() instanceof ItemEntity)
-			return AllShapes.FUNNEL_COLLISION.get(state.get(FACING));
+		if (context.getEntity() instanceof ItemEntity && state.get(FACE) == AttachFace.WALL)
+			return AllShapes.FUNNEL_COLLISION.get(getFacing(state));
 		return getShape(state, world, pos, context);
 	}
 
 	@Override
 	public BlockState updatePostPlacement(BlockState state, Direction direction, BlockState p_196271_3_, IWorld world,
 		BlockPos pos, BlockPos p_196271_6_) {
-		Direction facing = state.get(FACING);
-		if (facing.getAxis()
-			.isHorizontal()) {
-			if (direction == Direction.DOWN) {
-				BlockState equivalentFunnel = getEquivalentBeltFunnel(null, null, state);
-				if (BeltFunnelBlock.isOnValidBelt(equivalentFunnel, world, pos))
-					return equivalentFunnel.with(BeltFunnelBlock.SHAPE,
-						BeltFunnelBlock.getShapeForPosition(world, pos, facing));
-			}
-		}
+		if (state.get(FACE) != AttachFace.WALL || direction != Direction.DOWN)
+			return state;
+		BlockState equivalentFunnel = getEquivalentBeltFunnel(null, null, state);
+		if (BeltFunnelBlock.isOnValidBelt(equivalentFunnel, world, pos))
+			return equivalentFunnel.with(BeltFunnelBlock.SHAPE,
+				BeltFunnelBlock.getShapeForPosition(world, pos, getFacing(state), state.get(EXTRACTING)));
 		return state;
 	}
 
-	public abstract BlockState getEquivalentBeltFunnel(IBlockReader world, BlockPos pos, BlockState state);
-
-	@Override
-	public boolean isValidPosition(BlockState state, IWorldReader world, BlockPos pos) {
-		Block block = world.getBlockState(pos.offset(state.get(FACING)
-			.getOpposite()))
-			.getBlock();
-		return !(block instanceof FunnelBlock) && !(block instanceof BeltFunnelBlock);
-	}
-
-	@Nullable
-	public static Direction getFunnelFacing(BlockState state) {
-		if (state.has(FACING))
-			return state.get(FACING);
-		if (state.has(BlockStateProperties.HORIZONTAL_FACING))
-			return state.get(BlockStateProperties.HORIZONTAL_FACING);
-		return null;
-	}
-
-	@Override
-	public void onReplaced(BlockState p_196243_1_, World p_196243_2_, BlockPos p_196243_3_, BlockState p_196243_4_,
-		boolean p_196243_5_) {
-		if (p_196243_1_.hasTileEntity() && (p_196243_1_.getBlock() != p_196243_4_.getBlock() && !isFunnel(p_196243_4_)
-			|| !p_196243_4_.hasTileEntity())) {
-			TileEntityBehaviour.destroy(p_196243_2_, p_196243_3_, FilteringBehaviour.TYPE);
-			p_196243_2_.removeTileEntity(p_196243_3_);
-		}
-	}
-
-	protected boolean canInsertIntoFunnel(BlockState state) {
-		return !state.get(POWERED);
-	}
-
-	@Nullable
-	public static boolean isFunnel(BlockState state) {
-		return state.getBlock() instanceof FunnelBlock || state.getBlock() instanceof BeltFunnelBlock;
-	}
-
-	@Override
-	public Class<FunnelTileEntity> getTileEntityClass() {
-		return FunnelTileEntity.class;
-	}
-
 }
diff --git a/src/main/java/com/simibubi/create/content/logistics/block/funnel/FunnelFilterSlotPositioning.java b/src/main/java/com/simibubi/create/content/logistics/block/funnel/FunnelFilterSlotPositioning.java
index f76caa4f00..450de2cc3c 100644
--- a/src/main/java/com/simibubi/create/content/logistics/block/funnel/FunnelFilterSlotPositioning.java
+++ b/src/main/java/com/simibubi/create/content/logistics/block/funnel/FunnelFilterSlotPositioning.java
@@ -4,14 +4,13 @@ import com.mojang.blaze3d.matrix.MatrixStack;
 import com.simibubi.create.content.logistics.block.funnel.BeltFunnelBlock.Shape;
 import com.simibubi.create.foundation.tileEntity.behaviour.ValueBoxTransform;
 import com.simibubi.create.foundation.utility.AngleHelper;
-import com.simibubi.create.foundation.utility.DirectionHelper;
 import com.simibubi.create.foundation.utility.MatrixStacker;
 import com.simibubi.create.foundation.utility.VecHelper;
 
 import net.minecraft.block.BlockState;
+import net.minecraft.state.properties.AttachFace;
 import net.minecraft.util.Direction;
 import net.minecraft.util.Direction.Axis;
-import net.minecraft.util.Direction.AxisDirection;
 import net.minecraft.util.math.Vec3d;
 
 public class FunnelFilterSlotPositioning extends ValueBoxTransform.Sided {
@@ -26,8 +25,6 @@ public class FunnelFilterSlotPositioning extends ValueBoxTransform.Sided {
 		if (state.getBlock() instanceof BeltFunnelBlock) {
 			switch (state.get(BeltFunnelBlock.SHAPE)) {
 
-//			case CONNECTED:
-//				return VecHelper.rotateCentered(VecHelper.voxelSpace(8, 15.5f, 8), stateAngle, Axis.Y);
 			case EXTENDED:
 				return VecHelper.rotateCentered(VecHelper.voxelSpace(8, 15.5f, 13), stateAngle, Axis.Y);
 			case PULLING:
@@ -39,66 +36,75 @@ public class FunnelFilterSlotPositioning extends ValueBoxTransform.Sided {
 			}
 		}
 
-		if (!funnelFacing.getAxis()
-			.isHorizontal()) {
-			Vec3d southLocation = VecHelper.voxelSpace(8, funnelFacing == Direction.DOWN ? 3 : 13, 15.5f);
-			return VecHelper.rotateCentered(southLocation, horizontalAngle, Axis.Y);
+		if (state.getBlock() instanceof FunnelBlock) {
+			if (state.get(FunnelBlock.FACE) == AttachFace.WALL)
+				return VecHelper.rotateCentered(VecHelper.voxelSpace(8, 12.1, 8.7f), horizontalAngle, Axis.Y);
+			Vec3d southLocation = VecHelper.voxelSpace(8, funnelFacing == Direction.DOWN ? 6.5f : 9.5f, 13f);
+			return VecHelper.rotateCentered(southLocation,
+				AngleHelper.horizontalAngle(state.get(AbstractFunnelBlock.HORIZONTAL_FACING)), Axis.Y);
 		}
 
-		Direction verticalDirection = DirectionHelper.rotateAround(getSide(), funnelFacing.rotateY()
-			.getAxis());
-		if (funnelFacing.getAxis() == Axis.Z)
-			verticalDirection = verticalDirection.getOpposite();
-		float yRot = -AngleHelper.horizontalAngle(verticalDirection) + 180;
-		float xRot = -90;
-		boolean alongX = funnelFacing.getAxis() == Axis.X;
-		float zRotLast = alongX ^ funnelFacing.getAxisDirection() == AxisDirection.POSITIVE ? 180 : 0;
+		return Vec3d.ZERO;
 
-		Vec3d vec = VecHelper.voxelSpace(8, 13, .5f);
-		vec = vec.subtract(.5, .5, .5);
-		vec = VecHelper.rotate(vec, zRotLast, Axis.Z);
-		vec = VecHelper.rotate(vec, yRot, Axis.Y);
-		vec = VecHelper.rotate(vec, alongX ? 0 : xRot, Axis.X);
-		vec = VecHelper.rotate(vec, alongX ? xRot : 0, Axis.Z);
-		vec = vec.add(.5, .5, .5);
-		return vec;
+//		if (!funnelFacing.getAxis()
+//			.isHorizontal()) {
+//			Vec3d southLocation = VecHelper.voxelSpace(8, funnelFacing == Direction.DOWN ? 3 : 13, 15.5f);
+//			return VecHelper.rotateCentered(southLocation, horizontalAngle, Axis.Y);
+//		}
+//
+//		Direction verticalDirection = DirectionHelper.rotateAround(getSide(), funnelFacing.rotateY()
+//			.getAxis());
+//		if (funnelFacing.getAxis() == Axis.Z)
+//			verticalDirection = verticalDirection.getOpposite();
+//		float yRot = -AngleHelper.horizontalAngle(verticalDirection) + 180;
+//		float xRot = -90;
+//		boolean alongX = funnelFacing.getAxis() == Axis.X;
+//		float zRotLast = alongX ^ funnelFacing.getAxisDirection() == AxisDirection.POSITIVE ? 180 : 0;
+//
+//		Vec3d vec = VecHelper.voxelSpace(8, 13, .5f);
+//		vec = vec.subtract(.5, .5, .5);
+//		vec = VecHelper.rotate(vec, zRotLast, Axis.Z);
+//		vec = VecHelper.rotate(vec, yRot, Axis.Y);
+//		vec = VecHelper.rotate(vec, alongX ? 0 : xRot, Axis.X);
+//		vec = VecHelper.rotate(vec, alongX ? xRot : 0, Axis.Z);
+//		vec = vec.add(.5, .5, .5);
+//		return vec;
 	}
 
 	@Override
 	protected void rotate(BlockState state, MatrixStack ms) {
 		Direction facing = FunnelBlock.getFunnelFacing(state);
 
-		if (facing.getAxis()
-			.isVertical()) {
-			super.rotate(state, ms);
-			return;
-		}
+//		if (facing.getAxis()
+//			.isVertical()) {
+//			super.rotate(state, ms);
+//			return;
+//		}
 
 		boolean isBeltFunnel = state.getBlock() instanceof BeltFunnelBlock;
 		if (isBeltFunnel && state.get(BeltFunnelBlock.SHAPE) != Shape.EXTENDED) {
 			Shape shape = state.get(BeltFunnelBlock.SHAPE);
 			super.rotate(state, ms);
 			if (shape == Shape.PULLING || shape == Shape.PUSHING)
-				MatrixStacker.of(ms).rotateX(-22.5f);
+				MatrixStacker.of(ms)
+					.rotateX(-22.5f);
 			return;
 		}
 
-		Direction verticalDirection = DirectionHelper.rotateAround(getSide(), facing.rotateY()
-			.getAxis());
-		if (facing.getAxis() == Axis.Z)
-			verticalDirection = verticalDirection.getOpposite();
-
-		float yRot = -AngleHelper.horizontalAngle(verticalDirection) + 180;
-		float xRot = -90;
-		boolean alongX = facing.getAxis() == Axis.X;
-		float zRotLast = alongX ^ facing.getAxisDirection() == AxisDirection.POSITIVE ? 180 : 0;
-
+		if (state.getBlock() instanceof FunnelBlock) {
+			if (state.get(FunnelBlock.FACE) == AttachFace.WALL) {
+				super.rotate(state, ms);
+				MatrixStacker.of(ms)
+					.rotateX(-22.5f);
+				return;
+			}
+		}
 
+		float yRot = AngleHelper.horizontalAngle(state.get(AbstractFunnelBlock.HORIZONTAL_FACING))
+			+ (facing == Direction.DOWN ? 180 : 0);
 		MatrixStacker.of(ms)
-			.rotateZ(alongX ? xRot : 0)
-			.rotateX(alongX ? 0 : xRot)
 			.rotateY(yRot)
-			.rotateZ(zRotLast);
+			.rotateX(facing == Direction.DOWN ? -90 : 90);
 	}
 
 	@Override
@@ -107,11 +113,9 @@ public class FunnelFilterSlotPositioning extends ValueBoxTransform.Sided {
 
 		if (facing == null)
 			return false;
-
-		if (state.getBlock() instanceof BeltFunnelBlock)
-			return state.get(BeltFunnelBlock.SHAPE) != Shape.EXTENDED ? direction == facing : direction == Direction.UP;
-
-		return direction.getAxis() != facing.getAxis();
+		if (state.getBlock() instanceof BeltFunnelBlock && state.get(BeltFunnelBlock.SHAPE) == Shape.EXTENDED)
+			return direction == Direction.UP;
+		return direction == facing;
 	}
 
 	@Override
diff --git a/src/main/java/com/simibubi/create/content/logistics/block/funnel/FunnelItem.java b/src/main/java/com/simibubi/create/content/logistics/block/funnel/FunnelItem.java
index cd372d7208..c7a0a6357f 100644
--- a/src/main/java/com/simibubi/create/content/logistics/block/funnel/FunnelItem.java
+++ b/src/main/java/com/simibubi/create/content/logistics/block/funnel/FunnelItem.java
@@ -1,13 +1,12 @@
 package com.simibubi.create.content.logistics.block.funnel;
 
-import com.simibubi.create.content.logistics.block.chute.ChuteTileEntity;
 import com.simibubi.create.foundation.advancement.AllTriggers;
 
 import net.minecraft.block.Block;
 import net.minecraft.block.BlockState;
 import net.minecraft.item.BlockItem;
 import net.minecraft.item.BlockItemUseContext;
-import net.minecraft.tileentity.TileEntity;
+import net.minecraft.state.properties.AttachFace;
 import net.minecraft.util.Direction;
 import net.minecraft.util.math.BlockPos;
 import net.minecraft.world.World;
@@ -39,15 +38,10 @@ public class FunnelItem extends BlockItem {
 			return state;
 		if (!(state.getBlock() instanceof FunnelBlock))
 			return state;
-		Direction direction = state.get(FunnelBlock.FACING);
-		if (!direction.getAxis()
-			.isHorizontal()) {
-			TileEntity tileEntity = world.getTileEntity(pos.offset(direction.getOpposite()));
-			if (tileEntity instanceof ChuteTileEntity && ((ChuteTileEntity) tileEntity).getItemMotion() > 0)
-				state = state.with(FunnelBlock.FACING, direction.getOpposite());
+		if (state.get(FunnelBlock.FACE) != AttachFace.WALL)
 			return state;
-		}
 
+		Direction direction = state.get(FunnelBlock.HORIZONTAL_FACING);
 		FunnelBlock block = (FunnelBlock) getBlock();
 		Block beltFunnelBlock = block.getEquivalentBeltFunnel(world, pos, state)
 			.getBlock();
diff --git a/src/main/java/com/simibubi/create/content/logistics/block/funnel/FunnelRenderer.java b/src/main/java/com/simibubi/create/content/logistics/block/funnel/FunnelRenderer.java
index ed0f46a090..df80295154 100644
--- a/src/main/java/com/simibubi/create/content/logistics/block/funnel/FunnelRenderer.java
+++ b/src/main/java/com/simibubi/create/content/logistics/block/funnel/FunnelRenderer.java
@@ -9,6 +9,7 @@ import com.simibubi.create.foundation.utility.MatrixStacker;
 import com.simibubi.create.foundation.utility.SuperByteBuffer;
 import com.simibubi.create.foundation.utility.VecHelper;
 
+import net.minecraft.block.BlockState;
 import net.minecraft.client.renderer.IRenderTypeBuffer;
 import net.minecraft.client.renderer.RenderType;
 import net.minecraft.client.renderer.tileentity.TileEntityRendererDispatcher;
@@ -29,12 +30,14 @@ public class FunnelRenderer extends SmartTileEntityRenderer<FunnelTileEntity> {
 		if (!te.hasFlap())
 			return;
 
+		BlockState blockState = te.getBlockState();
 		IVertexBuilder vb = buffer.getBuffer(RenderType.getSolid());
-		SuperByteBuffer flapBuffer = AllBlockPartials.BELT_FUNNEL_FLAP.renderOn(te.getBlockState());
+		SuperByteBuffer flapBuffer = (blockState.getBlock() instanceof FunnelBlock ? AllBlockPartials.FUNNEL_FLAP
+			: AllBlockPartials.BELT_FUNNEL_FLAP).renderOn(blockState);
 		Vec3d pivot = VecHelper.voxelSpace(0, 10, 9.5f);
 		MatrixStacker msr = MatrixStacker.of(ms);
 
-		float horizontalAngle = AngleHelper.horizontalAngle(FunnelBlock.getFunnelFacing(te.getBlockState())
+		float horizontalAngle = AngleHelper.horizontalAngle(FunnelBlock.getFunnelFacing(blockState)
 			.getOpposite());
 		float f = te.flap.get(partialTicks);
 
@@ -43,7 +46,7 @@ public class FunnelRenderer extends SmartTileEntityRenderer<FunnelTileEntity> {
 			.rotateY(horizontalAngle)
 			.unCentre();
 		ms.translate(0, 0, -te.getFlapOffset());
-		
+
 		for (int segment = 0; segment <= 3; segment++) {
 			ms.push();
 
diff --git a/src/main/java/com/simibubi/create/content/logistics/block/funnel/FunnelTileEntity.java b/src/main/java/com/simibubi/create/content/logistics/block/funnel/FunnelTileEntity.java
index 0404626ca2..0a820f5eb7 100644
--- a/src/main/java/com/simibubi/create/content/logistics/block/funnel/FunnelTileEntity.java
+++ b/src/main/java/com/simibubi/create/content/logistics/block/funnel/FunnelTileEntity.java
@@ -1,8 +1,7 @@
 package com.simibubi.create.content.logistics.block.funnel;
 
+import java.lang.ref.WeakReference;
 import java.util.List;
-import java.util.function.Function;
-import java.util.function.Predicate;
 
 import com.simibubi.create.AllBlocks;
 import com.simibubi.create.content.contraptions.components.saw.SawTileEntity;
@@ -20,33 +19,38 @@ import com.simibubi.create.foundation.tileEntity.TileEntityBehaviour;
 import com.simibubi.create.foundation.tileEntity.behaviour.belt.DirectBeltInputBehaviour;
 import com.simibubi.create.foundation.tileEntity.behaviour.filtering.FilteringBehaviour;
 import com.simibubi.create.foundation.tileEntity.behaviour.inventory.InvManipulationBehaviour;
-import com.simibubi.create.foundation.tileEntity.behaviour.inventory.InvManipulationBehaviour.InterfaceProvider;
+import com.simibubi.create.foundation.utility.BlockFace;
+import com.simibubi.create.foundation.utility.VecHelper;
 
 import net.minecraft.block.BlockState;
+import net.minecraft.entity.item.ItemEntity;
 import net.minecraft.item.ItemStack;
 import net.minecraft.nbt.CompoundNBT;
+import net.minecraft.state.properties.AttachFace;
 import net.minecraft.state.properties.BlockStateProperties;
 import net.minecraft.tileentity.TileEntity;
 import net.minecraft.tileentity.TileEntityType;
 import net.minecraft.util.Direction;
+import net.minecraft.util.math.AxisAlignedBB;
 import net.minecraft.util.math.BlockPos;
+import net.minecraft.util.math.Vec3d;
 import net.minecraftforge.common.util.LazyOptional;
 import net.minecraftforge.items.CapabilityItemHandler;
 import net.minecraftforge.items.IItemHandler;
-import net.minecraftforge.items.ItemHandlerHelper;
 
 public class FunnelTileEntity extends SmartTileEntity implements IHaveHoveringInformation {
 
 	private FilteringBehaviour filtering;
 	private InvManipulationBehaviour invManipulation;
-	private InvManipulationBehaviour autoExtractor;
 	private int extractionCooldown;
 
+	private WeakReference<ItemEntity> lastObserved; // In-world Extractors only
+
 	int sendFlap;
 	InterpolatedChasingValue flap;
 
 	static enum Mode {
-		INVALID, PAUSED, COLLECT, PUSHING_TO_BELT, TAKING_FROM_BELT, HOPPER
+		INVALID, PAUSED, COLLECT, PUSHING_TO_BELT, TAKING_FROM_BELT, EXTRACT
 	}
 
 	public FunnelTileEntity(TileEntityType<?> tileEntityTypeIn) {
@@ -63,8 +67,6 @@ public class FunnelTileEntity extends SmartTileEntity implements IHaveHoveringIn
 			return Mode.INVALID;
 		if (state.has(BlockStateProperties.POWERED) && state.get(BlockStateProperties.POWERED))
 			return Mode.PAUSED;
-		if (FunnelBlock.getFunnelFacing(state) == Direction.UP && autoExtractor.hasInventory())
-			return Mode.HOPPER;
 		if (state.getBlock() instanceof BeltFunnelBlock) {
 			Shape shape = state.get(BeltFunnelBlock.SHAPE);
 			if (shape == Shape.PULLING)
@@ -76,8 +78,12 @@ public class FunnelTileEntity extends SmartTileEntity implements IHaveHoveringIn
 			if (belt != null)
 				return belt.getMovementFacing() == state.get(BeltFunnelBlock.HORIZONTAL_FACING) ? Mode.PUSHING_TO_BELT
 					: Mode.TAKING_FROM_BELT;
+			return Mode.INVALID;
 		}
-		return Mode.COLLECT;
+		if (state.getBlock() instanceof FunnelBlock)
+			return state.get(FunnelBlock.EXTRACTING) ? Mode.EXTRACT : Mode.COLLECT;
+
+		return Mode.INVALID;
 	}
 
 	@Override
@@ -101,40 +107,87 @@ public class FunnelTileEntity extends SmartTileEntity implements IHaveHoveringIn
 
 		if (mode == Mode.PUSHING_TO_BELT)
 			activateExtractingBeltFunnel();
-		if (mode == Mode.HOPPER)
-			activateHopper();
+		if (mode == Mode.EXTRACT)
+			activateExtractor();
 	}
 
-	private void activateHopper() {
-		if (!invManipulation.hasInventory())
-			return;
-		int amountToExtract = autoExtractor.getAmountFromFilter();
-		if (!filtering.isActive())
-			amountToExtract = 1;
+	private void activateExtractor() {
+		BlockState blockState = getBlockState();
+		Direction facing = AbstractFunnelBlock.getFunnelFacing(blockState);
 
-		Predicate<ItemStack> filter = s -> !filtering.isActive() || filtering.test(s);
-		Function<ItemStack, Integer> amountThreshold = s -> {
-			int maxStackSize = s.getMaxStackSize();
-			return maxStackSize - invManipulation.simulate()
-				.insert(ItemHandlerHelper.copyStackWithSize(s, maxStackSize))
-				.getCount();
-		};
-
-		if (amountToExtract != -1 && !invManipulation.simulate()
-			.insert(autoExtractor.simulate()
-				.extract(amountToExtract, filter))
-			.isEmpty())
+		if (facing == null)
 			return;
 
-		ItemStack stack = autoExtractor.extract(amountToExtract, filter, amountThreshold);
+		boolean trackingEntityPresent = true;
+		AxisAlignedBB area = getEntityOverflowScanningArea();
+
+		// Check if last item is still blocking the extractor
+		if (lastObserved == null) {
+			trackingEntityPresent = false;
+		} else {
+			ItemEntity lastEntity = lastObserved.get();
+			if (lastEntity == null || !lastEntity.isAlive() || !lastEntity.getBoundingBox()
+				.intersects(area)) {
+				trackingEntityPresent = false;
+				lastObserved = null;
+			}
+		}
+
+		if (trackingEntityPresent)
+			return;
+
+		// Find other entities blocking the extract (only if necessary)
+		int amountToExtract = getAmountToExtract();
+		ItemStack stack = invManipulation.simulate()
+			.extract(amountToExtract);
+		if (stack.isEmpty())
+			return;
+		for (ItemEntity itemEntity : world.getEntitiesWithinAABB(ItemEntity.class, area)) {
+			lastObserved = new WeakReference<>(itemEntity);
+			return;
+		}
+
+		// Extract
+		stack = invManipulation.extract(amountToExtract);
 		if (stack.isEmpty())
 			return;
 
+		flap(false);
 		onTransfer(stack);
-		invManipulation.insert(stack);
+
+		Vec3d outputPos = VecHelper.getCenterOf(pos);
+		boolean vertical = facing.getAxis()
+			.isVertical();
+		boolean up = facing == Direction.UP;
+
+		outputPos = outputPos.add(new Vec3d(facing.getDirectionVec()).scale(vertical ? up ? .15f : .5f : .25f));
+		if (!vertical)
+			outputPos = outputPos.subtract(0, .45f, 0);
+
+		Vec3d motion = Vec3d.ZERO;
+		if (up)
+			motion = new Vec3d(0, 4 / 16f, 0);
+
+		ItemEntity item = new ItemEntity(world, outputPos.x, outputPos.y, outputPos.z, stack.copy());
+		item.setDefaultPickupDelay();
+		item.setMotion(motion);
+		world.addEntity(item);
+		lastObserved = new WeakReference<>(item);
+
 		startCooldown();
 	}
 
+	static final AxisAlignedBB coreBB =
+		new AxisAlignedBB(VecHelper.CENTER_OF_ORIGIN, VecHelper.CENTER_OF_ORIGIN).grow(.75f);
+
+	private AxisAlignedBB getEntityOverflowScanningArea() {
+		Direction facing = AbstractFunnelBlock.getFunnelFacing(getBlockState());
+		AxisAlignedBB bb = coreBB.offset(pos);
+		if (facing == null || facing == Direction.UP)
+			return bb;
+		return bb.expand(0, -1, 0);
+	}
+
 	private void activateExtractingBeltFunnel() {
 		BlockState blockState = getBlockState();
 		Direction facing = blockState.get(BeltFunnelBlock.HORIZONTAL_FACING);
@@ -172,10 +225,10 @@ public class FunnelTileEntity extends SmartTileEntity implements IHaveHoveringIn
 
 	@Override
 	public void addBehaviours(List<TileEntityBehaviour> behaviours) {
-		invManipulation = new InvManipulationBehaviour(this, InterfaceProvider.oppositeOfBlockFacing());
+		invManipulation =
+			new InvManipulationBehaviour(this, (w, p, s) -> new BlockFace(p, AbstractFunnelBlock.getFunnelFacing(s)
+				.getOpposite()));
 		behaviours.add(invManipulation);
-		autoExtractor = InvManipulationBehaviour.forExtraction(this, InterfaceProvider.towardBlockFacing());
-		behaviours.add(autoExtractor);
 
 		filtering = new FilteringBehaviour(this, new FunnelFilterSlotPositioning());
 		filtering.showCountWhen(this::supportsAmountOnFilter);
@@ -196,10 +249,8 @@ public class FunnelTileEntity extends SmartTileEntity implements IHaveHoveringIn
 			else
 				beltFunnelsupportsAmount = BeltHelper.getSegmentTE(world, pos.down()) != null;
 		}
-		boolean hopper = FunnelBlock.getFunnelFacing(blockState) == Direction.UP && !world.getBlockState(pos.up())
-			.getMaterial()
-			.isReplaceable();
-		return beltFunnelsupportsAmount || hopper;
+		boolean extractor = blockState.getBlock() instanceof FunnelBlock && blockState.get(FunnelBlock.EXTRACTING);
+		return beltFunnelsupportsAmount || extractor;
 	}
 
 	private boolean supportsDirectBeltInput(Direction side) {
@@ -208,8 +259,7 @@ public class FunnelTileEntity extends SmartTileEntity implements IHaveHoveringIn
 			return false;
 		if (!(blockState.getBlock() instanceof FunnelBlock))
 			return false;
-		Direction direction = blockState.get(FunnelBlock.FACING);
-		return direction == Direction.UP || direction == side.getOpposite();
+		return blockState.get(FunnelBlock.FACE) == AttachFace.FLOOR;
 	}
 
 	private boolean supportsFiltering() {
@@ -237,7 +287,9 @@ public class FunnelTileEntity extends SmartTileEntity implements IHaveHoveringIn
 
 	public boolean hasFlap() {
 		BlockState blockState = getBlockState();
-		if (!(blockState.getBlock() instanceof BeltFunnelBlock))
+		if (!AbstractFunnelBlock.getFunnelFacing(blockState)
+			.getAxis()
+			.isHorizontal())
 			return false;
 		return true;
 	}
@@ -245,7 +297,7 @@ public class FunnelTileEntity extends SmartTileEntity implements IHaveHoveringIn
 	public float getFlapOffset() {
 		BlockState blockState = getBlockState();
 		if (!(blockState.getBlock() instanceof BeltFunnelBlock))
-			return 0;
+			return -1 / 16f;
 		switch (blockState.get(BeltFunnelBlock.SHAPE)) {
 		default:
 		case RETRACTED:
diff --git a/src/main/java/com/simibubi/create/content/logistics/block/mechanicalArm/ArmInteractionPoint.java b/src/main/java/com/simibubi/create/content/logistics/block/mechanicalArm/ArmInteractionPoint.java
index de5677b643..7b4643ef0f 100644
--- a/src/main/java/com/simibubi/create/content/logistics/block/mechanicalArm/ArmInteractionPoint.java
+++ b/src/main/java/com/simibubi/create/content/logistics/block/mechanicalArm/ArmInteractionPoint.java
@@ -15,6 +15,7 @@ import com.simibubi.create.content.contraptions.components.deployer.DeployerBloc
 import com.simibubi.create.content.contraptions.components.saw.SawBlock;
 import com.simibubi.create.content.contraptions.processing.burner.BlazeBurnerBlock;
 import com.simibubi.create.content.logistics.block.belts.tunnel.BeltTunnelBlock;
+import com.simibubi.create.content.logistics.block.chute.AbstractChuteBlock;
 import com.simibubi.create.content.logistics.block.funnel.FunnelBlock;
 import com.simibubi.create.content.logistics.block.funnel.FunnelTileEntity;
 import com.simibubi.create.foundation.advancement.AllTriggers;
@@ -280,11 +281,15 @@ public abstract class ArmInteractionPoint {
 		@Override
 		ItemStack insert(World world, ItemStack stack, boolean simulate) {
 			ItemStack input = stack.copy();
-			if (!BlazeBurnerBlock.tryInsert(state, world, pos, input, false, true).getResult().isEmpty()) {
+			if (!BlazeBurnerBlock.tryInsert(state, world, pos, input, false, true)
+				.getResult()
+				.isEmpty()) {
 				return stack;
 			}
 			ActionResult<ItemStack> res = BlazeBurnerBlock.tryInsert(state, world, pos, input, false, simulate);
-			return res.getType() == ActionResultType.SUCCESS ? ItemHandlerHelper.copyStackWithSize(stack, stack.getCount() - 1) : stack;
+			return res.getType() == ActionResultType.SUCCESS
+				? ItemHandlerHelper.copyStackWithSize(stack, stack.getCount() - 1)
+				: stack;
 		}
 
 		@Override
@@ -405,7 +410,7 @@ public abstract class ArmInteractionPoint {
 
 		@Override
 		boolean isValid(IBlockReader reader, BlockPos pos, BlockState state) {
-			return AllBlocks.CHUTE.has(state);
+			return AbstractChuteBlock.isChute(state);
 		}
 	}
 
@@ -415,7 +420,7 @@ public abstract class ArmInteractionPoint {
 		Vec3d getInteractionPositionVector() {
 			return VecHelper.getCenterOf(pos)
 				.add(new Vec3d(FunnelBlock.getFunnelFacing(state)
-					.getDirectionVec()).scale(.5f));
+					.getDirectionVec()).scale(-.15f));
 		}
 
 		@Override
@@ -450,15 +455,19 @@ public abstract class ArmInteractionPoint {
 			ItemStack insert = inserter.insert(stack);
 			if (!simulate && insert.getCount() != stack.getCount()) {
 				TileEntity tileEntity = world.getTileEntity(pos);
-				if (tileEntity instanceof FunnelTileEntity)
-					((FunnelTileEntity) tileEntity).onTransfer(stack);
+				if (tileEntity instanceof FunnelTileEntity) {
+					FunnelTileEntity funnelTileEntity = (FunnelTileEntity) tileEntity;
+					funnelTileEntity.onTransfer(stack);
+					if (funnelTileEntity.hasFlap())
+						funnelTileEntity.flap(true);
+				}
 			}
 			return insert;
 		}
 
 		@Override
 		boolean isValid(IBlockReader reader, BlockPos pos, BlockState state) {
-			return state.getBlock() instanceof FunnelBlock;
+			return state.getBlock() instanceof FunnelBlock && !state.get(FunnelBlock.EXTRACTING);
 		}
 
 		@Override
diff --git a/src/main/java/com/simibubi/create/content/logistics/block/mechanicalArm/ArmTileEntity.java b/src/main/java/com/simibubi/create/content/logistics/block/mechanicalArm/ArmTileEntity.java
index 7d72c4ff13..6a65e0e26a 100644
--- a/src/main/java/com/simibubi/create/content/logistics/block/mechanicalArm/ArmTileEntity.java
+++ b/src/main/java/com/simibubi/create/content/logistics/block/mechanicalArm/ArmTileEntity.java
@@ -102,16 +102,22 @@ public class ArmTileEntity extends KineticTileEntity {
 	public void tick() {
 		super.tick();
 		initInteractionPoints();
-		tickMovementProgress();
+		boolean targetReached = tickMovementProgress();
 
 		if (world.isRemote)
 			return;
 		if (chasedPointProgress < 1)
 			return;
+		
 		if (phase == Phase.MOVE_TO_INPUT)
 			collectItem();
-		if (phase == Phase.MOVE_TO_OUTPUT)
+		else if (phase == Phase.MOVE_TO_OUTPUT)
 			depositItem();
+		else if (phase == Phase.SEARCH_INPUTS || phase == Phase.DANCING)
+			searchForItem();
+		
+		if (targetReached)
+			lazyTick();
 	}
 
 	@Override
@@ -122,10 +128,8 @@ public class ArmTileEntity extends KineticTileEntity {
 			return;
 		if (chasedPointProgress < .5f)
 			return;
-		if (phase == Phase.SEARCH_INPUTS || phase == Phase.DANCING) {
+		if (phase == Phase.SEARCH_INPUTS || phase == Phase.DANCING) 
 			checkForMusic();
-			searchForItem();
-		}
 		if (phase == Phase.SEARCH_OUTPUTS)
 			searchForDestination();
 	}
@@ -156,12 +160,13 @@ public class ArmTileEntity extends KineticTileEntity {
 		return false;
 	}
 
-	private void tickMovementProgress() {
+	private boolean tickMovementProgress() {
+		boolean targetReachedPreviously = chasedPointProgress >= 1; 
 		chasedPointProgress += Math.min(256, Math.abs(getSpeed())) / 1024f;
 		if (chasedPointProgress > 1)
 			chasedPointProgress = 1;
 		if (!world.isRemote)
-			return;
+			return !targetReachedPreviously && chasedPointProgress >= 1;
 
 		ArmInteractionPoint targetedInteractionPoint = getTargetedInteractionPoint();
 		ArmAngleTarget previousTarget = this.previousTarget;
@@ -182,6 +187,7 @@ public class ArmTileEntity extends KineticTileEntity {
 		upperArmAngle.set(MathHelper.lerp(progress, previousTarget.upperArmAngle, target.upperArmAngle));
 
 		headAngle.set(AngleHelper.angleLerp(progress, previousTarget.headAngle % 360, target.headAngle % 360));
+		return false;
 	}
 
 	protected boolean isOnCeiling() {
diff --git a/src/main/java/com/simibubi/create/content/logistics/block/redstone/RedstoneLinkBlock.java b/src/main/java/com/simibubi/create/content/logistics/block/redstone/RedstoneLinkBlock.java
index 8d645f75b7..de0eb97b44 100644
--- a/src/main/java/com/simibubi/create/content/logistics/block/redstone/RedstoneLinkBlock.java
+++ b/src/main/java/com/simibubi/create/content/logistics/block/redstone/RedstoneLinkBlock.java
@@ -168,9 +168,7 @@ public class RedstoneLinkBlock extends ProperDirectionalBlock implements ITE<Red
 		BlockPos neighbourPos = pos.offset(state.get(FACING)
 			.getOpposite());
 		BlockState neighbour = worldIn.getBlockState(neighbourPos);
-		if (FunnelBlock.isFunnel(neighbour))
-			return true;
-		return Block.hasSolidSide(neighbour, worldIn, neighbourPos, state.get(FACING));
+		return !neighbour.getMaterial().isReplaceable();
 	}
 
 	@Override
diff --git a/src/main/java/com/simibubi/create/foundation/data/BlockStateGen.java b/src/main/java/com/simibubi/create/foundation/data/BlockStateGen.java
index abc1d0cd2e..f463590d3a 100644
--- a/src/main/java/com/simibubi/create/foundation/data/BlockStateGen.java
+++ b/src/main/java/com/simibubi/create/foundation/data/BlockStateGen.java
@@ -139,6 +139,16 @@ public class BlockStateGen {
 			}, BlockStateProperties.WATERLOGGED);
 	}
 
+	public static <T extends Block> void simpleBlock(DataGenContext<Block, T> ctx, RegistrateBlockstateProvider prov,
+		Function<BlockState, ModelFile> modelFunc) {
+		prov.getVariantBuilder(ctx.getEntry())
+			.forAllStatesExcept(state -> {
+				return ConfiguredModel.builder()
+					.modelFile(modelFunc.apply(state))
+					.build();
+			}, BlockStateProperties.WATERLOGGED);
+	}
+
 	public static <T extends Block> void horizontalAxisBlock(DataGenContext<Block, T> ctx,
 		RegistrateBlockstateProvider prov, Function<BlockState, ModelFile> modelFunc) {
 		prov.getVariantBuilder(ctx.getEntry())
diff --git a/src/main/java/com/simibubi/create/foundation/data/BuilderTransformers.java b/src/main/java/com/simibubi/create/foundation/data/BuilderTransformers.java
index d8417ee9cc..1947517c15 100644
--- a/src/main/java/com/simibubi/create/foundation/data/BuilderTransformers.java
+++ b/src/main/java/com/simibubi/create/foundation/data/BuilderTransformers.java
@@ -36,7 +36,6 @@ import net.minecraft.block.BlockState;
 import net.minecraft.client.renderer.RenderType;
 import net.minecraft.item.DyeColor;
 import net.minecraft.item.Item;
-import net.minecraft.state.properties.BlockStateProperties;
 import net.minecraft.state.properties.PistonType;
 import net.minecraft.util.Direction;
 import net.minecraft.util.Direction.Axis;
@@ -105,23 +104,30 @@ public class BuilderTransformers {
 		return b -> {
 			return b.blockstate((c, p) -> {
 				Function<BlockState, ModelFile> model = s -> {
-					String powered =
-						s.has(BlockStateProperties.POWERED) && s.get(BlockStateProperties.POWERED) ? "_powered" : "";
+					String powered = s.get(FunnelBlock.POWERED) ? "_powered" : "";
+					String extracting = s.get(FunnelBlock.EXTRACTING) ? "_push" : "_pull";
+					String face = s.get(FunnelBlock.FACE)
+						.getName();
 					return p.models()
-						.withExistingParent("block/" + type + "_funnel" + powered, p.modLoc("block/funnel/block"))
-						.texture("0", p.modLoc("block/" + type + "_funnel_plating"))
-						.texture("1", particleTexture)
-						.texture("2", p.modLoc("block/" + type + "_funnel" + powered))
+						.withExistingParent("block/" + type + "_funnel_" + face + extracting + powered,
+							p.modLoc("block/funnel/block_" + face))
+						.texture("particle", particleTexture)
+						.texture("7", p.modLoc("block/" + type + "_funnel_plating"))
+						.texture("6", p.modLoc("block/" + type + "_funnel" + powered))
+						.texture("5", p.modLoc("block/" + type + "_funnel_tall" + powered))
+						.texture("2_2", p.modLoc("block/" + type + "_funnel" + extracting))
 						.texture("3", p.modLoc("block/" + type + "_funnel_back"));
 				};
-				p.directionalBlock(c.get(), model);
+				p.horizontalFaceBlock(c.get(), model);
 			})
 				.item(FunnelItem::new)
 				.model((c, p) -> {
 					p.withExistingParent("item/" + type + "_funnel", p.modLoc("block/funnel/item"))
-						.texture("0", p.modLoc("block/" + type + "_funnel_plating"))
-						.texture("1", particleTexture)
-						.texture("2", p.modLoc("block/" + type + "_funnel"))
+						.texture("particle", particleTexture)
+						.texture("7", p.modLoc("block/" + type + "_funnel_plating"))
+						.texture("2", p.modLoc("block/" + type + "_funnel_neutral"))
+						.texture("6", p.modLoc("block/" + type + "_funnel"))
+						.texture("5", p.modLoc("block/" + type + "_funnel_tall"))
 						.texture("3", p.modLoc("block/" + type + "_funnel_back"));
 				})
 				.build();
diff --git a/src/main/java/com/simibubi/create/foundation/data/recipe/StandardRecipeGen.java b/src/main/java/com/simibubi/create/foundation/data/recipe/StandardRecipeGen.java
index 96ac8ca888..498d58552e 100644
--- a/src/main/java/com/simibubi/create/foundation/data/recipe/StandardRecipeGen.java
+++ b/src/main/java/com/simibubi/create/foundation/data/recipe/StandardRecipeGen.java
@@ -1,11 +1,11 @@
 package com.simibubi.create.foundation.data.recipe;
 
 import static com.simibubi.create.foundation.data.recipe.Mods.IE;
+import static com.simibubi.create.foundation.data.recipe.Mods.INF;
 import static com.simibubi.create.foundation.data.recipe.Mods.MEK;
 import static com.simibubi.create.foundation.data.recipe.Mods.MW;
 import static com.simibubi.create.foundation.data.recipe.Mods.SM;
 import static com.simibubi.create.foundation.data.recipe.Mods.TH;
-import static com.simibubi.create.foundation.data.recipe.Mods.INF;
 
 import java.util.ArrayList;
 import java.util.List;
@@ -22,7 +22,6 @@ import com.simibubi.create.AllTags.AllItemTags;
 import com.simibubi.create.Create;
 import com.simibubi.create.content.AllSections;
 import com.simibubi.create.content.palettes.AllPaletteBlocks;
-import com.simibubi.create.foundation.data.recipe.CreateRecipeProvider.I;
 import com.simibubi.create.foundation.utility.Lang;
 import com.tterrag.registrate.util.entry.BlockEntry;
 import com.tterrag.registrate.util.entry.ItemEntry;
@@ -568,6 +567,14 @@ public class StandardRecipeGen extends CreateRecipeProvider {
 				.patternLine("II")
 				.patternLine("AA")),
 
+		SMART_CHUTE = create(AllBlocks.SMART_CHUTE).unlockedBy(AllBlocks.CHUTE::get)
+			.viaShaped(b -> b.key('P', I.electronTube())
+				.key('S', AllBlocks.CHUTE.get())
+				.key('I', I.brassSheet())
+				.patternLine("I")
+				.patternLine("S")
+				.patternLine("P")),
+
 		DEPOT = create(AllBlocks.DEPOT).unlockedBy(I::andesiteCasing)
 			.viaShaped(b -> b.key('A', I.andesite())
 				.key('I', I.andesiteCasing())
diff --git a/src/main/java/com/simibubi/create/foundation/tileEntity/behaviour/filtering/FilteringHandler.java b/src/main/java/com/simibubi/create/foundation/tileEntity/behaviour/filtering/FilteringHandler.java
index 77b6de8b00..dd605d425c 100644
--- a/src/main/java/com/simibubi/create/foundation/tileEntity/behaviour/filtering/FilteringHandler.java
+++ b/src/main/java/com/simibubi/create/foundation/tileEntity/behaviour/filtering/FilteringHandler.java
@@ -1,5 +1,7 @@
 package com.simibubi.create.foundation.tileEntity.behaviour.filtering;
 
+import com.simibubi.create.AllBlocks;
+import com.simibubi.create.AllItems;
 import com.simibubi.create.AllKeys;
 import com.simibubi.create.content.logistics.item.filter.FilterItem;
 import com.simibubi.create.foundation.tileEntity.TileEntityBehaviour;
@@ -66,6 +68,11 @@ public class FilteringHandler {
 		ItemStack toApply = player.getHeldItem(hand)
 			.copy();
 
+		if (AllItems.WRENCH.isIn(toApply))
+			return;
+		if (AllBlocks.MECHANICAL_ARM.isIn(toApply))
+			return;
+		
 		if (event.getSide() != LogicalSide.CLIENT) {
 			if (!player.isCreative()) {
 				if (behaviour.getFilter()
diff --git a/src/main/java/com/simibubi/create/foundation/tileEntity/behaviour/filtering/FilteringRenderer.java b/src/main/java/com/simibubi/create/foundation/tileEntity/behaviour/filtering/FilteringRenderer.java
index 025ad5a42c..3be5ab7850 100644
--- a/src/main/java/com/simibubi/create/foundation/tileEntity/behaviour/filtering/FilteringRenderer.java
+++ b/src/main/java/com/simibubi/create/foundation/tileEntity/behaviour/filtering/FilteringRenderer.java
@@ -75,7 +75,7 @@ public class FilteringRenderer {
 
 		box.offsetLabel(behaviour.textShift)
 			.withColors(fluids ? 0x407088 : 0x7A6A2C, fluids ? 0x70adb5 : 0xB79D64)
-			.scrollTooltip(showCount ? "[" + Lang.translate("action.scroll") + "]" : "")
+			.scrollTooltip(showCount && !isFilterSlotted ? "[" + Lang.translate("action.scroll") + "]" : "")
 			.passive(!hit);
 
 		CreateClient.outliner.showValueBox(Pair.of("filter", pos), box.transform(behaviour.slotPositioning))
diff --git a/src/main/resources/assets/create/lang/default/messages.json b/src/main/resources/assets/create/lang/default/messages.json
index 59999f0d3d..9af5471be2 100644
--- a/src/main/resources/assets/create/lang/default/messages.json
+++ b/src/main/resources/assets/create/lang/default/messages.json
@@ -450,6 +450,7 @@
 	"create.tooltip.chute.fans_push_down": "Fans push from Above",
 	"create.tooltip.chute.fans_pull_up": "Fans pull from Above",
 	"create.tooltip.chute.fans_pull_down": "Fans pull from Below",
+	"create.tooltip.chute.contains": "Contains: %1$s x%2$s",
 	
 	"create.hint.hose_pulley.title": "Bottomless Supply",
 	"create.hint.hose_pulley": "The targeted body of fluid is considered infinite.",
diff --git a/src/main/resources/assets/create/models/block/belt_tunnel/item.json b/src/main/resources/assets/create/models/block/belt_tunnel/item.json
index 7a0e311013..387034dcc6 100644
--- a/src/main/resources/assets/create/models/block/belt_tunnel/item.json
+++ b/src/main/resources/assets/create/models/block/belt_tunnel/item.json
@@ -228,7 +228,7 @@
 			"scale": [0.25, 0.25, 0.25]
 		},
 		"gui": {
-			"rotation": [30, 225, 0],
+			"rotation": [30, 135, 0],
 			"translation": [0, 1, 0],
 			"scale": [0.5, 0.5, 0.5]
 		},
diff --git a/src/main/resources/assets/create/models/block/funnel/block.json b/src/main/resources/assets/create/models/block/funnel/block.json
deleted file mode 100644
index 9f46b9da06..0000000000
--- a/src/main/resources/assets/create/models/block/funnel/block.json
+++ /dev/null
@@ -1,105 +0,0 @@
-{
-	"credit": "Made with Blockbench",
-	"parent": "block/block",
-	"textures": {
-		"0": "create:block/brass_funnel_plating",
-		"1": "create:block/brass_block",
-		"2": "create:block/brass_funnel",
-		"3": "create:block/brass_funnel_back",
-		"particle": "#1"
-	},
-	"elements": [
-		{
-			"from": [2.1, -1.9, 2.1],
-			"to": [13.9, 2, 13.9],
-			"rotation": {"angle": 0, "axis": "y", "origin": [10, 7, 10]},
-			"faces": {
-				"north": {"uv": [0, 0, 12, 4], "texture": "#2"},
-				"east": {"uv": [0, 0, 12, 4], "texture": "#2"},
-				"south": {"uv": [0, 0, 12, 4], "texture": "#2"},
-				"west": {"uv": [0, 0, 12, 4], "texture": "#2"},
-				"up": {"uv": [0, 4, 12, 16], "texture": "#2"},
-				"down": {"uv": [6, 8, 12, 14], "texture": "#3"}
-			}
-		},
-		{
-			"from": [2, 10, 14],
-			"to": [14, 16, 16],
-			"rotation": {"angle": 0, "axis": "y", "origin": [10, 19, 12]},
-			"faces": {
-				"north": {"uv": [2, 1, 14, 7], "texture": "#1"},
-				"south": {"uv": [1, 0, 7, 3], "texture": "#0"},
-				"up": {"uv": [2, 14, 14, 16], "texture": "#1"},
-				"down": {"uv": [2, 14, 14, 16], "rotation": 180, "texture": "#1"}
-			}
-		},
-		{
-			"from": [2, 10, 0],
-			"to": [14, 16, 2],
-			"rotation": {"angle": 0, "axis": "y", "origin": [10, 19, -2]},
-			"faces": {
-				"north": {"uv": [1, 0, 7, 3], "texture": "#0"},
-				"south": {"uv": [2, 1, 14, 7], "texture": "#1"},
-				"up": {"uv": [2, 0, 14, 2], "texture": "#1"},
-				"down": {"uv": [2, 0, 14, 2], "rotation": 180, "texture": "#1"}
-			}
-		},
-		{
-			"from": [0, 10, 0],
-			"to": [2, 16, 16],
-			"rotation": {"angle": 0, "axis": "y", "origin": [-2, 19, -2]},
-			"faces": {
-				"north": {"uv": [7, 0, 8, 3], "texture": "#0"},
-				"east": {"uv": [0, 1, 16, 7], "texture": "#1"},
-				"south": {"uv": [0, 0, 1, 3], "texture": "#0"},
-				"west": {"uv": [0, 0, 8, 3], "texture": "#0"},
-				"up": {"uv": [0, 0, 2, 16], "texture": "#1"},
-				"down": {"uv": [0, 0, 2, 16], "texture": "#1"}
-			}
-		},
-		{
-			"from": [14, 10, 0],
-			"to": [16, 16, 16],
-			"rotation": {"angle": 0, "axis": "y", "origin": [12, 19, -2]},
-			"faces": {
-				"north": {"uv": [0, 0, 1, 3], "texture": "#0"},
-				"east": {"uv": [0, 0, 8, 3], "texture": "#0"},
-				"south": {"uv": [7, 0, 8, 3], "texture": "#0"},
-				"west": {"uv": [0, 1, 16, 7], "texture": "#1"},
-				"up": {"uv": [14, 0, 16, 16], "texture": "#1"},
-				"down": {"uv": [14, 0, 16, 16], "texture": "#1"}
-			}
-		},
-		{
-			"from": [2, 6, 2],
-			"to": [14, 10, 14],
-			"rotation": {"angle": 0, "axis": "y", "origin": [10, 15, 10]},
-			"faces": {
-				"north": {"uv": [6, 0, 8, 6], "rotation": 90, "texture": "#3"},
-				"east": {"uv": [6, 0, 8, 6], "rotation": 90, "texture": "#3"},
-				"south": {"uv": [6, 0, 8, 6], "rotation": 90, "texture": "#3"},
-				"west": {"uv": [6, 0, 8, 6], "rotation": 90, "texture": "#3"},
-				"down": {"uv": [0, 0, 6, 6], "texture": "#3"}
-			}
-		},
-		{
-			"from": [2, 11, 2],
-			"to": [14, 15, 14],
-			"rotation": {"angle": 0, "axis": "y", "origin": [10, 20, 10]},
-			"faces": {
-				"up": {"uv": [0, 8, 6, 14], "texture": "#3"}
-			}
-		},
-		{
-			"from": [3, 2, 3],
-			"to": [13, 6, 13],
-			"rotation": {"angle": 0, "axis": "y", "origin": [10, 11, 10]},
-			"faces": {
-				"north": {"uv": [9.5, 2, 14.5, 4], "texture": "#3"},
-				"east": {"uv": [9.5, 2, 14.5, 4], "texture": "#3"},
-				"south": {"uv": [9.5, 2, 14.5, 4], "texture": "#3"},
-				"west": {"uv": [9.5, 2, 14.5, 4], "texture": "#3"}
-			}
-		}
-	]
-}
\ No newline at end of file
diff --git a/src/main/resources/assets/create/models/block/funnel/block_ceiling.json b/src/main/resources/assets/create/models/block/funnel/block_ceiling.json
new file mode 100644
index 0000000000..5a70211b50
--- /dev/null
+++ b/src/main/resources/assets/create/models/block/funnel/block_ceiling.json
@@ -0,0 +1,134 @@
+{
+	"credit": "Made with Blockbench",
+	"parent": "block/block",
+	"textures": {
+		"3": "create:block/brass_funnel_back",
+		"5": "create:block/brass_funnel_tall",
+		"6": "create:block/brass_funnel",
+		"7": "create:block/brass_funnel_plating",
+		"2_2": "create:block/brass_funnel_pull"
+	},
+	"elements": [
+		{
+			"name": "LeftWall",
+			"from": [14, 6, 0],
+			"to": [16.05, 12, 16],
+			"rotation": {"angle": 0, "axis": "x", "origin": [8, 12, 2]},
+			"faces": {
+				"north": {"uv": [14, 0, 16, 6], "rotation": 180, "texture": "#2_2"},
+				"east": {"uv": [0, 0, 16, 6], "rotation": 180, "texture": "#2_2"},
+				"south": {"uv": [0, 0, 2, 6], "rotation": 180, "texture": "#2_2"},
+				"west": {"uv": [0, 12, 16, 6], "texture": "#2_2"},
+				"up": {"uv": [15, 0, 16, 8], "texture": "#7"},
+				"down": {"uv": [0, 0, 1, 8], "rotation": 180, "texture": "#7"}
+			}
+		},
+		{
+			"name": "LeftWall",
+			"from": [-0.05, 6, 0],
+			"to": [2, 12, 16],
+			"rotation": {"angle": 0, "axis": "x", "origin": [8, 12, 2]},
+			"faces": {
+				"north": {"uv": [2, 0, 0, 6], "texture": "#2_2"},
+				"east": {"uv": [0, 6, 16, 12], "rotation": 180, "texture": "#2_2"},
+				"south": {"uv": [14, 0, 16, 6], "rotation": 180, "texture": "#2_2"},
+				"west": {"uv": [0, 6, 16, 0], "texture": "#2_2"},
+				"up": {"uv": [8, 0, 9, 8], "texture": "#7"},
+				"down": {"uv": [7, 0, 8, 8], "rotation": 180, "texture": "#7"}
+			}
+		},
+		{
+			"name": "Top",
+			"from": [2, 6, 0],
+			"to": [14, 12, 6],
+			"rotation": {"angle": 0, "axis": "x", "origin": [8, 12, 2]},
+			"faces": {
+				"north": {"uv": [2, 0, 14, 6], "rotation": 180, "texture": "#2_2"},
+				"south": {"uv": [9, 13, 15, 16], "rotation": 180, "texture": "#7"},
+				"up": {"uv": [9, 0, 15, 3], "texture": "#7"},
+				"down": {"uv": [1, 0, 7, 3], "rotation": 180, "texture": "#7"}
+			}
+		},
+		{
+			"name": "Top",
+			"from": [2, 6, 14],
+			"to": [14, 12, 16],
+			"rotation": {"angle": 0, "axis": "x", "origin": [8, 12, 18]},
+			"faces": {
+				"north": {"uv": [15, 13, 9, 16], "rotation": 180, "texture": "#7"},
+				"south": {"uv": [14, 0, 2, 6], "rotation": 180, "texture": "#2_2"},
+				"up": {"uv": [9, 3, 15, 0], "texture": "#7"},
+				"down": {"uv": [0.5, 12.5, 7.5, 11.5], "texture": "#7"}
+			}
+		},
+		{
+			"name": "Top",
+			"from": [2, 7, 6],
+			"to": [14, 8, 15],
+			"rotation": {"angle": 0, "axis": "x", "origin": [8, 12, 2]},
+			"faces": {
+				"down": {"uv": [0, 9, 6, 13.5], "rotation": 180, "texture": "#3"}
+			}
+		},
+		{
+			"from": [1, 11, 1],
+			"to": [15, 14, 15],
+			"rotation": {"angle": 0, "axis": "y", "origin": [9, 21, 10]},
+			"faces": {
+				"north": {"uv": [9, 6.5, 16, 8], "rotation": 180, "texture": "#3"},
+				"east": {"uv": [9, 6.5, 16, 8], "rotation": 180, "texture": "#3"},
+				"south": {"uv": [9, 6.5, 16, 8], "rotation": 180, "texture": "#3"},
+				"west": {"uv": [9, 6.5, 16, 8], "rotation": 180, "texture": "#3"},
+				"up": {"uv": [0, 0, 6, 6], "rotation": 90, "texture": "#3"}
+			}
+		},
+		{
+			"name": "Back",
+			"from": [2.1, 14, 2.05],
+			"to": [13.9, 18.1, 14.1],
+			"rotation": {"angle": 0, "axis": "y", "origin": [8, 6, 24.1]},
+			"faces": {
+				"north": {"uv": [0, 0, 12, 4], "rotation": 180, "texture": "#6"},
+				"east": {"uv": [0, 0, 12, 4], "rotation": 180, "texture": "#6"},
+				"south": {"uv": [0, 0, 12, 4], "rotation": 180, "texture": "#6"},
+				"west": {"uv": [0, 0, 12, 4], "rotation": 180, "texture": "#6"},
+				"up": {"uv": [6, 8, 12, 14], "texture": "#3"}
+			}
+		},
+		{
+			"name": "Back",
+			"from": [2.1, 11.9, 2.05],
+			"to": [13.9, 14, 13.1],
+			"rotation": {"angle": 0, "axis": "y", "origin": [8, 22, 24.1]},
+			"faces": {
+				"north": {"uv": [0, 1.5, 6, 0.5], "rotation": 180, "texture": "#6"},
+				"east": {"uv": [2.5, 0.5, 8, 1.5], "texture": "#5"},
+				"west": {"uv": [2.5, 1.5, 8, 0.5], "rotation": 180, "texture": "#5"}
+			}
+		}
+	],
+	"groups": [
+		{
+			"name": "block_retracted",
+			"origin": [8, 8, 8],
+			"children": [
+				{
+					"name": "BeltFunnel",
+					"origin": [9, -4, 8],
+					"children": [
+						{
+							"name": "FrontSection",
+							"origin": [9, -4, 8],
+							"children": [0, 1, 2, 3, 4, 5]
+						},
+						{
+							"name": "Base",
+							"origin": [9, -4, 8],
+							"children": [6, 7]
+						}
+					]
+				}
+			]
+		}
+	]
+}
\ No newline at end of file
diff --git a/src/main/resources/assets/create/models/block/funnel/block_ceiling_old.json b/src/main/resources/assets/create/models/block/funnel/block_ceiling_old.json
new file mode 100644
index 0000000000..d5fd6b5993
--- /dev/null
+++ b/src/main/resources/assets/create/models/block/funnel/block_ceiling_old.json
@@ -0,0 +1,147 @@
+{
+	"credit": "Made with Blockbench",
+	"parent": "block/block",
+	"textures": {
+		"3": "create:block/brass_funnel_back",
+		"5": "create:block/brass_funnel_tall",
+		"6": "create:block/brass_funnel",
+		"7": "create:block/brass_funnel_plating",
+		"2_2": "create:block/brass_funnel_pull"
+	},
+	"elements": [
+		{
+			"name": "LeftWall",
+			"from": [14, 6, -2],
+			"to": [16.05, 12, 14],
+			"rotation": {"angle": -22.5, "axis": "x", "origin": [8, 12, 0]},
+			"faces": {
+				"north": {"uv": [0, 0, 2, 6], "texture": "#2_2"},
+				"east": {"uv": [0, 0, 16, 6], "rotation": 180, "texture": "#2_2"},
+				"south": {"uv": [14, 0, 16, 6], "texture": "#2_2"},
+				"west": {"uv": [0, 12, 16, 6], "texture": "#2_2"},
+				"up": {"uv": [15, 0, 16, 8], "texture": "#7"},
+				"down": {"uv": [0, 0, 1, 8], "rotation": 180, "texture": "#7"}
+			}
+		},
+		{
+			"name": "LeftWall",
+			"from": [-0.05, 6, -2],
+			"to": [2, 12, 14],
+			"rotation": {"angle": -22.5, "axis": "x", "origin": [8, 12, 0]},
+			"faces": {
+				"north": {"uv": [16, 0, 14, 6], "rotation": 180, "texture": "#2_2"},
+				"east": {"uv": [0, 6, 16, 12], "rotation": 180, "texture": "#2_2"},
+				"south": {"uv": [0, 0, 2, 6], "texture": "#2_2"},
+				"west": {"uv": [0, 6, 16, 0], "texture": "#2_2"},
+				"up": {"uv": [8, 0, 9, 8], "texture": "#7"},
+				"down": {"uv": [7, 0, 8, 8], "rotation": 180, "texture": "#7"}
+			}
+		},
+		{
+			"name": "Top",
+			"from": [2, 6, -2],
+			"to": [14, 12, 4],
+			"rotation": {"angle": -22.5, "axis": "x", "origin": [8, 12, 0]},
+			"faces": {
+				"north": {"uv": [2, 0, 14, 6], "rotation": 180, "texture": "#2_2"},
+				"south": {"uv": [9, 13, 15, 16], "rotation": 180, "texture": "#7"},
+				"up": {"uv": [9, 0, 15, 3], "texture": "#7"},
+				"down": {"uv": [1, 0, 7, 3], "rotation": 180, "texture": "#7"}
+			}
+		},
+		{
+			"name": "Top",
+			"from": [2, 7, 4],
+			"to": [14, 8, 13],
+			"rotation": {"angle": -22.5, "axis": "x", "origin": [8, 12, 0]},
+			"faces": {
+				"down": {"uv": [0, 9, 6, 13.5], "rotation": 180, "texture": "#3"}
+			}
+		},
+		{
+			"name": "Top",
+			"from": [0.05, 12, 14],
+			"to": [15.95, 15.95, 16],
+			"rotation": {"angle": 0, "axis": "y", "origin": [8, 17, 2]},
+			"faces": {
+				"north": {"uv": [8, 11, 16, 13], "rotation": 180, "texture": "#7"},
+				"east": {"uv": [16, 11, 15, 13], "texture": "#7"},
+				"south": {"uv": [8, 11, 16, 13], "rotation": 180, "texture": "#7"},
+				"west": {"uv": [9, 11, 8, 13], "texture": "#7"},
+				"up": {"uv": [0, 13.5, 8, 14.5], "texture": "#7"},
+				"down": {"uv": [0, 11.5, 8, 12.5], "texture": "#7"}
+			}
+		},
+		{
+			"name": "Top",
+			"from": [0, 14, 13.1],
+			"to": [16, 16, 14],
+			"rotation": {"angle": 0, "axis": "y", "origin": [8, 17, 1.1]},
+			"faces": {
+				"east": {"uv": [6, 13, 5, 13.5], "rotation": 270, "texture": "#7"},
+				"south": {"uv": [0, 13.5, 8, 14.5], "rotation": 180, "texture": "#7"},
+				"west": {"uv": [7, 13, 6, 13.5], "rotation": 270, "texture": "#7"},
+				"up": {"uv": [0, 13, 8, 13.5], "texture": "#7"}
+			}
+		},
+		{
+			"from": [1, 11, 0],
+			"to": [15, 14, 7],
+			"rotation": {"angle": 0, "axis": "y", "origin": [9, 21, 9]},
+			"faces": {
+				"north": {"uv": [6.5, 0, 8, 6], "rotation": 270, "texture": "#3"},
+				"east": {"uv": [1, 6.5, 4.5, 8], "rotation": 180, "texture": "#3"},
+				"west": {"uv": [1, 6, 4.5, 7.5], "texture": "#3"},
+				"up": {"uv": [8, 0, 11.5, 6], "rotation": 90, "texture": "#3"}
+			}
+		},
+		{
+			"name": "Back",
+			"from": [2.1, 14, 1.05],
+			"to": [13.9, 18.1, 13.1],
+			"rotation": {"angle": 0, "axis": "y", "origin": [8, 6, 23.1]},
+			"faces": {
+				"north": {"uv": [0, 0, 12, 4], "rotation": 180, "texture": "#6"},
+				"east": {"uv": [0, 0, 12, 4], "rotation": 180, "texture": "#6"},
+				"south": {"uv": [0, 0, 12, 4], "rotation": 180, "texture": "#6"},
+				"west": {"uv": [0, 0, 12, 4], "rotation": 180, "texture": "#6"},
+				"up": {"uv": [6, 8, 12, 14], "texture": "#3"}
+			}
+		},
+		{
+			"name": "Back",
+			"from": [2.1, 11.9, 1.05],
+			"to": [13.9, 14, 12.1],
+			"rotation": {"angle": 0, "axis": "y", "origin": [8, 22, 23.1]},
+			"faces": {
+				"north": {"uv": [0, 1.5, 6, 0.5], "rotation": 180, "texture": "#6"},
+				"east": {"uv": [2.5, 0.5, 8, 1.5], "texture": "#5"},
+				"west": {"uv": [2.5, 1.5, 8, 0.5], "rotation": 180, "texture": "#5"}
+			}
+		}
+	],
+	"groups": [
+		{
+			"name": "block_retracted",
+			"origin": [8, 8, 8],
+			"children": [
+				{
+					"name": "BeltFunnel",
+					"origin": [9, -4, 8],
+					"children": [
+						{
+							"name": "FrontSection",
+							"origin": [9, -4, 8],
+							"children": [0, 1, 2, 3, 4, 5, 6]
+						},
+						{
+							"name": "Base",
+							"origin": [9, -4, 8],
+							"children": [7, 8]
+						}
+					]
+				}
+			]
+		}
+	]
+}
\ No newline at end of file
diff --git a/src/main/resources/assets/create/models/block/funnel/block_floor.json b/src/main/resources/assets/create/models/block/funnel/block_floor.json
new file mode 100644
index 0000000000..ecd1567831
--- /dev/null
+++ b/src/main/resources/assets/create/models/block/funnel/block_floor.json
@@ -0,0 +1,134 @@
+{
+	"credit": "Made with Blockbench",
+	"parent": "block/block",
+	"textures": {
+		"3": "create:block/brass_funnel_back",
+		"5": "create:block/brass_funnel_tall",
+		"6": "create:block/brass_funnel",
+		"7": "create:block/brass_funnel_plating",
+		"2_2": "create:block/brass_funnel_pull"
+	},
+	"elements": [
+		{
+			"name": "LeftWall",
+			"from": [-0.05, 4, 0],
+			"to": [2, 10, 16],
+			"rotation": {"angle": 0, "axis": "x", "origin": [8, 4, 2]},
+			"faces": {
+				"north": {"uv": [14, 0, 16, 6], "texture": "#2_2"},
+				"east": {"uv": [0, 12, 16, 6], "rotation": 180, "texture": "#2_2"},
+				"south": {"uv": [0, 0, 2, 6], "texture": "#2_2"},
+				"west": {"uv": [0, 0, 16, 6], "texture": "#2_2"},
+				"up": {"uv": [0, 0, 1, 8], "texture": "#7"},
+				"down": {"uv": [15, 0, 16, 8], "rotation": 180, "texture": "#7"}
+			}
+		},
+		{
+			"name": "LeftWall",
+			"from": [14, 4, 0],
+			"to": [16.05, 10, 16],
+			"rotation": {"angle": 0, "axis": "x", "origin": [8, 4, 2]},
+			"faces": {
+				"north": {"uv": [2, 0, 0, 6], "rotation": 180, "texture": "#2_2"},
+				"east": {"uv": [0, 6, 16, 0], "rotation": 180, "texture": "#2_2"},
+				"south": {"uv": [14, 0, 16, 6], "texture": "#2_2"},
+				"west": {"uv": [0, 6, 16, 12], "texture": "#2_2"},
+				"up": {"uv": [7, 0, 8, 8], "texture": "#7"},
+				"down": {"uv": [8, 0, 9, 8], "rotation": 180, "texture": "#7"}
+			}
+		},
+		{
+			"name": "Top",
+			"from": [2, 4, 0],
+			"to": [14, 10, 6],
+			"rotation": {"angle": 0, "axis": "x", "origin": [8, 4, 2]},
+			"faces": {
+				"north": {"uv": [2, 0, 14, 6], "texture": "#2_2"},
+				"south": {"uv": [9, 13, 15, 16], "texture": "#7"},
+				"up": {"uv": [1, 0, 7, 3], "texture": "#7"},
+				"down": {"uv": [9, 0, 15, 3], "rotation": 180, "texture": "#7"}
+			}
+		},
+		{
+			"name": "Top",
+			"from": [2, 4, 14],
+			"to": [14, 10, 16],
+			"rotation": {"angle": 0, "axis": "x", "origin": [8, 4, 18]},
+			"faces": {
+				"north": {"uv": [15, 13, 9, 16], "texture": "#7"},
+				"south": {"uv": [14, 0, 2, 6], "texture": "#2_2"},
+				"up": {"uv": [0.5, 12.5, 7.5, 11.5], "rotation": 180, "texture": "#7"},
+				"down": {"uv": [9, 3, 15, 0], "rotation": 180, "texture": "#7"}
+			}
+		},
+		{
+			"name": "Top",
+			"from": [2, 8, 6],
+			"to": [14, 9, 15],
+			"rotation": {"angle": 0, "axis": "x", "origin": [8, 4, 2]},
+			"faces": {
+				"up": {"uv": [0, 9, 6, 13.5], "texture": "#3"}
+			}
+		},
+		{
+			"from": [1, 2, 1],
+			"to": [15, 5, 15],
+			"rotation": {"angle": 0, "axis": "y", "origin": [7, -5, 10]},
+			"faces": {
+				"north": {"uv": [9, 6.5, 16, 8], "texture": "#3"},
+				"east": {"uv": [9, 6.5, 16, 8], "texture": "#3"},
+				"south": {"uv": [9, 6.5, 16, 8], "texture": "#3"},
+				"west": {"uv": [9, 6.5, 16, 8], "texture": "#3"},
+				"down": {"uv": [0, 0, 6, 6], "rotation": 270, "texture": "#3"}
+			}
+		},
+		{
+			"name": "Back",
+			"from": [2.1, -2.1, 2.05],
+			"to": [13.9, 2, 14.1],
+			"rotation": {"angle": 0, "axis": "y", "origin": [8, 10, 24.1]},
+			"faces": {
+				"north": {"uv": [0, 0, 12, 4], "texture": "#6"},
+				"east": {"uv": [0, 0, 12, 4], "texture": "#6"},
+				"south": {"uv": [0, 0, 12, 4], "texture": "#6"},
+				"west": {"uv": [0, 0, 12, 4], "texture": "#6"},
+				"down": {"uv": [6, 8, 12, 14], "rotation": 180, "texture": "#3"}
+			}
+		},
+		{
+			"name": "Back",
+			"from": [2.1, 2, 2.05],
+			"to": [13.9, 4.1, 13.1],
+			"rotation": {"angle": 0, "axis": "y", "origin": [8, -6, 24.1]},
+			"faces": {
+				"north": {"uv": [0, 1.5, 6, 0.5], "texture": "#6"},
+				"east": {"uv": [2.5, 1.5, 8, 0.5], "texture": "#5"},
+				"west": {"uv": [2.5, 0.5, 8, 1.5], "rotation": 180, "texture": "#5"}
+			}
+		}
+	],
+	"groups": [
+		{
+			"name": "block_retracted",
+			"origin": [8, 8, 8],
+			"children": [
+				{
+					"name": "BeltFunnel",
+					"origin": [9, -4, 8],
+					"children": [
+						{
+							"name": "FrontSection",
+							"origin": [9, -4, 8],
+							"children": [0, 1, 2, 3, 4, 5]
+						},
+						{
+							"name": "Base",
+							"origin": [9, -4, 8],
+							"children": [6, 7]
+						}
+					]
+				}
+			]
+		}
+	]
+}
\ No newline at end of file
diff --git a/src/main/resources/assets/create/models/block/funnel/block_wall.json b/src/main/resources/assets/create/models/block/funnel/block_wall.json
new file mode 100644
index 0000000000..23c63640f5
--- /dev/null
+++ b/src/main/resources/assets/create/models/block/funnel/block_wall.json
@@ -0,0 +1,150 @@
+{
+	"credit": "Made with Blockbench",
+	"parent": "block/block",
+	"textures": {
+		"3": "create:block/brass_funnel_back",
+		"5": "create:block/brass_funnel_tall",
+		"6": "create:block/brass_funnel",
+		"7": "create:block/brass_funnel_plating",
+		"2_2": "create:block/brass_funnel_pull"
+	},
+	"elements": [
+		{
+			"name": "LeftWall",
+			"from": [14, 1, 6],
+			"to": [16.05, 17, 12],
+			"rotation": {"angle": -22.5, "axis": "x", "origin": [8, 15, 12]},
+			"faces": {
+				"north": {"uv": [0, 0, 1, 8], "texture": "#7"},
+				"east": {"uv": [0, 0, 16, 6], "rotation": 90, "texture": "#2_2"},
+				"south": {"uv": [15, 0, 16, 8], "texture": "#7"},
+				"west": {"uv": [0, 12, 16, 6], "rotation": 90, "texture": "#2_2"},
+				"up": {"uv": [0, 0, 2, 6], "rotation": 180, "texture": "#2_2"},
+				"down": {"uv": [14, 0, 16, 6], "texture": "#2_2"}
+			}
+		},
+		{
+			"name": "LeftWall",
+			"from": [-0.05, 1, 6],
+			"to": [2, 17, 12],
+			"rotation": {"angle": -22.5, "axis": "x", "origin": [8, 15, 12]},
+			"faces": {
+				"north": {"uv": [7, 0, 8, 8], "texture": "#7"},
+				"east": {"uv": [0, 6, 16, 12], "rotation": 90, "texture": "#2_2"},
+				"south": {"uv": [8, 0, 9, 8], "texture": "#7"},
+				"west": {"uv": [0, 6, 16, 0], "rotation": 90, "texture": "#2_2"},
+				"up": {"uv": [16, 0, 14, 6], "texture": "#2_2"},
+				"down": {"uv": [0, 0, 2, 6], "texture": "#2_2"}
+			}
+		},
+		{
+			"name": "Top",
+			"from": [2, 11, 6],
+			"to": [14, 17, 12],
+			"rotation": {"angle": -22.5, "axis": "x", "origin": [8, 15, 12]},
+			"faces": {
+				"north": {"uv": [1, 0, 7, 3], "texture": "#7"},
+				"south": {"uv": [9, 0, 15, 3], "texture": "#7"},
+				"up": {"uv": [2, 0, 14, 6], "texture": "#2_2"},
+				"down": {"uv": [9, 13, 15, 16], "rotation": 180, "texture": "#7"}
+			}
+		},
+		{
+			"name": "Top",
+			"from": [0.05, -1, 12],
+			"to": [15.95, 1, 15.95],
+			"rotation": {"angle": 0, "axis": "y", "origin": [8, 13, 17]},
+			"faces": {
+				"north": {"uv": [0, 11.5, 8, 12.5], "rotation": 180, "texture": "#7"},
+				"east": {"uv": [16, 11, 15, 13], "rotation": 270, "texture": "#7"},
+				"south": {"uv": [0, 13.5, 8, 14.5], "texture": "#7"},
+				"west": {"uv": [9, 11, 8, 13], "rotation": 90, "texture": "#7"},
+				"up": {"uv": [8, 11, 16, 13], "texture": "#7"},
+				"down": {"uv": [8, 11, 16, 13], "rotation": 180, "texture": "#7"}
+			}
+		},
+		{
+			"name": "Top",
+			"from": [0, 1, 14],
+			"to": [16, 1.9, 16],
+			"rotation": {"angle": 0, "axis": "y", "origin": [8, 13.9, 17]},
+			"faces": {
+				"north": {"uv": [0, 7, 0.5, 15], "rotation": 90, "texture": "#3"},
+				"east": {"uv": [7, 13, 6, 13.5], "texture": "#7"},
+				"south": {"uv": [0, 13, 8, 13.5], "texture": "#7"},
+				"west": {"uv": [8, 13, 7, 13.5], "texture": "#7"},
+				"up": {"uv": [8, 11, 16, 13], "texture": "#7"},
+				"down": {"uv": [8, 11, 16, 13], "rotation": 180, "texture": "#7"}
+			}
+		},
+		{
+			"from": [1, 8, 11],
+			"to": [15, 15, 14],
+			"rotation": {"angle": 0, "axis": "y", "origin": [9, 6, 21]},
+			"faces": {
+				"east": {"uv": [1, 6.5, 4.5, 8], "rotation": 90, "texture": "#3"},
+				"south": {"uv": [8, 0, 11.5, 6], "rotation": 90, "texture": "#3"},
+				"west": {"uv": [1, 6, 4.5, 7.5], "rotation": 90, "texture": "#3"},
+				"up": {"uv": [6.5, 0, 8, 6], "rotation": 90, "texture": "#3"}
+			}
+		},
+		{
+			"name": "Back",
+			"from": [2.1, 1.9, 14],
+			"to": [13.9, 13.95, 18.1],
+			"rotation": {"angle": 0, "axis": "y", "origin": [8, -8.1, 6]},
+			"faces": {
+				"north": {"uv": [0, 7.5, 6, 13.5], "texture": "#3"},
+				"east": {"uv": [0, 0, 12, 4], "rotation": 90, "texture": "#6"},
+				"south": {"uv": [6, 8, 12, 14], "texture": "#3"},
+				"west": {"uv": [0, 0, 12, 4], "rotation": 270, "texture": "#6"},
+				"up": {"uv": [0, 0, 12, 4], "texture": "#6"},
+				"down": {"uv": [0, 0, 12, 4], "rotation": 180, "texture": "#6"}
+			}
+		},
+		{
+			"name": "Back",
+			"from": [2.1, 2.9, 11.9],
+			"to": [13.9, 13.95, 14],
+			"rotation": {"angle": 0, "axis": "y", "origin": [8, -8.1, 22]},
+			"faces": {
+				"east": {"uv": [2.5, 0.5, 8, 1.5], "rotation": 270, "texture": "#5"},
+				"west": {"uv": [2.5, 1.5, 8, 0.5], "rotation": 270, "texture": "#5"},
+				"up": {"uv": [0, 1.5, 6, 0.5], "texture": "#6"}
+			}
+		},
+		{
+			"name": "RearBackPlate",
+			"from": [2, 9.9, 10],
+			"to": [14, 11.9, 14],
+			"rotation": {"angle": 0, "axis": "y", "origin": [7, 6.9, 8]},
+			"faces": {
+				"down": {"uv": [0, 11.5, 6, 14], "texture": "#3"}
+			}
+		}
+	],
+	"groups": [
+		{
+			"name": "block_retracted",
+			"origin": [8, 8, 8],
+			"children": [
+				{
+					"name": "BeltFunnel",
+					"origin": [9, -4, 8],
+					"children": [
+						{
+							"name": "FrontSection",
+							"origin": [9, -4, 8],
+							"children": [0, 1, 2, 3, 4, 5]
+						},
+						{
+							"name": "Base",
+							"origin": [9, -4, 8],
+							"children": [6, 7, 8]
+						}
+					]
+				}
+			]
+		}
+	]
+}
\ No newline at end of file
diff --git a/src/main/resources/assets/create/models/block/funnel/flap.json b/src/main/resources/assets/create/models/block/funnel/flap.json
new file mode 100644
index 0000000000..94b2a6bb99
--- /dev/null
+++ b/src/main/resources/assets/create/models/block/funnel/flap.json
@@ -0,0 +1,22 @@
+{
+	"credit": "Made with Blockbench",
+	"textures": {
+		"4": "create:block/brass_funnel_back"
+	},
+	"elements": [
+		{
+			"name": "F4",
+			"from": [11, 0, 9],
+			"to": [14, 10, 10],
+			"rotation": {"angle": 0, "axis": "y", "origin": [-24.5, -7.5, 9]},
+			"faces": {
+				"north": {"uv": [14, 8.5, 12.5, 13.5], "texture": "#4"},
+				"east": {"uv": [13.5, 8.5, 14, 13.5], "texture": "#4"},
+				"south": {"uv": [12.5, 8.5, 14, 13.5], "texture": "#4"},
+				"west": {"uv": [12.5, 8.5, 13, 13.5], "texture": "#4"},
+				"up": {"uv": [12.5, 8.5, 14, 9], "texture": "#4"},
+				"down": {"uv": [12.5, 14.5, 14, 15], "texture": "#4"}
+			}
+		}
+	]
+}
\ No newline at end of file
diff --git a/src/main/resources/assets/create/models/block/funnel/item.json b/src/main/resources/assets/create/models/block/funnel/item.json
index 62aa61fe08..8a95603273 100644
--- a/src/main/resources/assets/create/models/block/funnel/item.json
+++ b/src/main/resources/assets/create/models/block/funnel/item.json
@@ -1,104 +1,230 @@
 {
 	"credit": "Made with Blockbench",
 	"parent": "block/block",
+	"texture_size": [32, 32],
 	"textures": {
-		"0": "create:block/brass_funnel_plating",
-		"1": "create:block/brass_block",
-		"2": "create:block/brass_funnel",
+		"2": "create:block/brass_funnel_neutral",
 		"3": "create:block/brass_funnel_back",
-		"particle": "#1"
+		"5": "create:block/brass_funnel_tall",
+		"6": "create:block/brass_funnel",
+		"7": "create:block/brass_funnel_plating",
+		"particle": "create:block/brass_block"
 	},
 	"elements": [
 		{
-			"from": [2.1, -1.9, 2.1],
-			"to": [13.9, 2, 13.9],
-			"rotation": {"angle": 0, "axis": "y", "origin": [10, 7, 10]},
+			"name": "LeftWall",
+			"from": [14, -3, 8],
+			"to": [16, 0, 14],
+			"rotation": {"angle": 0, "axis": "y", "origin": [8, -8, 8]},
 			"faces": {
-				"north": {"uv": [0, 0, 12, 4], "texture": "#2"},
-				"east": {"uv": [0, 0, 12, 4], "texture": "#2"},
-				"south": {"uv": [0, 0, 12, 4], "texture": "#2"},
-				"west": {"uv": [0, 0, 12, 4], "texture": "#2"},
-				"up": {"uv": [0, 4, 12, 16], "texture": "#2"},
-				"down": {"uv": [6, 8, 12, 14], "texture": "#3"}
+				"north": {"uv": [0, 8, 1, 9.5], "texture": "#7"},
+				"east": {"uv": [13, 0, 16, 6], "rotation": 90, "texture": "#2"},
+				"south": {"uv": [15, 8, 16, 9.5], "texture": "#7"},
+				"west": {"uv": [13, 0, 16, 6], "rotation": 90, "texture": "#2"},
+				"down": {"uv": [14, 10, 16, 16], "texture": "#particle"}
 			}
 		},
 		{
-			"from": [2, 10, 14],
-			"to": [14, 16, 16],
-			"rotation": {"angle": 0, "axis": "y", "origin": [10, 19, 12]},
+			"name": "LeftWall",
+			"from": [0, -3, 8],
+			"to": [2, 0, 14],
+			"rotation": {"angle": 0, "axis": "y", "origin": [8, -8, 8]},
 			"faces": {
-				"north": {"uv": [2, 1, 14, 7], "texture": "#1"},
-				"south": {"uv": [1, 0, 7, 3], "texture": "#0"},
-				"up": {"uv": [2, 14, 14, 16], "texture": "#1"},
-				"down": {"uv": [2, 14, 14, 16], "rotation": 180, "texture": "#1"}
+				"north": {"uv": [7, 8, 8, 9.5], "texture": "#7"},
+				"east": {"uv": [13, 6, 16, 0], "rotation": 90, "texture": "#2"},
+				"south": {"uv": [8, 7.5, 9, 9], "texture": "#7"},
+				"west": {"uv": [13, 6, 16, 0], "rotation": 90, "texture": "#2"},
+				"down": {"uv": [0, 10, 2, 16], "texture": "#particle"}
 			}
 		},
 		{
-			"from": [2, 10, 0],
-			"to": [14, 16, 2],
-			"rotation": {"angle": 0, "axis": "y", "origin": [10, 19, -2]},
+			"name": "LeftWall",
+			"from": [14, 0, 8],
+			"to": [16, 16, 14],
+			"rotation": {"angle": 0, "axis": "y", "origin": [8, -8, 8]},
 			"faces": {
-				"north": {"uv": [1, 0, 7, 3], "texture": "#0"},
-				"south": {"uv": [2, 1, 14, 7], "texture": "#1"},
-				"up": {"uv": [2, 0, 14, 2], "texture": "#1"},
-				"down": {"uv": [2, 0, 14, 2], "rotation": 180, "texture": "#1"}
+				"north": {"uv": [0, 0, 1, 8], "texture": "#7"},
+				"east": {"uv": [0, 6, 16, 12], "rotation": 90, "texture": "#2"},
+				"south": {"uv": [15, 0, 16, 8], "texture": "#7"},
+				"west": {"uv": [0, 12, 16, 6], "rotation": 90, "texture": "#2"},
+				"up": {"uv": [14, 0, 16, 6], "texture": "#2"}
 			}
 		},
 		{
-			"from": [0, 10, 0],
-			"to": [2, 16, 16],
-			"rotation": {"angle": 0, "axis": "y", "origin": [-2, 19, -2]},
+			"name": "LeftWall",
+			"from": [0, 0, 8],
+			"to": [2, 16, 14],
+			"rotation": {"angle": 0, "axis": "y", "origin": [8, -8, 8]},
 			"faces": {
-				"north": {"uv": [7, 0, 8, 3], "texture": "#0"},
-				"east": {"uv": [0, 1, 16, 7], "texture": "#1"},
-				"south": {"uv": [0, 0, 1, 3], "texture": "#0"},
-				"west": {"uv": [0, 0, 8, 3], "texture": "#0"},
-				"up": {"uv": [0, 0, 2, 16], "texture": "#1"},
-				"down": {"uv": [0, 0, 2, 16], "texture": "#1"}
+				"north": {"uv": [7, 0, 8, 8], "texture": "#7"},
+				"east": {"uv": [0, 6, 16, 12], "rotation": 90, "texture": "#2"},
+				"south": {"uv": [8, 0, 9, 8], "texture": "#7"},
+				"west": {"uv": [0, 12, 16, 6], "rotation": 90, "texture": "#2"},
+				"up": {"uv": [16, 0, 14, 6], "texture": "#2"}
 			}
 		},
 		{
-			"from": [14, 10, 0],
-			"to": [16, 16, 16],
-			"rotation": {"angle": 0, "axis": "y", "origin": [12, 19, -2]},
+			"name": "Top",
+			"from": [2, 10, 8],
+			"to": [14, 16, 14],
+			"rotation": {"angle": 0, "axis": "y", "origin": [6, -8, 8]},
 			"faces": {
-				"north": {"uv": [0, 0, 1, 3], "texture": "#0"},
-				"east": {"uv": [0, 0, 8, 3], "texture": "#0"},
-				"south": {"uv": [7, 0, 8, 3], "texture": "#0"},
-				"west": {"uv": [0, 1, 16, 7], "texture": "#1"},
-				"up": {"uv": [14, 0, 16, 16], "texture": "#1"},
-				"down": {"uv": [14, 0, 16, 16], "texture": "#1"}
+				"north": {"uv": [1, 0, 7, 3], "texture": "#7"},
+				"south": {"uv": [9, 0, 15, 3], "texture": "#7"},
+				"up": {"uv": [2, 0, 14, 6], "texture": "#2"},
+				"down": {"uv": [2, 0, 14, 6], "rotation": 180, "texture": "#2"}
 			}
 		},
 		{
-			"from": [2, 6, 2],
+			"name": "Top",
+			"from": [2, -2, 12],
 			"to": [14, 10, 14],
-			"rotation": {"angle": 0, "axis": "y", "origin": [10, 15, 10]},
+			"rotation": {"angle": 0, "axis": "y", "origin": [6, -14, 8]},
 			"faces": {
-				"north": {"uv": [6, 0, 8, 6], "rotation": 90, "texture": "#3"},
-				"east": {"uv": [6, 0, 8, 6], "rotation": 90, "texture": "#3"},
-				"south": {"uv": [6, 0, 8, 6], "rotation": 90, "texture": "#3"},
-				"west": {"uv": [6, 0, 8, 6], "rotation": 90, "texture": "#3"},
-				"down": {"uv": [0, 0, 6, 6], "texture": "#3"}
+				"north": {"uv": [0, 8, 6, 14], "texture": "#3"},
+				"south": {"uv": [9, 3, 15, 9.5], "texture": "#7"}
 			}
 		},
 		{
-			"from": [2, 11, 2],
-			"to": [14, 15, 14],
-			"rotation": {"angle": 0, "axis": "y", "origin": [10, 20, 10]},
+			"name": "LeftBottom",
+			"from": [15, -5, 8],
+			"to": [16, -3, 14],
+			"rotation": {"angle": 0, "axis": "y", "origin": [8, -8, 8]},
 			"faces": {
-				"up": {"uv": [0, 8, 6, 14], "texture": "#3"}
+				"north": {"uv": [0, 9.5, 0.5, 10.5], "texture": "#7"},
+				"east": {"uv": [5, 15, 8, 16], "texture": "#7"},
+				"west": {"uv": [5, 15, 8, 16], "texture": "#7"},
+				"down": {"uv": [0, 0, 1, 6], "texture": "#particle"}
 			}
 		},
 		{
-			"from": [3, 2, 3],
-			"to": [13, 6, 13],
-			"rotation": {"angle": 0, "axis": "y", "origin": [10, 11, 10]},
+			"name": "LeftBottom",
+			"from": [0, -5, 8],
+			"to": [1, -3, 14],
+			"rotation": {"angle": 0, "axis": "y", "origin": [8, -8, 8]},
 			"faces": {
-				"north": {"uv": [9.5, 2, 14.5, 4], "texture": "#3"},
-				"east": {"uv": [9.5, 2, 14.5, 4], "texture": "#3"},
-				"south": {"uv": [9.5, 2, 14.5, 4], "texture": "#3"},
-				"west": {"uv": [9.5, 2, 14.5, 4], "texture": "#3"}
+				"north": {"uv": [7.5, 9.5, 8, 10.5], "texture": "#7"},
+				"east": {"uv": [8, 15, 5, 16], "texture": "#7"},
+				"west": {"uv": [8, 15, 5, 16], "texture": "#7"},
+				"down": {"uv": [0, 0, 1, 6], "texture": "#particle"}
+			}
+		},
+		{
+			"name": "Back",
+			"from": [2.1, -2.1, 14],
+			"to": [13.9, 13.95, 18.1],
+			"rotation": {"angle": 0, "axis": "y", "origin": [8, -8.1, 6]},
+			"faces": {
+				"east": {"uv": [0, 0, 16, 4], "rotation": 90, "texture": "#5"},
+				"south": {"uv": [9, 1, 15, 9], "texture": "#7"},
+				"west": {"uv": [0, 0, 16, 4], "rotation": 270, "texture": "#5"},
+				"up": {"uv": [0, 0, 12, 4], "texture": "#6"},
+				"down": {"uv": [0, 0, 12, 4], "rotation": 180, "texture": "#6"}
+			}
+		},
+		{
+			"name": "RearBackPlate",
+			"from": [1, -5, 10],
+			"to": [15, -2, 16.05],
+			"rotation": {"angle": 0, "axis": "y", "origin": [7, -8, 8]},
+			"faces": {
+				"north": {"uv": [1, 13, 15, 16], "texture": "#particle"},
+				"south": {"uv": [0.5, 13, 7.5, 14.5], "texture": "#7"},
+				"up": {"uv": [1, 10, 15, 16], "texture": "#particle"},
+				"down": {"uv": [8.5, 13, 15.5, 16], "texture": "#7"}
+			}
+		},
+		{
+			"name": "BackPlateLeft",
+			"from": [15, -5, 14],
+			"to": [16, -2, 16.05],
+			"rotation": {"angle": 0, "axis": "y", "origin": [8, -8, 6]},
+			"faces": {
+				"east": {"uv": [0, 14.5, 1, 16], "texture": "#7"},
+				"south": {"uv": [7.5, 14.5, 8, 16], "texture": "#7"},
+				"west": {"uv": [7, 14.5, 8, 16], "texture": "#7"},
+				"up": {"uv": [0, 15, 1, 14.5], "rotation": 270, "texture": "#7"},
+				"down": {"uv": [0, 0, 1, 2], "texture": "#particle"}
+			}
+		},
+		{
+			"name": "BackPlateLeft",
+			"from": [0, -5, 14],
+			"to": [1, -2, 16.05],
+			"rotation": {"angle": 0, "axis": "y", "origin": [8, -8, 6]},
+			"faces": {
+				"east": {"uv": [8, 14.5, 7, 16], "texture": "#7"},
+				"south": {"uv": [0, 14.5, 0.5, 16], "texture": "#7"},
+				"west": {"uv": [1, 14.5, 0, 16], "texture": "#7"},
+				"up": {"uv": [0, 15, 1, 14.5], "rotation": 270, "texture": "#7"},
+				"down": {"uv": [0, 0, 1, 2], "texture": "#particle"}
+			}
+		},
+		{
+			"from": [1, -2, 14],
+			"to": [15, 15, 15],
+			"rotation": {"angle": 0, "axis": "y", "origin": [9, 6, 22]},
+			"faces": {
+				"east": {"uv": [1, 6, 9, 6.5], "rotation": 90, "texture": "#3"},
+				"south": {"uv": [8, 0, 16, 6], "rotation": 90, "texture": "#3"},
+				"west": {"uv": [1, 6, 9, 6.5], "rotation": 90, "texture": "#3"},
+				"up": {"uv": [6, 0, 6.5, 6], "rotation": 90, "texture": "#3"}
+			}
+		},
+		{
+			"name": "F4",
+			"from": [11, -3, 9],
+			"to": [14, 10, 10],
+			"rotation": {"angle": 0, "axis": "y", "origin": [-24.5, -7.5, 9]},
+			"faces": {
+				"north": {"uv": [14, 8.5, 12.5, 15], "texture": "#3"},
+				"east": {"uv": [13.5, 8.5, 14, 15], "texture": "#3"},
+				"south": {"uv": [12.5, 8.5, 14, 15], "texture": "#3"},
+				"west": {"uv": [12.5, 8.5, 13, 15], "texture": "#3"},
+				"up": {"uv": [12.5, 8.5, 14, 9], "texture": "#3"},
+				"down": {"uv": [12.5, 14.5, 14, 15], "texture": "#3"}
+			}
+		},
+		{
+			"name": "F5",
+			"from": [8, -3, 9],
+			"to": [11, 10, 10],
+			"rotation": {"angle": 0, "axis": "y", "origin": [-27.5, -7.5, 9]},
+			"faces": {
+				"north": {"uv": [14, 8.5, 12.5, 15], "texture": "#3"},
+				"east": {"uv": [13.5, 8.5, 14, 15], "texture": "#3"},
+				"south": {"uv": [12.5, 8.5, 14, 15], "texture": "#3"},
+				"west": {"uv": [12.5, 8.5, 13, 15], "texture": "#3"},
+				"up": {"uv": [12.5, 8.5, 14, 9], "texture": "#3"},
+				"down": {"uv": [12.5, 14.5, 14, 15], "texture": "#3"}
+			}
+		},
+		{
+			"name": "F6",
+			"from": [5, -3, 9],
+			"to": [8, 10, 10],
+			"rotation": {"angle": 0, "axis": "y", "origin": [-30.5, -7.5, 9]},
+			"faces": {
+				"north": {"uv": [14, 8.5, 12.5, 15], "texture": "#3"},
+				"east": {"uv": [13.5, 8.5, 14, 15], "texture": "#3"},
+				"south": {"uv": [12.5, 8.5, 14, 15], "texture": "#3"},
+				"west": {"uv": [12.5, 8.5, 13, 15], "texture": "#3"},
+				"up": {"uv": [12.5, 8.5, 14, 9], "texture": "#3"},
+				"down": {"uv": [12.5, 14.5, 14, 15], "texture": "#3"}
+			}
+		},
+		{
+			"name": "F7",
+			"from": [2, -3, 9],
+			"to": [5, 10, 10],
+			"rotation": {"angle": 0, "axis": "y", "origin": [-33.5, -7.5, 9]},
+			"faces": {
+				"north": {"uv": [14, 8.5, 12.5, 15], "texture": "#3"},
+				"east": {"uv": [13.5, 8.5, 14, 15], "texture": "#3"},
+				"south": {"uv": [12.5, 8.5, 14, 15], "texture": "#3"},
+				"west": {"uv": [12.5, 8.5, 13, 15], "texture": "#3"},
+				"up": {"uv": [12.5, 8.5, 14, 9], "texture": "#3"},
+				"down": {"uv": [12.5, 14.5, 14, 15], "texture": "#3"}
 			}
 		}
 	],
@@ -122,18 +248,58 @@
 			"scale": [0.4, 0.4, 0.4]
 		},
 		"ground": {
-			"translation": [0, 3, 0],
+			"translation": [0, 3, -1.5],
 			"scale": [0.25, 0.25, 0.25]
 		},
 		"gui": {
 			"rotation": [30, 225, 0],
-			"scale": [0.625, 0.625, 0.625]
+			"translation": [1, 1, 0],
+			"scale": [0.5, 0.5, 0.5]
 		},
 		"head": {
-			"rotation": [0, 90, 0]
+			"translation": [0, -14, 3.25]
 		},
 		"fixed": {
+			"translation": [0, 1.5, -3],
 			"scale": [0.5, 0.5, 0.5]
 		}
-	}
+	},
+	"groups": [
+		{
+			"name": "BeltFunnel",
+			"origin": [9, -4, 8],
+			"children": [
+				{
+					"name": "FrontSection",
+					"origin": [9, -4, 8],
+					"children": [0, 1, 2, 3, 4, 5, 6, 7]
+				},
+				{
+					"name": "Base",
+					"origin": [9, -4, 8],
+					"children": [8, 9, 10, 11]
+				}
+			]
+		}, 12,
+		{
+			"name": "flap",
+			"origin": [8, 8, 8],
+			"children": [13]
+		},
+		{
+			"name": "flap",
+			"origin": [8, 8, 8],
+			"children": [14]
+		},
+		{
+			"name": "flap",
+			"origin": [8, 8, 8],
+			"children": [15]
+		},
+		{
+			"name": "flap",
+			"origin": [8, 8, 8],
+			"children": [16]
+		}
+	]
 }
\ No newline at end of file
diff --git a/src/main/resources/assets/create/models/block/smart_chute/block.json b/src/main/resources/assets/create/models/block/smart_chute/block.json
new file mode 100644
index 0000000000..8977344b63
--- /dev/null
+++ b/src/main/resources/assets/create/models/block/smart_chute/block.json
@@ -0,0 +1,194 @@
+{
+	"credit": "Made with Blockbench",
+	"parent": "block/block",
+	"textures": {
+		"1": "create:block/chute_diagonal",
+		"2": "create:block/brass_funnel_plating",
+		"3": "create:block/brass_block",
+		"5": "create:block/brass_funnel_tall",
+		"13": "create:block/chute",
+		"particle": "block/hopper_outside"
+	},
+	"elements": [
+		{
+			"from": [3, 9, 1],
+			"to": [13, 16, 3],
+			"rotation": {"angle": 0, "axis": "y", "origin": [11, 16, -3]},
+			"faces": {
+				"north": {"uv": [9.5, 0, 14.5, 3.5], "texture": "#13"},
+				"south": {"uv": [9.5, 0, 14.5, 4], "texture": "#13"},
+				"up": {"uv": [1, 0, 6, 1], "texture": "#13"}
+			}
+		},
+		{
+			"from": [3, 9, 13],
+			"to": [13, 16, 15],
+			"rotation": {"angle": 0, "axis": "y", "origin": [5, 16, 19]},
+			"faces": {
+				"north": {"uv": [9.5, 0, 14.5, 4], "texture": "#13"},
+				"south": {"uv": [9.5, 0, 14.5, 3.5], "texture": "#13"},
+				"up": {"uv": [1, 0, 6, 1], "rotation": 180, "texture": "#13"}
+			}
+		},
+		{
+			"from": [1, 9, 1],
+			"to": [3, 16, 15],
+			"rotation": {"angle": 0, "axis": "y", "origin": [9, 16, 9]},
+			"faces": {
+				"north": {"uv": [14.5, 0, 15.5, 3.5], "texture": "#13"},
+				"east": {"uv": [8.5, 0, 15.5, 4], "texture": "#13"},
+				"south": {"uv": [8.5, 0, 9.5, 3.5], "texture": "#13"},
+				"west": {"uv": [8.5, 0, 15.5, 3.5], "texture": "#13"},
+				"up": {"uv": [0, 0, 1, 7], "texture": "#13"}
+			}
+		},
+		{
+			"from": [13, 9, 1],
+			"to": [15, 16, 15],
+			"rotation": {"angle": 0, "axis": "y", "origin": [7, 16, 7]},
+			"faces": {
+				"north": {"uv": [8.5, 0, 9.5, 3.5], "texture": "#13"},
+				"east": {"uv": [8.5, 0, 15.5, 3.5], "texture": "#13"},
+				"south": {"uv": [14.5, 0, 15.5, 3.5], "texture": "#13"},
+				"west": {"uv": [8.5, 0, 15.5, 4], "texture": "#13"},
+				"up": {"uv": [0, 0, 1, 7], "rotation": 180, "texture": "#13"}
+			}
+		},
+		{
+			"from": [0, 0, 0],
+			"to": [16, 5, 16],
+			"rotation": {"angle": 0, "axis": "x", "origin": [8, 11, 15]},
+			"faces": {
+				"north": {"uv": [0, 5.5, 8, 8], "texture": "#1"},
+				"east": {"uv": [0, 5.5, 8, 8], "texture": "#1"},
+				"south": {"uv": [0, 5.5, 8, 8], "texture": "#1"},
+				"west": {"uv": [0, 5.5, 8, 8], "texture": "#1"},
+				"up": {"uv": [8, 8, 16, 16], "rotation": 180, "texture": "#13"},
+				"down": {"uv": [8, 8, 16, 16], "rotation": 180, "texture": "#13"}
+			}
+		},
+		{
+			"from": [13, 1, 2],
+			"to": [14, 8, 14],
+			"rotation": {"angle": 0, "axis": "y", "origin": [9, 8, 9]},
+			"faces": {
+				"north": {"uv": [9, 4, 9.5, 7.5], "texture": "#13"},
+				"east": {"uv": [9, 4, 15, 7.5], "texture": "#13"},
+				"south": {"uv": [14.5, 4, 15, 7.5], "texture": "#13"},
+				"west": {"uv": [9, 4, 15, 8], "texture": "#13"},
+				"down": {"uv": [9, 7.5, 15, 8], "rotation": 90, "texture": "#13"}
+			}
+		},
+		{
+			"from": [2, 1, 2],
+			"to": [3, 8, 14],
+			"rotation": {"angle": 0, "axis": "y", "origin": [9, 8, 9]},
+			"faces": {
+				"north": {"uv": [14.5, 4, 15, 7.5], "texture": "#13"},
+				"east": {"uv": [9, 4, 15, 8], "texture": "#13"},
+				"south": {"uv": [9, 4, 9.5, 7.5], "texture": "#13"},
+				"west": {"uv": [9, 4, 15, 7.5], "texture": "#13"},
+				"down": {"uv": [9, 7.5, 15, 8], "rotation": 90, "texture": "#13"}
+			}
+		},
+		{
+			"from": [3, 1, 13],
+			"to": [13, 8, 14],
+			"rotation": {"angle": 0, "axis": "y", "origin": [8, 8, 20]},
+			"faces": {
+				"north": {"uv": [9.5, 4, 14.5, 8], "texture": "#13"},
+				"south": {"uv": [9.5, 4, 14.5, 7.5], "texture": "#13"},
+				"down": {"uv": [9.5, 7.5, 14.5, 8], "texture": "#13"}
+			}
+		},
+		{
+			"from": [3, 1, 2],
+			"to": [13, 8, 3],
+			"rotation": {"angle": 0, "axis": "y", "origin": [8, 8, 9]},
+			"faces": {
+				"north": {"uv": [9.5, 4, 14.5, 7.5], "texture": "#13"},
+				"south": {"uv": [9.5, 4, 14.5, 8], "texture": "#13"},
+				"down": {"uv": [9.5, 7.5, 14.5, 8], "texture": "#13"}
+			}
+		},
+		{
+			"from": [3, 13, 3],
+			"to": [13, 14, 13],
+			"faces": {
+				"up": {"uv": [9.5, 9.5, 14.5, 14.5], "texture": "#13"},
+				"down": {"uv": [9.5, 9.5, 14.5, 14.5], "texture": "#13"}
+			}
+		},
+		{
+			"from": [0, 9, 0],
+			"to": [2, 15, 16],
+			"rotation": {"angle": 0, "axis": "y", "origin": [8, 22, 8]},
+			"faces": {
+				"north": {"uv": [7, 0, 8, 3], "texture": "#2"},
+				"south": {"uv": [0, 0, 1, 3], "texture": "#2"},
+				"west": {"uv": [0, 0, 8, 3], "texture": "#2"},
+				"up": {"uv": [0, 0, 2, 16], "texture": "#3"},
+				"down": {"uv": [0, 0, 2, 16], "texture": "#3"}
+			}
+		},
+		{
+			"from": [2, 9, 0],
+			"to": [14, 15, 2],
+			"rotation": {"angle": 0, "axis": "y", "origin": [8, 22, 8]},
+			"faces": {
+				"north": {"uv": [1, 0, 7, 3], "texture": "#2"},
+				"east": {"uv": [7, 0, 8, 3], "texture": "#2"},
+				"west": {"uv": [0, 0, 1, 3], "texture": "#2"},
+				"up": {"uv": [0, 2, 2, 14], "rotation": 90, "texture": "#3"},
+				"down": {"uv": [0, 2, 2, 14], "rotation": 270, "texture": "#3"}
+			}
+		},
+		{
+			"from": [2, 9, 14],
+			"to": [14, 15, 16],
+			"rotation": {"angle": 0, "axis": "y", "origin": [8, 22, 8]},
+			"faces": {
+				"east": {"uv": [8, 0, 7, 3], "texture": "#2"},
+				"south": {"uv": [7, 0, 1, 3], "texture": "#2"},
+				"west": {"uv": [1, 0, 0, 3], "texture": "#2"},
+				"up": {"uv": [2, 2, 0, 14], "rotation": 90, "texture": "#3"},
+				"down": {"uv": [2, 2, 0, 14], "rotation": 270, "texture": "#3"}
+			}
+		},
+		{
+			"from": [14, 9, 0],
+			"to": [16, 15, 16],
+			"rotation": {"angle": 0, "axis": "y", "origin": [8, 22, 8]},
+			"faces": {
+				"north": {"uv": [0, 0, 1, 3], "texture": "#2"},
+				"east": {"uv": [8, 0, 0, 3], "texture": "#2"},
+				"south": {"uv": [7, 0, 8, 3], "texture": "#2"},
+				"up": {"uv": [2, 0, 0, 16], "texture": "#3"},
+				"down": {"uv": [2, 0, 0, 16], "texture": "#3"}
+			}
+		},
+		{
+			"from": [1, 7, 1],
+			"to": [15, 9, 15],
+			"rotation": {"angle": 0, "axis": "y", "origin": [21, 18, 9]},
+			"faces": {
+				"north": {"uv": [1, 4, 15, 6], "texture": "#5"},
+				"east": {"uv": [1, 4, 15, 6], "texture": "#5"},
+				"south": {"uv": [1, 4, 15, 6], "texture": "#5"},
+				"west": {"uv": [1, 4, 15, 6], "texture": "#5"},
+				"down": {"uv": [1, 1, 15, 15], "texture": "#3"}
+			}
+		}
+	],
+	"groups": [
+		{
+			"name": "ChuteTop",
+			"origin": [9, 16, -7],
+			"children": [0, 1, 2, 3, 4]
+		},
+		{
+			"name": "ChuteBase",
+			"origin": [8, 8, -7],
+			"children": [5, 6, 7, 8]
+		}, 9, 10, 11, 12, 13, 14]
+}
\ No newline at end of file
diff --git a/src/main/resources/assets/create/models/block/smart_chute/block_powered.json b/src/main/resources/assets/create/models/block/smart_chute/block_powered.json
new file mode 100644
index 0000000000..1a2636b1be
--- /dev/null
+++ b/src/main/resources/assets/create/models/block/smart_chute/block_powered.json
@@ -0,0 +1,6 @@
+{
+	"parent": "create:block/smart_chute/block",
+	"textures": {
+		"5": "create:block/brass_funnel_tall_powered"
+	}
+}
\ No newline at end of file
diff --git a/src/main/resources/assets/create/textures/block/andesite_funnel_plating.png b/src/main/resources/assets/create/textures/block/andesite_funnel_plating.png
index 6f4ed26a87..e7b7b046d8 100644
Binary files a/src/main/resources/assets/create/textures/block/andesite_funnel_plating.png and b/src/main/resources/assets/create/textures/block/andesite_funnel_plating.png differ
diff --git a/src/main/resources/assets/create/textures/block/andesite_funnel_pull.png b/src/main/resources/assets/create/textures/block/andesite_funnel_pull.png
index bf0abd43f8..8fa778d40d 100644
Binary files a/src/main/resources/assets/create/textures/block/andesite_funnel_pull.png and b/src/main/resources/assets/create/textures/block/andesite_funnel_pull.png differ
diff --git a/src/main/resources/assets/create/textures/block/andesite_funnel_push.png b/src/main/resources/assets/create/textures/block/andesite_funnel_push.png
index ede3d171ec..980f0bda91 100644
Binary files a/src/main/resources/assets/create/textures/block/andesite_funnel_push.png and b/src/main/resources/assets/create/textures/block/andesite_funnel_push.png differ
diff --git a/src/main/resources/assets/create/textures/block/brass_funnel_plating.png b/src/main/resources/assets/create/textures/block/brass_funnel_plating.png
index 76fe0d5428..014d9ba8d6 100644
Binary files a/src/main/resources/assets/create/textures/block/brass_funnel_plating.png and b/src/main/resources/assets/create/textures/block/brass_funnel_plating.png differ
diff --git a/src/main/resources/assets/create/textures/block/brass_funnel_pull.png b/src/main/resources/assets/create/textures/block/brass_funnel_pull.png
index f8fe8e44b2..df455d78e5 100644
Binary files a/src/main/resources/assets/create/textures/block/brass_funnel_pull.png and b/src/main/resources/assets/create/textures/block/brass_funnel_pull.png differ
diff --git a/src/main/resources/assets/create/textures/block/brass_funnel_push.png b/src/main/resources/assets/create/textures/block/brass_funnel_push.png
index 18eb093209..6b1c6d0e75 100644
Binary files a/src/main/resources/assets/create/textures/block/brass_funnel_push.png and b/src/main/resources/assets/create/textures/block/brass_funnel_push.png differ