From ca104912d64a72b7af7889d2115c9df692bc3bc0 Mon Sep 17 00:00:00 2001 From: Sebastian Hartte Date: Mon, 29 Jun 2020 21:23:50 +0200 Subject: [PATCH] More fixes --- .../api/events/LocatableEventAnnounce.java | 8 +- .../api/features/IP2PTunnelRegistry.java | 3 + .../java/appeng/api/features/IWorldGen.java | 3 +- .../appeng/api/movable/IMovableHandler.java | 4 +- .../appeng/block/misc/QuartzFixtureBlock.java | 2 +- .../block/misc/SkyCompassRendering.java | 0 .../java/appeng/block/misc/TinyTNTBlock.java | 0 .../appeng/bootstrap/BlockEntityBuilder.java | 16 +- .../IItemColorRegistrationComponent.java | 2 +- .../components/ItemColorComponent.java | 5 +- .../main/java/appeng/client/AppEngClient.java | 166 +++ .../client/render/FacingToRotation.java | 16 +- .../client/render/effects/ParticleTypes.java | 15 +- .../client/render/tesr/SkyChestTESR.java | 92 +- .../client/render/tesr/SkyCompassTESR.java | 24 +- core/src/main/java/appeng/core/AEConfig.java | 9 +- .../src}/main/java/appeng/core/Api.java | 5 +- .../main/java/appeng/core/ApiDefinitions.java | 0 core/src/main/java/appeng/core/AppEng.java | 28 +- .../src/main/java/appeng/core/AppEngBase.java | 91 ++ .../java/appeng/core/AppEngClientStartup.java | 13 + .../main/java/appeng/core/AppEngHolder.java | 7 + .../main/java/appeng/core/CreativeTab.java | 2 +- .../java/appeng/core/api/ApiClientHelper.java | 4 +- .../main/java/appeng/core/api/ApiGrid.java | 9 +- .../main/java/appeng/core/api/ApiPart.java | 6 +- .../main/java/appeng/core/api/ApiStorage.java | 19 +- .../core/api/definitions/ApiBlocks.java | 941 +++++++++++++++ .../appeng/core/api/definitions/ApiItems.java | 509 ++++++++ .../core/api/definitions/ApiMaterials.java | 0 .../appeng/core/api/definitions/ApiParts.java | 385 ++++++ .../registries/GridCacheRegistry.java | 0 .../registries/LocatableRegistry.java | 25 +- .../registries/MatterCannonAmmoRegistry.java | 10 +- .../registries/MovableTileRegistry.java | 2 +- .../registries/P2PTunnelRegistry.java | 47 +- .../core/features/registries/PartModels.java | 0 .../features/registries/PlayerRegistry.java | 4 +- .../registries/RegistryContainer.java | 0 .../features/registries/WirelessRegistry.java | 6 +- .../features/registries/WorldGenRegistry.java | 32 +- .../registries/cell/BasicCellHandler.java | 0 .../cell/BasicItemCellGuiHandler.java | 7 +- .../registries/cell/CellRegistry.java | 0 .../registries/cell/CreativeCellHandler.java | 0 .../registries/charger/ChargerRegistry.java | 0 .../decorative/solid/AEStairsBlock.java | 12 + .../solid/ChargedQuartzOreBlock.java | 2 +- .../decorative/solid/QuartzLampBlock.java | 2 +- .../java/appeng/fluids/util/FluidList.java | 0 .../fluids/util/MeaningfulFluidIterator.java | 0 .../main/java/appeng/hooks/AEToolItem.java | 9 + .../hooks/TinyTNTDispenseItemBehavior.java | 8 +- .../main/java/appeng/hooks/ToolItemHook.java | 40 + .../appeng/items/contents/CellConfig.java | 3 +- .../appeng/items/materials/MaterialItem.java | 59 +- .../storage/CreativeStorageCellItem.java | 0 .../me/storage/AbstractCellInventory.java | 0 .../appeng/me/storage/BasicCellInventory.java | 0 .../me/storage/BasicCellInventoryHandler.java | 0 .../me/storage/CreativeCellInventory.java | 0 .../appeng/me/storage/MEInventoryHandler.java | 0 .../java/appeng/me/storage/MEPassThrough.java | 0 .../appeng/mixins/CriteriaRegisterMixin.java | 16 + .../appeng/spatial/DefaultSpatialHandler.java | 12 +- .../java/appeng/tile/AEBaseBlockEntity.java | 1 - .../resources/appliedenergistics2.mixins.json | 4 +- core/src/main/resources/fabric.mod.json | 3 + .../block/paint/PaintSplotchesBakedModel.java | 12 +- .../block/paint/PaintSplotchesModel.java | 8 +- .../appeng/block/qnb/QnbFormedBakedModel.java | 18 +- .../java/appeng/block/qnb/QnbFormedModel.java | 8 +- .../DummyFluidDispatcherBakedModel.java | 8 +- .../client/render/DummyFluidItemModel.java | 8 +- .../appeng/client/render/FacadeItemModel.java | 7 +- .../client/render/SpatialSkyRender.java | 2 +- .../client/render/TesrRenderHelper.java | 2 +- .../client/render/cablebus/CableBuilder.java | 12 +- .../client/render/cablebus/CableBusModel.java | 10 +- .../client/render/cablebus/CableCoreType.java | 6 +- .../client/render/cablebus/CubeBuilder.java | 2 +- .../cablebus/P2PTunnelFrequencyModel.java | 10 +- .../render/cablebus/SmartCableTextures.java | 8 +- .../render/crafting/CraftingCubeModel.java | 42 +- .../render/crafting/EncodedPatternModel.java | 8 +- .../render/model/AutoRotatingBakedModel.java | 6 +- .../render/model/BiometricCardModel.java | 10 +- .../render/model/ColorApplicatorModel.java | 14 +- .../client/render/model/DriveModel.java | 8 +- .../client/render/model/GlassBakedModel.java | 20 +- .../client/render/model/GlassModel.java | 10 +- .../render/model/MatrixVertexTransformer.java | 2 +- .../client/render/model/MemoryCardModel.java | 10 +- .../render/model/SkyCompassBakedModel.java | 6 +- .../client/render/model/SkyCompassModel.java | 8 +- .../client/render/model/UVLModelLoader.java | 10 +- .../render/spatial/SpatialPylonModel.java | 12 +- .../appeng/client/render/tesr/CrankTESR.java | 8 +- .../tesr/DriveLedTileEntityRenderer.java | 2 +- .../client/render/tesr/InscriberTESR.java | 10 +- src/main/java/appeng/core/Registration.java | 77 -- .../core/api/definitions/ApiBlocks.java | 1037 ----------------- .../appeng/core/api/definitions/ApiItems.java | 559 --------- .../appeng/core/api/definitions/ApiParts.java | 441 ------- .../appeng/debug/DebugPartPlacerItem.java | 2 +- .../hooks/BlockToolDispenseItemBehavior.java | 8 +- .../MatterCannonDispenseItemBehavior.java | 8 +- .../theoneprobe/part/PartAccessor.java | 2 +- .../appeng/items/contents/CellUpgrades.java | 3 +- .../appeng/items/tools/NetworkToolItem.java | 4 +- src/main/java/appeng/parts/PartPlacement.java | 2 +- .../parts/automation/FormationPlanePart.java | 4 +- .../appeng/parts/automation/PlaneModel.java | 20 +- .../reporting/ConversionMonitorPart.java | 2 +- .../subcommands/TestMeteoritesCommand.java | 6 +- src/main/java/appeng/spatial/CachedPlane.java | 2 +- .../codechicken/lib/model/Quad.java | 2 +- .../transformers/QuadCornerKicker.java | 2 +- .../transformers/QuadMatrixTransformer.java | 6 +- .../tile/crafting/CraftingBlockEntity.java | 2 - .../crafting/MolecularAssemblerRenderer.java | 2 +- 121 files changed, 2623 insertions(+), 2563 deletions(-) rename {src => core/src}/main/java/appeng/block/misc/QuartzFixtureBlock.java (99%) rename {src => core/src}/main/java/appeng/block/misc/SkyCompassRendering.java (100%) rename {src => core/src}/main/java/appeng/block/misc/TinyTNTBlock.java (100%) create mode 100644 core/src/main/java/appeng/client/AppEngClient.java rename {src => core/src}/main/java/appeng/client/render/FacingToRotation.java (88%) rename {src => core/src}/main/java/appeng/client/render/tesr/SkyChestTESR.java (64%) rename {src => core/src}/main/java/appeng/client/render/tesr/SkyCompassTESR.java (79%) rename {src => core/src}/main/java/appeng/core/Api.java (94%) rename {src => core/src}/main/java/appeng/core/ApiDefinitions.java (100%) create mode 100644 core/src/main/java/appeng/core/AppEngBase.java create mode 100644 core/src/main/java/appeng/core/AppEngClientStartup.java create mode 100644 core/src/main/java/appeng/core/AppEngHolder.java rename {src => core/src}/main/java/appeng/core/api/ApiClientHelper.java (92%) rename {src => core/src}/main/java/appeng/core/api/ApiGrid.java (88%) rename {src => core/src}/main/java/appeng/core/api/ApiPart.java (88%) rename {src => core/src}/main/java/appeng/core/api/ApiStorage.java (89%) create mode 100644 core/src/main/java/appeng/core/api/definitions/ApiBlocks.java create mode 100644 core/src/main/java/appeng/core/api/definitions/ApiItems.java rename {src => core/src}/main/java/appeng/core/api/definitions/ApiMaterials.java (100%) create mode 100644 core/src/main/java/appeng/core/api/definitions/ApiParts.java rename {src => core/src}/main/java/appeng/core/features/registries/GridCacheRegistry.java (100%) rename {src => core/src}/main/java/appeng/core/features/registries/LocatableRegistry.java (71%) rename {src => core/src}/main/java/appeng/core/features/registries/MatterCannonAmmoRegistry.java (94%) rename {src => core/src}/main/java/appeng/core/features/registries/MovableTileRegistry.java (99%) rename {src => core/src}/main/java/appeng/core/features/registries/P2PTunnelRegistry.java (88%) rename {src => core/src}/main/java/appeng/core/features/registries/PartModels.java (100%) rename {src => core/src}/main/java/appeng/core/features/registries/PlayerRegistry.java (92%) rename {src => core/src}/main/java/appeng/core/features/registries/RegistryContainer.java (100%) rename {src => core/src}/main/java/appeng/core/features/registries/WirelessRegistry.java (92%) rename {src => core/src}/main/java/appeng/core/features/registries/WorldGenRegistry.java (76%) rename {src => core/src}/main/java/appeng/core/features/registries/cell/BasicCellHandler.java (100%) rename {src => core/src}/main/java/appeng/core/features/registries/cell/BasicItemCellGuiHandler.java (77%) rename {src => core/src}/main/java/appeng/core/features/registries/cell/CellRegistry.java (100%) rename {src => core/src}/main/java/appeng/core/features/registries/cell/CreativeCellHandler.java (100%) rename {src => core/src}/main/java/appeng/core/features/registries/charger/ChargerRegistry.java (100%) create mode 100644 core/src/main/java/appeng/decorative/solid/AEStairsBlock.java rename {src => core/src}/main/java/appeng/fluids/util/FluidList.java (100%) rename {src => core/src}/main/java/appeng/fluids/util/MeaningfulFluidIterator.java (100%) create mode 100644 core/src/main/java/appeng/hooks/AEToolItem.java rename {src => core/src}/main/java/appeng/hooks/TinyTNTDispenseItemBehavior.java (85%) create mode 100644 core/src/main/java/appeng/hooks/ToolItemHook.java rename {src => core/src}/main/java/appeng/items/contents/CellConfig.java (88%) rename {src => core/src}/main/java/appeng/items/materials/MaterialItem.java (82%) rename {src => core/src}/main/java/appeng/items/storage/CreativeStorageCellItem.java (100%) rename {src => core/src}/main/java/appeng/me/storage/AbstractCellInventory.java (100%) rename {src => core/src}/main/java/appeng/me/storage/BasicCellInventory.java (100%) rename {src => core/src}/main/java/appeng/me/storage/BasicCellInventoryHandler.java (100%) rename {src => core/src}/main/java/appeng/me/storage/CreativeCellInventory.java (100%) rename {src => core/src}/main/java/appeng/me/storage/MEInventoryHandler.java (100%) rename {src => core/src}/main/java/appeng/me/storage/MEPassThrough.java (100%) create mode 100644 core/src/main/java/appeng/mixins/CriteriaRegisterMixin.java rename {src => core/src}/main/java/appeng/spatial/DefaultSpatialHandler.java (83%) delete mode 100644 src/main/java/appeng/core/api/definitions/ApiBlocks.java delete mode 100644 src/main/java/appeng/core/api/definitions/ApiItems.java delete mode 100644 src/main/java/appeng/core/api/definitions/ApiParts.java diff --git a/api/src/main/java/appeng/api/events/LocatableEventAnnounce.java b/api/src/main/java/appeng/api/events/LocatableEventAnnounce.java index 1f8470c2a..ce76ab837 100644 --- a/api/src/main/java/appeng/api/events/LocatableEventAnnounce.java +++ b/api/src/main/java/appeng/api/events/LocatableEventAnnounce.java @@ -34,15 +34,15 @@ import net.fabricmc.fabric.api.event.EventFactory; */ public interface LocatableEventAnnounce { - Event EVENT = EventFactory.createArrayBacked(LocatableEventAnnounce.class, listeners -> (ILocatable o, LocatableEvent evt) -> { + Event EVENT = EventFactory.createArrayBacked(LocatableEventAnnounce.class, listeners -> (ILocatable target, LocatableEvent change) -> { for (LocatableEventAnnounce listener : listeners) { - listener.onLocatableAnnounce(o, evt); + listener.onLocatableAnnounce(target, change); } }); - void onLocatableAnnounce(final ILocatable o, final LocatableEvent ev); + void onLocatableAnnounce(final ILocatable target, final LocatableEvent change); - public enum LocatableEvent { + enum LocatableEvent { /** * Adds the locatable to the registry */ diff --git a/api/src/main/java/appeng/api/features/IP2PTunnelRegistry.java b/api/src/main/java/appeng/api/features/IP2PTunnelRegistry.java index 1b031953a..bf6a206b0 100644 --- a/api/src/main/java/appeng/api/features/IP2PTunnelRegistry.java +++ b/api/src/main/java/appeng/api/features/IP2PTunnelRegistry.java @@ -26,6 +26,7 @@ package appeng.api.features; import javax.annotation.Nonnull; import javax.annotation.Nullable; +import alexiil.mc.lib.attributes.Attribute; import net.minecraft.item.ItemStack; import appeng.api.config.TunnelType; @@ -47,6 +48,8 @@ public interface IP2PTunnelRegistry { void addNewAttunement(@Nonnull String ModId, @Nullable TunnelType type); + void addNewAttunement(@Nonnull Attribute attr, @Nullable TunnelType type); + /** * returns null if no attunement can be found. * diff --git a/api/src/main/java/appeng/api/features/IWorldGen.java b/api/src/main/java/appeng/api/features/IWorldGen.java index e109272f7..512b64a0b 100644 --- a/api/src/main/java/appeng/api/features/IWorldGen.java +++ b/api/src/main/java/appeng/api/features/IWorldGen.java @@ -23,6 +23,7 @@ package appeng.api.features; +import net.minecraft.server.world.ServerWorld; import net.minecraft.util.Identifier; import net.minecraft.world.ServerWorldAccess; @@ -32,7 +33,7 @@ public interface IWorldGen { void disableWorldGenForDimension(WorldGenType type, Identifier dimID); - boolean isWorldGenEnabled(WorldGenType type, ServerWorldAccess w); + boolean isWorldGenEnabled(WorldGenType type, ServerWorld w); enum WorldGenType { CERTUS_QUARTZ, CHARGED_CERTUS_QUARTZ, METEORITES diff --git a/api/src/main/java/appeng/api/movable/IMovableHandler.java b/api/src/main/java/appeng/api/movable/IMovableHandler.java index f196ca32d..95876184b 100644 --- a/api/src/main/java/appeng/api/movable/IMovableHandler.java +++ b/api/src/main/java/appeng/api/movable/IMovableHandler.java @@ -50,11 +50,11 @@ public interface IMovableHandler { *
      * {
      *     @code
-     *     Chunk c = world.getChunkAt(x, z);
+     *     Chunk c = world.getChunk(x, z);
      *     c.setChunkBlockTileEntity(x & 0xF, y + y, z & 0xF, tile);
      *
      *     if (c.isChunkLoaded) {
-     *         world.addTileEntity(tile);
+     *         world.addBlockEntity(tile);
      *         world.markBlockForUpdate(x, y, z);
      *     }
      * }
diff --git a/src/main/java/appeng/block/misc/QuartzFixtureBlock.java b/core/src/main/java/appeng/block/misc/QuartzFixtureBlock.java
similarity index 99%
rename from src/main/java/appeng/block/misc/QuartzFixtureBlock.java
rename to core/src/main/java/appeng/block/misc/QuartzFixtureBlock.java
index e9f062eae..20963c515 100644
--- a/src/main/java/appeng/block/misc/QuartzFixtureBlock.java
+++ b/core/src/main/java/appeng/block/misc/QuartzFixtureBlock.java
@@ -161,7 +161,7 @@ public class QuartzFixtureBlock extends AEBaseBlock implements IOrientableBlock
         final double yOff = -0.3 * up.getOffsetY();
         final double zOff = -0.3 * up.getOffsetZ();
         for (int bolts = 0; bolts < 3; bolts++) {
-            if (AppEng.proxy.shouldAddParticles(r)) {
+            if (AppEng.instance().shouldAddParticles(r)) {
                 w.addParticle(ParticleTypes.LIGHTNING, xOff + 0.5 + pos.getX(), yOff + 0.5 + pos.getY(),
                         zOff + 0.5 + pos.getZ(), 0, 0, 0);
             }
diff --git a/src/main/java/appeng/block/misc/SkyCompassRendering.java b/core/src/main/java/appeng/block/misc/SkyCompassRendering.java
similarity index 100%
rename from src/main/java/appeng/block/misc/SkyCompassRendering.java
rename to core/src/main/java/appeng/block/misc/SkyCompassRendering.java
diff --git a/src/main/java/appeng/block/misc/TinyTNTBlock.java b/core/src/main/java/appeng/block/misc/TinyTNTBlock.java
similarity index 100%
rename from src/main/java/appeng/block/misc/TinyTNTBlock.java
rename to core/src/main/java/appeng/block/misc/TinyTNTBlock.java
diff --git a/core/src/main/java/appeng/bootstrap/BlockEntityBuilder.java b/core/src/main/java/appeng/bootstrap/BlockEntityBuilder.java
index 27d97909d..4464039f2 100644
--- a/core/src/main/java/appeng/bootstrap/BlockEntityBuilder.java
+++ b/core/src/main/java/appeng/bootstrap/BlockEntityBuilder.java
@@ -103,11 +103,11 @@ public class BlockEntityBuilder {
                     baseTileBlock.setTileEntity(tileClass, factory);
                 }
             }
-        });
 
-        if (Platform.hasClientClasses()) {
-            buildClient();
-        }
+            if (Platform.hasClientClasses()) {
+                buildClient();
+            }
+        });
 
         return new TileEntityDefinition(this::addBlock);
 
@@ -115,11 +115,9 @@ public class BlockEntityBuilder {
 
     @Environment(EnvType.CLIENT)
     private void buildClient() {
-        this.factory.addBootstrapComponent((IClientSetupComponent) () -> {
-            if (tileEntityRendering.tileEntityRenderer != null) {
-                BlockEntityRendererRegistry.INSTANCE.register(type, tileEntityRendering.tileEntityRenderer);
-            }
-        });
+        if (tileEntityRendering.tileEntityRenderer != null) {
+            BlockEntityRendererRegistry.INSTANCE.register(type, tileEntityRendering.tileEntityRenderer);
+        }
     }
 
     private void addBlock(Block block) {
diff --git a/core/src/main/java/appeng/bootstrap/components/IItemColorRegistrationComponent.java b/core/src/main/java/appeng/bootstrap/components/IItemColorRegistrationComponent.java
index 47b520ea7..41b2b27ae 100644
--- a/core/src/main/java/appeng/bootstrap/components/IItemColorRegistrationComponent.java
+++ b/core/src/main/java/appeng/bootstrap/components/IItemColorRegistrationComponent.java
@@ -7,6 +7,6 @@ import appeng.bootstrap.IBootstrapComponent;
 
 public interface IItemColorRegistrationComponent extends IBootstrapComponent {
 
-    void register(ItemColors itemColors, BlockColors blockColors);
+    void register();
 
 }
diff --git a/core/src/main/java/appeng/bootstrap/components/ItemColorComponent.java b/core/src/main/java/appeng/bootstrap/components/ItemColorComponent.java
index d5e28b921..05c3cf433 100644
--- a/core/src/main/java/appeng/bootstrap/components/ItemColorComponent.java
+++ b/core/src/main/java/appeng/bootstrap/components/ItemColorComponent.java
@@ -18,6 +18,7 @@
 
 package appeng.bootstrap.components;
 
+import net.fabricmc.fabric.api.client.rendering.v1.ColorProviderRegistry;
 import net.minecraft.client.color.block.BlockColors;
 import net.minecraft.client.color.item.ItemColorProvider;
 import net.minecraft.client.color.item.ItemColors;
@@ -34,7 +35,7 @@ public class ItemColorComponent implements IItemColorRegistrationComponent {
     }
 
     @Override
-    public void register(ItemColors itemColors, BlockColors blockColors) {
-        itemColors.register(this.itemColor, this.item);
+    public void register() {
+        ColorProviderRegistry.ITEM.register(itemColor, item);
     }
 }
diff --git a/core/src/main/java/appeng/client/AppEngClient.java b/core/src/main/java/appeng/client/AppEngClient.java
new file mode 100644
index 000000000..48bdd2bee
--- /dev/null
+++ b/core/src/main/java/appeng/client/AppEngClient.java
@@ -0,0 +1,166 @@
+package appeng.client;
+
+import appeng.api.parts.CableRenderMode;
+import appeng.block.AEBaseBlock;
+import appeng.bootstrap.ModelsReloadCallback;
+import appeng.bootstrap.components.IItemColorRegistrationComponent;
+import appeng.bootstrap.components.IModelBakeComponent;
+import appeng.client.render.effects.*;
+import appeng.client.render.tesr.SkyChestTESR;
+import appeng.core.Api;
+import appeng.core.ApiDefinitions;
+import appeng.core.AppEngBase;
+import appeng.core.sync.BasePacket;
+import appeng.entity.*;
+import net.fabricmc.fabric.api.client.particle.v1.ParticleFactoryRegistry;
+import net.fabricmc.fabric.api.client.rendereregistry.v1.EntityRendererRegistry;
+import net.fabricmc.fabric.api.event.client.ClientSpriteRegistryCallback;
+import net.minecraft.block.entity.BlockEntity;
+import net.minecraft.client.MinecraftClient;
+import net.minecraft.client.render.entity.ItemEntityRenderer;
+import net.minecraft.client.render.model.BakedModel;
+import net.minecraft.client.util.InputUtil;
+import net.minecraft.client.util.SpriteIdentifier;
+import net.minecraft.entity.player.PlayerEntity;
+import net.minecraft.util.Identifier;
+import net.minecraft.util.hit.HitResult;
+import net.minecraft.world.World;
+
+import javax.annotation.Nonnull;
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+import java.util.Random;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+public class AppEngClient extends AppEngBase {
+
+    private final MinecraftClient client;
+
+    public AppEngClient() {
+        super();
+
+        client = MinecraftClient.getInstance();
+
+        ModelsReloadCallback.EVENT.register(this::onModelsReloaded);
+
+        registerParticleRenderers();
+        registerEntityRenderers();
+        registerItemColors();
+        registerTextures();
+    }
+
+    @Override
+    public void bindTileEntitySpecialRenderer(Class tile, AEBaseBlock blk) {
+
+    }
+
+    @Override
+    public List getPlayers() {
+        return null;
+    }
+
+    @Override
+    public void sendToAllNearExcept(PlayerEntity p, double x, double y, double z, double dist, World w, BasePacket packet) {
+
+    }
+
+    @Override
+    public void spawnEffect(EffectType effect, World world, double posX, double posY, double posZ, Object extra) {
+
+    }
+
+    @Override
+    public boolean shouldAddParticles(Random r) {
+        return false;
+    }
+
+    @Override
+    public HitResult getRTR() {
+        return null;
+    }
+
+    @Override
+    public void postInit() {
+
+    }
+
+    @Override
+    public CableRenderMode getRenderMode() {
+        return null;
+    }
+
+    @Override
+    public void triggerUpdates() {
+
+    }
+
+    @Override
+    public void updateRenderMode(PlayerEntity player) {
+
+    }
+
+    @Override
+    public boolean isActionKey(@Nonnull ActionKey key, InputUtil.Key input) {
+        return false;
+    }
+
+    protected void registerParticleRenderers() {
+        ParticleFactoryRegistry particles = ParticleFactoryRegistry.getInstance();
+        particles.register(ParticleTypes.CHARGED_ORE, ChargedOreFX.Factory::new);
+        particles.register(ParticleTypes.CRAFTING, CraftingFx.Factory::new);
+        particles.register(ParticleTypes.ENERGY, EnergyFx.Factory::new);
+        particles.register(ParticleTypes.LIGHTNING_ARC, LightningArcFX.Factory::new);
+        particles.register(ParticleTypes.LIGHTNING, LightningFX.Factory::new);
+        particles.register(ParticleTypes.MATTER_CANNON, MatterCannonFX.Factory::new);
+        particles.register(ParticleTypes.VIBRANT, VibrantFX.Factory::new);
+    }
+
+    protected void registerEntityRenderers() {
+        EntityRendererRegistry registry = EntityRendererRegistry.INSTANCE;
+
+        registry.register(TinyTNTPrimedEntity.TYPE, (dispatcher, context) -> new TinyTNTPrimedRenderer(dispatcher));
+
+        EntityRendererRegistry.Factory itemEntityFactory = (dispatcher, context) -> new ItemEntityRenderer(dispatcher, context.getItemRenderer());
+        registry.register(SingularityEntity.TYPE, itemEntityFactory);
+        registry.register(GrowingCrystalEntity.TYPE, itemEntityFactory);
+        registry.register(ChargedQuartzEntity.TYPE, itemEntityFactory);
+    }
+
+    protected void registerItemColors() {
+        // TODO: Do not use the internal API
+        final ApiDefinitions definitions = Api.INSTANCE.definitions();
+        definitions.getRegistry().getBootstrapComponents(IItemColorRegistrationComponent.class)
+                .forEachRemaining(IItemColorRegistrationComponent::register);
+    }
+
+    protected void onModelsReloaded(Map loadedModels) {
+        // TODO: Do not use the internal API
+        final ApiDefinitions definitions = Api.INSTANCE.definitions();
+        definitions.getRegistry().getBootstrapComponents(IModelBakeComponent.class)
+                .forEachRemaining(c -> c.onModelsReloaded(loadedModels));
+    }
+
+    public void registerTextures() {
+        // FIXME FABRIC InscriberTESR.registerTexture();
+        Stream> sprites = Stream.of(
+                SkyChestTESR.SPRITES
+        );
+
+        // Group every needed sprite by atlas, since every atlas has their own event
+        Map> groupedByAtlas = sprites.flatMap(Collection::stream)
+                .collect(Collectors.groupingBy(SpriteIdentifier::getAtlasId));
+
+        // Register to the stitch event for each atlas
+        for (Map.Entry> entry : groupedByAtlas.entrySet()) {
+            ClientSpriteRegistryCallback.event(entry.getKey())
+                    .register((spriteAtlasTexture, registry) -> {
+                        for (SpriteIdentifier spriteIdentifier : entry.getValue()) {
+                            registry.register(spriteIdentifier.getTextureId());
+                        }
+                    });
+        }
+    }
+
+}
diff --git a/src/main/java/appeng/client/render/FacingToRotation.java b/core/src/main/java/appeng/client/render/FacingToRotation.java
similarity index 88%
rename from src/main/java/appeng/client/render/FacingToRotation.java
rename to core/src/main/java/appeng/client/render/FacingToRotation.java
index 1903d1aa0..5c4c04150 100644
--- a/src/main/java/appeng/client/render/FacingToRotation.java
+++ b/core/src/main/java/appeng/client/render/FacingToRotation.java
@@ -20,10 +20,10 @@ package appeng.client.render;
 
 import net.minecraft.client.util.math.MatrixStack;
 
+import net.minecraft.client.util.math.Vector4f;
 import net.minecraft.util.math.Matrix4f;
-import net.minecraft.client.renderer.Quaternion;
+import net.minecraft.util.math.Quaternion;
 import net.minecraft.client.util.math.Vector3f;
-import net.minecraft.client.renderer.Vector4f;
 import net.minecraft.util.StringIdentifiable;
 import net.minecraft.util.math.Direction;
 import net.minecraft.util.math.Vec3i;
@@ -65,10 +65,10 @@ public enum FacingToRotation implements StringIdentifiable {
     private FacingToRotation(Vector3f rot) {
         this.rot = rot;
         this.mat = new Matrix4f();
-        this.mat.setIdentity();
-        this.mat.mul(xRot = Vector3f.POSITIVE_X.getDegreesQuaternion(rot.getX()));
-        this.mat.mul(yRot = Vector3f.POSITIVE_Y.getDegreesQuaternion(rot.getY()));
-        this.mat.mul(zRot = Vector3f.POSITIVE_Z.getDegreesQuaternion(rot.getZ()));
+        this.mat.loadIdentity();
+        this.mat.multiply(xRot = Vector3f.POSITIVE_X.getDegreesQuaternion(rot.getX()));
+        this.mat.multiply(yRot = Vector3f.POSITIVE_Y.getDegreesQuaternion(rot.getY()));
+        this.mat.multiply(zRot = Vector3f.POSITIVE_Z.getDegreesQuaternion(rot.getZ()));
     }
 
     public boolean isRedundant() {
@@ -90,10 +90,10 @@ public enum FacingToRotation implements StringIdentifiable {
     }
 
     public Direction rotate(Direction facing) {
-        Vec3i dir = facing.getDirectionVec();
+        Vec3i dir = facing.getVector();
         Vector4f vec = new Vector4f(dir.getX(), dir.getY(), dir.getZ(), 1);
         vec.transform(mat);
-        return Direction.getFacingFromVector(vec.getX(), vec.getY(), vec.getZ());
+        return Direction.getFacing(vec.getX(), vec.getY(), vec.getZ());
     }
 
     public Direction resultingRotate(Direction facing) {
diff --git a/core/src/main/java/appeng/client/render/effects/ParticleTypes.java b/core/src/main/java/appeng/client/render/effects/ParticleTypes.java
index 46da0dd63..8baeb1286 100644
--- a/core/src/main/java/appeng/client/render/effects/ParticleTypes.java
+++ b/core/src/main/java/appeng/client/render/effects/ParticleTypes.java
@@ -1,6 +1,11 @@
 package appeng.client.render.effects;
 
+import net.fabricmc.api.EnvType;
+import net.fabricmc.api.Environment;
+import net.fabricmc.fabric.api.client.particle.v1.ParticleFactoryRegistry;
 import net.fabricmc.fabric.api.particle.v1.FabricParticleTypes;
+import net.minecraft.client.MinecraftClient;
+import net.minecraft.client.particle.ParticleManager;
 import net.minecraft.particle.DefaultParticleType;
 import net.minecraft.particle.ParticleType;
 
@@ -22,14 +27,8 @@ public final class ParticleTypes {
     public static final DefaultParticleType MATTER_CANNON = FabricParticleTypes.simple(false);
     public static final DefaultParticleType VIBRANT = FabricParticleTypes.simple(false);
 
-    public static void register() {
-        Registry.register(Registry.PARTICLE_TYPE, AppEng.makeId("charged_ore_fx"), CHARGED_ORE);
-        Registry.register(Registry.PARTICLE_TYPE, AppEng.makeId("crafting_fx"), CRAFTING);
-        Registry.register(Registry.PARTICLE_TYPE, AppEng.makeId("energy_fx"), ENERGY);
-        Registry.register(Registry.PARTICLE_TYPE, AppEng.makeId("lightning_arc_fx"), LIGHTNING_ARC);
-        Registry.register(Registry.PARTICLE_TYPE, AppEng.makeId("lightning_fx"), LIGHTNING);
-        Registry.register(Registry.PARTICLE_TYPE, AppEng.makeId("matter_cannon_fx"), MATTER_CANNON);
-        Registry.register(Registry.PARTICLE_TYPE, AppEng.makeId("vibrant_fx"), VIBRANT);
+    public static void registerClient() {
     }
 
+
 }
diff --git a/src/main/java/appeng/client/render/tesr/SkyChestTESR.java b/core/src/main/java/appeng/client/render/tesr/SkyChestTESR.java
similarity index 64%
rename from src/main/java/appeng/client/render/tesr/SkyChestTESR.java
rename to core/src/main/java/appeng/client/render/tesr/SkyChestTESR.java
index c0f808286..5ac8c31be 100644
--- a/src/main/java/appeng/client/render/tesr/SkyChestTESR.java
+++ b/core/src/main/java/appeng/client/render/tesr/SkyChestTESR.java
@@ -18,86 +18,91 @@
 
 package appeng.client.render.tesr;
 
-import net.fabricmc.api.EnvType;
-import net.fabricmc.api.Environment;
-import net.minecraft.client.render.VertexConsumer;
-import net.minecraft.client.render.VertexConsumerProvider;
-import net.minecraft.client.render.block.entity.BlockEntityRenderer;
-import net.minecraft.client.util.math.MatrixStack;
-
-import net.minecraft.block.Block;
-import net.minecraft.client.renderer.Atlases;
-import net.minecraft.client.render.RenderLayer;
-import net.minecraft.client.util.math.Vector3f;
-import net.minecraft.client.render.model.Material;
-import net.minecraft.client.render.model.ModelRenderer;
-import net.minecraft.client.render.block.entity.BlockEntityRenderDispatcher;
-import net.minecraft.util.Identifier;
-import net.minecraftforge.client.event.TextureStitchEvent;
-
 import appeng.block.storage.SkyChestBlock;
 import appeng.block.storage.SkyChestBlock.SkyChestType;
 import appeng.core.AppEng;
 import appeng.tile.storage.SkyChestBlockEntity;
+import com.google.common.collect.ImmutableList;
+import net.fabricmc.api.EnvType;
+import net.fabricmc.api.Environment;
+import net.fabricmc.fabric.api.event.client.ClientSpriteRegistryCallback;
+import net.minecraft.block.Block;
+import net.minecraft.client.model.ModelPart;
+import net.minecraft.client.render.RenderLayer;
+import net.minecraft.client.render.TexturedRenderLayers;
+import net.minecraft.client.render.VertexConsumer;
+import net.minecraft.client.render.VertexConsumerProvider;
+import net.minecraft.client.render.block.entity.BlockEntityRenderDispatcher;
+import net.minecraft.client.render.block.entity.BlockEntityRenderer;
+import net.minecraft.client.util.SpriteIdentifier;
+import net.minecraft.client.util.math.MatrixStack;
+import net.minecraft.client.util.math.Vector3f;
+import net.minecraft.util.Identifier;
 
 // This is mostly a copy&paste job of the vanilla chest TESR
 @Environment(EnvType.CLIENT)
 public class SkyChestTESR extends BlockEntityRenderer {
 
-    public static final Material TEXTURE_STONE = new Material(Atlases.CHEST_ATLAS,
+    public static final SpriteIdentifier TEXTURE_STONE = new SpriteIdentifier(TexturedRenderLayers.CHEST_ATLAS_TEXTURE,
             new Identifier(AppEng.MOD_ID, "models/skychest"));
-    public static final Material TEXTURE_BLOCK = new Material(Atlases.CHEST_ATLAS,
+    public static final SpriteIdentifier TEXTURE_BLOCK = new SpriteIdentifier(TexturedRenderLayers.CHEST_ATLAS_TEXTURE,
             new Identifier(AppEng.MOD_ID, "models/skyblockchest"));
 
-    private final ModelRenderer singleLid;
-    private final ModelRenderer singleBottom;
-    private final ModelRenderer singleLatch;
+    public static final ImmutableList SPRITES = ImmutableList.of(
+            TEXTURE_STONE,
+            TEXTURE_BLOCK
+    );
+
+    private final ModelPart singleLid;
+    private final ModelPart singleBottom;
+    private final ModelPart singleLatch;
 
     public SkyChestTESR(BlockEntityRenderDispatcher rendererDispatcherIn) {
         super(rendererDispatcherIn);
 
-        this.singleBottom = new ModelRenderer(64, 64, 0, 19);
-        this.singleBottom.addBox(1.0F, 0.0F, 1.0F, 14.0F, 10.0F, 14.0F, 0.0F);
-        this.singleLid = new ModelRenderer(64, 64, 0, 0);
-        this.singleLid.addBox(1.0F, 0.0F, 0.0F, 14.0F, 5.0F, 14.0F, 0.0F);
-        this.singleLid.rotationPointY = 9.0F;
-        this.singleLid.rotationPointZ = 1.0F;
-        this.singleLatch = new ModelRenderer(64, 64, 0, 0);
-        this.singleLatch.addBox(7.0F, -1.0F, 15.0F, 2.0F, 4.0F, 1.0F, 0.0F);
-        this.singleLatch.rotationPointY = 8.0F;
+        this.singleBottom = new ModelPart(64, 64, 0, 19);
+        this.singleBottom.addCuboid(1.0F, 0.0F, 1.0F, 14.0F, 10.0F, 14.0F, 0.0F);
+        this.singleLid = new ModelPart(64, 64, 0, 0);
+        this.singleLid.addCuboid(1.0F, 0.0F, 0.0F, 14.0F, 5.0F, 14.0F, 0.0F);
+        this.singleLid.pivotY = 9.0F;
+        this.singleLid.pivotZ = 1.0F;
+        this.singleLatch = new ModelPart(64, 64, 0, 0);
+        this.singleLatch.addCuboid(7.0F, -1.0F, 15.0F, 2.0F, 4.0F, 1.0F, 0.0F);
+        this.singleLatch.pivotY = 8.0F;
     }
 
     @Override
     public void render(SkyChestBlockEntity tileEntityIn, float partialTicks, MatrixStack matrixStackIn,
                        VertexConsumerProvider bufferIn, int combinedLightIn, int combinedOverlayIn) {
         matrixStackIn.push();
-        float f = tileEntityIn.getForward().getHorizontalAngle();
+        float f = tileEntityIn.getForward().asRotation();
         matrixStackIn.translate(0.5D, 0.5D, 0.5D);
         matrixStackIn.multiply(Vector3f.POSITIVE_Y.getDegreesQuaternion(-f));
         matrixStackIn.translate(-0.5D, -0.5D, -0.5D);
 
-        float f1 = tileEntityIn.getLidAngle(partialTicks);
+        float f1 = tileEntityIn.getAnimationProgress(partialTicks);
         f1 = 1.0F - f1;
         f1 = 1.0F - f1 * f1 * f1;
-        Material material = this.getMaterial(tileEntityIn);
-        VertexConsumer ivertexbuilder = material.getBuffer(bufferIn, RenderLayer::getEntityCutout);
+        SpriteIdentifier material = this.getMaterial(tileEntityIn);
+        VertexConsumer ivertexbuilder = material.getVertexConsumer(bufferIn, RenderLayer::getEntityCutout);
         this.renderModels(matrixStackIn, ivertexbuilder, this.singleLid, this.singleLatch, this.singleBottom, f1,
                 combinedLightIn, combinedOverlayIn);
 
         matrixStackIn.pop();
     }
 
-    private void renderModels(MatrixStack matrixStackIn, VertexConsumer bufferIn, ModelRenderer chestLid,
-                              ModelRenderer chestLatch, ModelRenderer chestBottom, float lidAngle, int combinedLightIn,
+    // See ChestBlockEntityRenderer
+    private void renderModels(MatrixStack matrixStackIn, VertexConsumer bufferIn, ModelPart chestLid,
+                              ModelPart chestLatch, ModelPart chestBottom, float lidAngle, int combinedLightIn,
                               int combinedOverlayIn) {
-        chestLid.rotateAngleX = -(lidAngle * 1.5707964F);
-        chestLatch.rotateAngleX = chestLid.rotateAngleX;
+        chestLid.pitch = -(lidAngle * 1.5707964F);
+        chestLatch.pitch = chestLid.pitch;
         chestLid.render(matrixStackIn, bufferIn, combinedLightIn, combinedOverlayIn);
         chestLatch.render(matrixStackIn, bufferIn, combinedLightIn, combinedOverlayIn);
         chestBottom.render(matrixStackIn, bufferIn, combinedLightIn, combinedOverlayIn);
     }
 
-    protected Material getMaterial(SkyChestBlockEntity tileEntity) {
+    protected SpriteIdentifier getMaterial(SkyChestBlockEntity tileEntity) {
         SkyChestType type = SkyChestType.BLOCK;
         if (tileEntity.getWorld() != null) {
             Block blockType = tileEntity.getCachedState().getBlock();
@@ -116,11 +121,4 @@ public class SkyChestTESR extends BlockEntityRenderer {
         }
     }
 
-    public static void registerTextures(TextureStitchEvent.Pre evt) {
-        if (evt.getMap().getTextureLocation().equals(Atlases.CHEST_ATLAS)) {
-            evt.addSprite(TEXTURE_STONE.getTextureLocation());
-            evt.addSprite(TEXTURE_BLOCK.getTextureLocation());
-        }
-    }
-
 }
diff --git a/src/main/java/appeng/client/render/tesr/SkyCompassTESR.java b/core/src/main/java/appeng/client/render/tesr/SkyCompassTESR.java
similarity index 79%
rename from src/main/java/appeng/client/render/tesr/SkyCompassTESR.java
rename to core/src/main/java/appeng/client/render/tesr/SkyCompassTESR.java
index 58f0dedf6..e906b88c9 100644
--- a/src/main/java/appeng/client/render/tesr/SkyCompassTESR.java
+++ b/core/src/main/java/appeng/client/render/tesr/SkyCompassTESR.java
@@ -26,16 +26,14 @@ import net.minecraft.client.util.math.MatrixStack;
 
 import net.minecraft.block.BlockState;
 import net.minecraft.client.MinecraftClient;
-import net.minecraft.client.renderer.Atlases;
+import net.minecraft.client.render.TexturedRenderLayers;
 import net.minecraft.client.render.block.BlockRenderManager;
 import net.minecraft.client.render.VertexConsumerProvider;
 import net.minecraft.client.render.block.entity.BlockEntityRenderer;
 import net.minecraft.util.math.Direction;
 import net.fabricmc.api.Environment;
-import net.minecraftforge.client.model.data.ModelDataMap;
 
 import appeng.client.render.FacingToRotation;
-import appeng.client.render.model.SkyCompassBakedModel;
 import appeng.tile.misc.SkyCompassBlockEntity;
 
 @Environment(EnvType.CLIENT)
@@ -55,10 +53,10 @@ public class SkyCompassTESR extends BlockEntityRenderer {
             blockRenderer = MinecraftClient.getInstance().getBlockRenderManager();
         }
 
-        VertexConsumer buffer = buffers.getBuffer(Atlases.getTranslucentBlockType());
+        VertexConsumer buffer = buffers.getBuffer(TexturedRenderLayers.getEntityTranslucentCull());
 
         BlockState blockState = te.getCachedState();
-        BakedModel model = blockRenderer.getBlockModelShapes().getModel(blockState);
+        BakedModel model = blockRenderer.getModels().getModel(blockState);
 
         // FIXME: Rotation was previously handled by an auto rotating model I think, but
         // FIXME: Should be handled using matrices instead
@@ -77,26 +75,26 @@ public class SkyCompassTESR extends BlockEntityRenderer {
         FacingToRotation.get(up, forward).push(ms);
         ms.translate(-0.5D, -0.5D, -0.5D);
 
-        ModelDataMap modelData = new ModelDataMap.Builder().withInitial(SkyCompassBakedModel.ROTATION, getRotation(te))
-                .build();
+        // FIXME FABRIC ModelDataMap modelData = new ModelDataMap.Builder().withInitial(SkyCompassBakedModel.ROTATION, getRotation(te)).build();
 
-        blockRenderer.getBlockModelRenderer().renderModel(ms.getLast(), buffer, null, model, 1, 1, 1, combinedLightIn,
-                combinedOverlayIn, modelData);
+        blockRenderer.getModelRenderer().render(ms.peek(), buffer, null, model, 1, 1, 1, combinedLightIn,
+                combinedOverlayIn);
         ms.pop();
 
     }
 
+    // FIXME FABRIC This needs to go to the tile entity (?)
     private static float getRotation(SkyCompassBlockEntity skyCompass) {
-        float rotation;
+        float rotation = 0;
 
         if (skyCompass.getForward() == Direction.UP || skyCompass.getForward() == Direction.DOWN) {
-            rotation = SkyCompassBakedModel.getAnimatedRotation(skyCompass.getPos(), false);
+            // FIXME FABRIC rotation = SkyCompassBakedModel.getAnimatedRotation(skyCompass.getPos(), false);
         } else {
-            rotation = SkyCompassBakedModel.getAnimatedRotation(null, false);
+            // FIXME FABRIC rotation = SkyCompassBakedModel.getAnimatedRotation(null, false);
         }
 
         if (skyCompass.getForward() == Direction.DOWN) {
-            rotation = flipidiy(rotation);
+            // FIXME FABRIC rotation = flipidiy(rotation);
         }
 
         return rotation;
diff --git a/core/src/main/java/appeng/core/AEConfig.java b/core/src/main/java/appeng/core/AEConfig.java
index adbcb075b..f2acfdf7d 100644
--- a/core/src/main/java/appeng/core/AEConfig.java
+++ b/core/src/main/java/appeng/core/AEConfig.java
@@ -35,7 +35,7 @@ public final class AEConfig {
     public final ClientConfig clientConfig;
     public final CommonConfig commonConfig;
 
-    public AEConfig(File configDir) {
+    AEConfig(File configDir) {
         ConfigSection clientRoot = ConfigSection.createRoot();
         clientConfig = new ClientConfig(clientRoot);
         syncClientConfig();
@@ -57,6 +57,13 @@ public final class AEConfig {
     // Config instance
     private static AEConfig instance;
 
+    static void load(File configFolder) {
+        if (instance != null) {
+            throw new IllegalStateException();
+        }
+        instance = new AEConfig(configFolder);
+    }
+
     private final EnumSet featureFlags = EnumSet.noneOf(AEFeature.class);
 
     // Misc
diff --git a/src/main/java/appeng/core/Api.java b/core/src/main/java/appeng/core/Api.java
similarity index 94%
rename from src/main/java/appeng/core/Api.java
rename to core/src/main/java/appeng/core/Api.java
index fa4240502..d3d0115d7 100644
--- a/src/main/java/appeng/core/Api.java
+++ b/core/src/main/java/appeng/core/Api.java
@@ -31,18 +31,17 @@ import appeng.core.features.registries.PartModels;
 import appeng.core.features.registries.RegistryContainer;
 
 public final class Api implements IAppEngApi {
-    public static final Api INSTANCE = new Api();
+    public static Api INSTANCE;
 
     private final ApiPart partHelper;
 
-    // private MovableTileRegistry MovableRegistry = new MovableTileRegistry();
     private final IRegistryContainer registryContainer;
     private final IStorageHelper storageHelper;
     private final IGridHelper networkHelper;
     private final ApiDefinitions definitions;
     private final IClientHelper client;
 
-    private Api() {
+    Api() {
         this.storageHelper = new ApiStorage();
         this.networkHelper = new ApiGrid();
         this.registryContainer = new RegistryContainer();
diff --git a/src/main/java/appeng/core/ApiDefinitions.java b/core/src/main/java/appeng/core/ApiDefinitions.java
similarity index 100%
rename from src/main/java/appeng/core/ApiDefinitions.java
rename to core/src/main/java/appeng/core/ApiDefinitions.java
diff --git a/core/src/main/java/appeng/core/AppEng.java b/core/src/main/java/appeng/core/AppEng.java
index 3a5015fbc..49cf4e403 100644
--- a/core/src/main/java/appeng/core/AppEng.java
+++ b/core/src/main/java/appeng/core/AppEng.java
@@ -36,9 +36,13 @@ import java.util.Random;
 
 public interface AppEng {
 
+    String MOD_NAME = "Applied Energistics 2";
+
     String MOD_ID = "appliedenergistics2";
 
-    AppEng INSTANCE = null;
+    static AppEng instance() {
+        return AppEngHolder.INSTANCE;
+    }
 
     static Identifier makeId(String id) {
         return new Identifier(MOD_ID, id);
@@ -68,28 +72,14 @@ public interface AppEng {
 
     boolean isActionKey(@Nonnull final ActionKey key, InputUtil.Key input);
 
-//    public static final String MOD_NAME = "Applied Energistics 2";
-//
-//    private static AppEng INSTANCE;
 //
 //    private final Registration registration;
 //
 //    public AppEng() {
-//        if (INSTANCE != null) {
-//            throw new IllegalStateException();
-//        }
 //        INSTANCE = this;
-//        ParticleTypes.register();
-//        ModLoadingContext.get().registerConfig(ModConfig.Type.CLIENT, AEConfig.CLIENT_SPEC);
-//        ModLoadingContext.get().registerConfig(ModConfig.Type.COMMON, AEConfig.COMMON_SPEC);
-//
-//        proxy = DistExecutor.runForDist(() -> ClientHelper::new, () -> ServerHelper::new);
 //
 //        CrashReportExtender.registerCrashCallable(new ModCrashEnhancement());
 //
-//        CreativeTab.init();
-//        new FacadeItemGroup(); // This call has a side-effect (adding it to the creative screen)
-//
 //        IEventBus modEventBus = FMLJavaModLoadingContext.get().getModEventBus();
 //        registration = new Registration();
 //        modEventBus.addGenericListener(Block.class, registration::registerBlocks);
@@ -142,14 +132,6 @@ public interface AppEng {
 //
 //        ((ClientHelper) proxy).clientInit();
 //
-//        RenderingRegistry.registerEntityRenderingHandler(TinyTNTPrimedEntity.TYPE, TinyTNTPrimedRenderer::new);
-//        RenderingRegistry.registerEntityRenderingHandler(SingularityEntity.TYPE,
-//                m -> new ItemRenderer(m, MinecraftClient.getInstance().getItemRenderer()));
-//        RenderingRegistry.registerEntityRenderingHandler(GrowingCrystalEntity.TYPE,
-//                m -> new ItemRenderer(m, MinecraftClient.getInstance().getItemRenderer()));
-//        RenderingRegistry.registerEntityRenderingHandler(ChargedQuartzEntity.TYPE,
-//                m -> new ItemRenderer(m, MinecraftClient.getInstance().getItemRenderer()));
-//
 //        // TODO: Do not use the internal API
 //        final ApiDefinitions definitions = Api.INSTANCE.definitions();
 //        definitions.getRegistry().getBootstrapComponents(IClientSetupComponent.class)
diff --git a/core/src/main/java/appeng/core/AppEngBase.java b/core/src/main/java/appeng/core/AppEngBase.java
new file mode 100644
index 000000000..27b483ea1
--- /dev/null
+++ b/core/src/main/java/appeng/core/AppEngBase.java
@@ -0,0 +1,91 @@
+package appeng.core;
+
+import appeng.api.features.IRegistryContainer;
+import appeng.api.networking.IGridCacheRegistry;
+import appeng.api.networking.crafting.ICraftingGrid;
+import appeng.api.networking.energy.IEnergyGrid;
+import appeng.api.networking.pathing.IPathingGrid;
+import appeng.api.networking.security.ISecurityGrid;
+import appeng.api.networking.spatial.ISpatialCache;
+import appeng.api.networking.storage.IStorageGrid;
+import appeng.api.networking.ticking.ITickManager;
+import appeng.bootstrap.components.ITileEntityRegistrationComponent;
+import appeng.client.render.effects.ParticleTypes;
+import appeng.core.features.registries.cell.BasicCellHandler;
+import appeng.core.features.registries.cell.BasicItemCellGuiHandler;
+import appeng.core.features.registries.cell.CreativeCellHandler;
+import appeng.core.stats.AdvancementTriggers;
+import appeng.core.stats.AeStats;
+import appeng.hooks.ToolItemHook;
+import appeng.mixins.CriteriaRegisterMixin;
+import net.fabricmc.loader.api.FabricLoader;
+import net.minecraft.util.registry.Registry;
+
+public abstract class AppEngBase implements AppEng {
+
+    protected AdvancementTriggers advancementTriggers;
+
+    public AppEngBase() {
+        if (AppEng.instance() != null) {
+            throw new IllegalStateException();
+        }
+
+        AEConfig.load(FabricLoader.getInstance().getConfigDirectory());
+
+        CreativeTab.init();
+        // FIXME FABRIC new FacadeItemGroup(); // This call has a side-effect (adding it to the creative screen)
+
+        AeStats.register();
+        advancementTriggers = new AdvancementTriggers(CriteriaRegisterMixin::callRegister);
+
+        ToolItemHook.install();
+
+        Api.INSTANCE = new Api();
+        registerTileEntities();
+
+        registerParticleTypes();
+
+        setupInternalRegistries();
+
+    }
+
+    public static void setupInternalRegistries() {
+        // TODO: Do not use the internal API
+        final Api api = Api.INSTANCE;
+        final IRegistryContainer registries = api.registries();
+
+        final IGridCacheRegistry gcr = registries.gridCache();
+// FIXME FABRIC        gcr.registerGridCache(ITickManager.class, TickManagerCache.class);
+// FIXME FABRIC        gcr.registerGridCache(IEnergyGrid.class, EnergyGridCache.class);
+// FIXME FABRIC        gcr.registerGridCache(IPathingGrid.class, PathGridCache.class);
+// FIXME FABRIC        gcr.registerGridCache(IStorageGrid.class, GridStorageCache.class);
+// FIXME FABRIC        gcr.registerGridCache(P2PCache.class, P2PCache.class);
+// FIXME FABRIC        gcr.registerGridCache(ISpatialCache.class, SpatialPylonCache.class);
+// FIXME FABRIC        gcr.registerGridCache(ISecurityGrid.class, SecurityCache.class);
+// FIXME FABRIC        gcr.registerGridCache(ICraftingGrid.class, CraftingGridCache.class);
+
+        registries.cell().addCellHandler(new BasicCellHandler());
+        registries.cell().addCellHandler(new CreativeCellHandler());
+        registries.cell().addCellGuiHandler(new BasicItemCellGuiHandler());
+// FIXME FABRIC        registries.cell().addCellGuiHandler(new BasicFluidCellGuiHandler());
+
+        registries.matterCannon().registerAmmoItem(api.definitions().materials().matterBall().item(), 32);
+    }
+
+    protected void registerParticleTypes() {
+        Registry.register(Registry.PARTICLE_TYPE, AppEng.makeId("charged_ore_fx"), ParticleTypes.CHARGED_ORE);
+        Registry.register(Registry.PARTICLE_TYPE, AppEng.makeId("crafting_fx"), ParticleTypes.CRAFTING);
+        Registry.register(Registry.PARTICLE_TYPE, AppEng.makeId("energy_fx"), ParticleTypes.ENERGY);
+        Registry.register(Registry.PARTICLE_TYPE, AppEng.makeId("lightning_arc_fx"), ParticleTypes.LIGHTNING_ARC);
+        Registry.register(Registry.PARTICLE_TYPE, AppEng.makeId("lightning_fx"), ParticleTypes.LIGHTNING);
+        Registry.register(Registry.PARTICLE_TYPE, AppEng.makeId("matter_cannon_fx"), ParticleTypes.MATTER_CANNON);
+        Registry.register(Registry.PARTICLE_TYPE, AppEng.makeId("vibrant_fx"), ParticleTypes.VIBRANT);
+    }
+
+    public void registerTileEntities() {
+        final ApiDefinitions definitions = Api.INSTANCE.definitions();
+        definitions.getRegistry().getBootstrapComponents(ITileEntityRegistrationComponent.class)
+                .forEachRemaining(ITileEntityRegistrationComponent::register);
+    }
+
+}
diff --git a/core/src/main/java/appeng/core/AppEngClientStartup.java b/core/src/main/java/appeng/core/AppEngClientStartup.java
new file mode 100644
index 000000000..34aa90091
--- /dev/null
+++ b/core/src/main/java/appeng/core/AppEngClientStartup.java
@@ -0,0 +1,13 @@
+package appeng.core;
+
+import appeng.client.AppEngClient;
+import net.fabricmc.api.ClientModInitializer;
+
+@SuppressWarnings("unused")
+public class AppEngClientStartup implements ClientModInitializer {
+
+    @Override
+    public void onInitializeClient() {
+        AppEngHolder.INSTANCE = new AppEngClient();
+    }
+}
diff --git a/core/src/main/java/appeng/core/AppEngHolder.java b/core/src/main/java/appeng/core/AppEngHolder.java
new file mode 100644
index 000000000..56ebc1869
--- /dev/null
+++ b/core/src/main/java/appeng/core/AppEngHolder.java
@@ -0,0 +1,7 @@
+package appeng.core;
+
+class AppEngHolder {
+
+    static AppEng INSTANCE;
+
+}
diff --git a/core/src/main/java/appeng/core/CreativeTab.java b/core/src/main/java/appeng/core/CreativeTab.java
index 8ae0b8594..b32b82234 100644
--- a/core/src/main/java/appeng/core/CreativeTab.java
+++ b/core/src/main/java/appeng/core/CreativeTab.java
@@ -41,7 +41,7 @@ public final class CreativeTab {
                 .icon(() -> {
                     final IDefinitions definitions = AEApi.instance().definitions();
                     final IBlocks blocks = definitions.blocks();
-                    return blocks.controller().stack(1);
+                    return blocks.quartzOre().stack(1); // FIXME FABRIC blocks.controller().stack(1);
                 })
                 .appendItems(CreativeTab::fill)
                 .build();
diff --git a/src/main/java/appeng/core/api/ApiClientHelper.java b/core/src/main/java/appeng/core/api/ApiClientHelper.java
similarity index 92%
rename from src/main/java/appeng/core/api/ApiClientHelper.java
rename to core/src/main/java/appeng/core/api/ApiClientHelper.java
index e4240362f..7a9e778ca 100644
--- a/src/main/java/appeng/core/api/ApiClientHelper.java
+++ b/core/src/main/java/appeng/core/api/ApiClientHelper.java
@@ -55,10 +55,10 @@ public class ApiClientHelper implements IClientHelper {
                     : GuiText.Excluded).getLocal();
 
             if (handler.isFuzzy()) {
-                lines.add(GuiText.Partitioned.textComponent().append(" - " + list + " ")
+                lines.add(GuiText.Partitioned.textComponent().copy().append(" - " + list + " ")
                         .append(GuiText.Fuzzy.textComponent()));
             } else {
-                lines.add(GuiText.Partitioned.textComponent().append(" - " + list + " ")
+                lines.add(GuiText.Partitioned.textComponent().copy().append(" - " + list + " ")
                         .append(GuiText.Precise.textComponent()));
             }
         }
diff --git a/src/main/java/appeng/core/api/ApiGrid.java b/core/src/main/java/appeng/core/api/ApiGrid.java
similarity index 88%
rename from src/main/java/appeng/core/api/ApiGrid.java
rename to core/src/main/java/appeng/core/api/ApiGrid.java
index 45c8f2c25..13b79bec1 100644
--- a/src/main/java/appeng/core/api/ApiGrid.java
+++ b/core/src/main/java/appeng/core/api/ApiGrid.java
@@ -25,9 +25,6 @@ import appeng.api.networking.IGridBlock;
 import appeng.api.networking.IGridConnection;
 import appeng.api.networking.IGridHelper;
 import appeng.api.networking.IGridNode;
-import appeng.api.util.AEPartLocation;
-import appeng.me.GridConnection;
-import appeng.me.GridNode;
 import appeng.util.Platform;
 
 /**
@@ -45,7 +42,8 @@ public class ApiGrid implements IGridHelper {
             throw new IllegalStateException("Grid features for " + blk + " are server side only.");
         }
 
-        return new GridNode(blk);
+        // FIXME FABRIC return new GridNode(blk);
+        throw new IllegalStateException();
     }
 
     @Override
@@ -53,7 +51,8 @@ public class ApiGrid implements IGridHelper {
         Preconditions.checkNotNull(a);
         Preconditions.checkNotNull(b);
 
-        return GridConnection.create(a, b, AEPartLocation.INTERNAL);
+        // FIXME FABRIC return GridConnection.create(a, b, AEPartLocation.INTERNAL);
+        throw new IllegalStateException();
     }
 
 }
diff --git a/src/main/java/appeng/core/api/ApiPart.java b/core/src/main/java/appeng/core/api/ApiPart.java
similarity index 88%
rename from src/main/java/appeng/core/api/ApiPart.java
rename to core/src/main/java/appeng/core/api/ApiPart.java
index f74a5efeb..0f36df6c8 100644
--- a/src/main/java/appeng/core/api/ApiPart.java
+++ b/core/src/main/java/appeng/core/api/ApiPart.java
@@ -29,18 +29,18 @@ import net.minecraft.world.World;
 import appeng.api.parts.CableRenderMode;
 import appeng.api.parts.IPartHelper;
 import appeng.core.AppEng;
-import appeng.parts.PartPlacement;
 
 public class ApiPart implements IPartHelper {
 
     @Override
     public ActionResult placeBus(final ItemStack is, final BlockPos pos, final Direction side,
             final PlayerEntity player, final Hand hand, final World w) {
-        return PartPlacement.place(is, pos, side, player, hand, w, PartPlacement.PlaceType.PLACE_ITEM, 0);
+        // FIXME return PartPlacement.place(is, pos, side, player, hand, w, PartPlacement.PlaceType.PLACE_ITEM, 0);
+        throw new IllegalStateException();
     }
 
     @Override
     public CableRenderMode getCableRenderMode() {
-        return AppEng.proxy.getRenderMode();
+        return AppEng.instance().getRenderMode();
     }
 }
diff --git a/src/main/java/appeng/core/api/ApiStorage.java b/core/src/main/java/appeng/core/api/ApiStorage.java
similarity index 89%
rename from src/main/java/appeng/core/api/ApiStorage.java
rename to core/src/main/java/appeng/core/api/ApiStorage.java
index 2e040e118..92c62ce5f 100644
--- a/src/main/java/appeng/core/api/ApiStorage.java
+++ b/core/src/main/java/appeng/core/api/ApiStorage.java
@@ -21,7 +21,14 @@ package appeng.core.api;
 import java.util.Collection;
 import java.util.Collections;
 
+import alexiil.mc.lib.attributes.Attributes;
+import alexiil.mc.lib.attributes.Simulation;
+import alexiil.mc.lib.attributes.fluid.FluidAttributes;
+import alexiil.mc.lib.attributes.fluid.FluidExtractable;
+import alexiil.mc.lib.attributes.fluid.FluidVolumeUtil;
+import alexiil.mc.lib.attributes.fluid.amount.FluidAmount;
 import alexiil.mc.lib.attributes.fluid.volume.FluidVolume;
+import appeng.fluids.util.FluidList;
 import com.google.common.base.Preconditions;
 import com.google.common.collect.ClassToInstanceMap;
 import com.google.common.collect.MutableClassToInstanceMap;
@@ -29,7 +36,6 @@ import com.google.common.collect.MutableClassToInstanceMap;
 import net.minecraft.item.ItemStack;
 import net.minecraft.nbt.CompoundTag;
 import net.minecraft.network.PacketByteBuf;
-import net.minecraftforge.fluids.FluidUtil;
 
 import appeng.api.config.Actionable;
 import appeng.api.networking.crafting.ICraftingLink;
@@ -46,10 +52,8 @@ import appeng.api.storage.data.IAEFluidStack;
 import appeng.api.storage.data.IAEItemStack;
 import appeng.api.storage.data.IAEStack;
 import appeng.api.storage.data.IItemList;
-import appeng.crafting.CraftingLink;
 import appeng.fluids.items.FluidDummyItem;
 import appeng.fluids.util.AEFluidStack;
-import appeng.fluids.util.FluidList;
 import appeng.util.Platform;
 import appeng.util.item.AEItemStack;
 import appeng.util.item.ItemList;
@@ -96,7 +100,8 @@ public class ApiStorage implements IStorageHelper {
         Preconditions.checkNotNull(data);
         Preconditions.checkNotNull(req);
 
-        return new CraftingLink(data, req);
+        // FIXME FABRIC return new CraftingLink(data, req);
+        throw new IllegalStateException();
     }
 
     @Override
@@ -182,7 +187,11 @@ public class ApiStorage implements IStorageHelper {
                 if (is.getItem() instanceof FluidDummyItem) {
                     return AEFluidStack.fromFluidStack(((FluidDummyItem) is.getItem()).getFluidStack(is));
                 } else {
-                    return AEFluidStack.fromFluidStack(FluidUtil.getFluidContained(is).orElse(null));
+                    FluidExtractable fluidExtractable = FluidAttributes.EXTRACTABLE.get(is);
+                    FluidVolume fluidVolume = fluidExtractable.attemptAnyExtraction(FluidAmount.MAX_VALUE, Simulation.ACTION);
+                    if (!fluidVolume.isEmpty()) {
+                        return AEFluidStack.fromFluidStack(fluidVolume);
+                    }
                 }
             }
 
diff --git a/core/src/main/java/appeng/core/api/definitions/ApiBlocks.java b/core/src/main/java/appeng/core/api/definitions/ApiBlocks.java
new file mode 100644
index 000000000..edbbf8aee
--- /dev/null
+++ b/core/src/main/java/appeng/core/api/definitions/ApiBlocks.java
@@ -0,0 +1,941 @@
+/*
+ * This file is part of Applied Energistics 2.
+ * Copyright (c) 2013 - 2015, AlgorithmX2, All rights reserved.
+ *
+ * Applied Energistics 2 is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Applied Energistics 2 is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Applied Energistics 2.  If not, see .
+ */
+
+package appeng.core.api.definitions;
+
+import appeng.api.definitions.IBlockDefinition;
+import appeng.api.definitions.IBlocks;
+import appeng.api.definitions.ITileDefinition;
+import appeng.api.features.AEFeature;
+import appeng.block.misc.*;
+import appeng.block.storage.SkyChestBlock;
+import appeng.bootstrap.*;
+import appeng.bootstrap.components.IInitComponent;
+import appeng.bootstrap.definitions.TileEntityDefinition;
+import appeng.client.render.tesr.SkyChestTESR;
+import appeng.decorative.AEDecorativeBlock;
+import appeng.decorative.solid.*;
+import appeng.decorative.solid.SkyStoneBlock.SkystoneType;
+import appeng.entity.TinyTNTPrimedEntity;
+import appeng.hooks.TinyTNTDispenseItemBehavior;
+import appeng.tile.misc.LightDetectorBlockEntity;
+import appeng.tile.misc.SkyCompassBlockEntity;
+import appeng.tile.storage.SkyChestBlockEntity;
+import net.fabricmc.api.EnvType;
+import net.fabricmc.api.Environment;
+import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings;
+import net.fabricmc.fabric.api.tool.attribute.v1.FabricToolTags;
+import net.minecraft.block.*;
+import net.minecraft.client.render.RenderLayer;
+import net.minecraft.entity.SpawnGroup;
+import net.minecraft.sound.BlockSoundGroup;
+
+import static appeng.block.AEBaseBlock.defaultProps;
+
+/**
+ * Internal implementation for the API blocks
+ */
+public final class ApiBlocks implements IBlocks {
+    private IBlockDefinition quartzOre;
+    private IBlockDefinition quartzOreCharged;
+    private IBlockDefinition matrixFrame;
+    private IBlockDefinition quartzBlock;
+    private IBlockDefinition quartzPillar;
+    private IBlockDefinition chiseledQuartzBlock;
+    private IBlockDefinition quartzGlass;
+    private IBlockDefinition quartzVibrantGlass;
+    private IBlockDefinition quartzFixture;
+    private IBlockDefinition fluixBlock;
+    private IBlockDefinition skyStoneBlock;
+    private IBlockDefinition smoothSkyStoneBlock;
+    private IBlockDefinition skyStoneBrick;
+    private IBlockDefinition skyStoneSmallBrick;
+    private IBlockDefinition skyStoneChest;
+    private IBlockDefinition smoothSkyStoneChest;
+    private IBlockDefinition skyCompass;
+    private ITileDefinition grindstone;
+    private ITileDefinition crank;
+    private ITileDefinition inscriber;
+    private ITileDefinition wirelessAccessPoint;
+    private ITileDefinition charger;
+    private IBlockDefinition tinyTNT;
+    private ITileDefinition securityStation;
+    private ITileDefinition quantumRing;
+    private ITileDefinition quantumLink;
+    private ITileDefinition spatialPylon;
+    private ITileDefinition spatialIOPort;
+    private ITileDefinition multiPart;
+    private ITileDefinition controller;
+    private ITileDefinition drive;
+    private ITileDefinition chest;
+    private ITileDefinition iface;
+    private ITileDefinition fluidIface;
+    private ITileDefinition cellWorkbench;
+    private ITileDefinition iOPort;
+    private ITileDefinition condenser;
+    private ITileDefinition energyAcceptor;
+    private ITileDefinition vibrationChamber;
+    private ITileDefinition quartzGrowthAccelerator;
+    private ITileDefinition energyCell;
+    private ITileDefinition energyCellDense;
+    private ITileDefinition energyCellCreative;
+    private ITileDefinition craftingUnit;
+    private ITileDefinition craftingAccelerator;
+    private ITileDefinition craftingStorage1k;
+    private ITileDefinition craftingStorage4k;
+    private ITileDefinition craftingStorage16k;
+    private ITileDefinition craftingStorage64k;
+    private ITileDefinition craftingMonitor;
+    private ITileDefinition molecularAssembler;
+    private ITileDefinition lightDetector;
+    private ITileDefinition paint;
+    private IBlockDefinition skyStoneStairs;
+    private IBlockDefinition smoothSkyStoneStairs;
+    private IBlockDefinition skyStoneBrickStairs;
+    private IBlockDefinition skyStoneSmallBrickStairs;
+    private IBlockDefinition fluixStairs;
+    private IBlockDefinition quartzStairs;
+    private IBlockDefinition chiseledQuartzStairs;
+    private IBlockDefinition quartzPillarStairs;
+
+    private IBlockDefinition skyStoneSlab;
+    private IBlockDefinition smoothSkyStoneSlab;
+    private IBlockDefinition skyStoneBrickSlab;
+    private IBlockDefinition skyStoneSmallBrickSlab;
+    private IBlockDefinition fluixSlab;
+    private IBlockDefinition quartzSlab;
+    private IBlockDefinition chiseledQuartzSlab;
+    private IBlockDefinition quartzPillarSlab;
+
+    private IBlockDefinition itemGen;
+    private IBlockDefinition chunkLoader;
+    private IBlockDefinition phantomNode;
+    private IBlockDefinition cubeGenerator;
+    private IBlockDefinition energyGenerator;
+
+    private static final FabricBlockSettings QUARTZ_PROPERTIES = defaultProps(Material.STONE).strength(3, 5);
+
+    private static final FabricBlockSettings SKYSTONE_PROPERTIES = defaultProps(Material.STONE).strength(50,
+            150);
+
+    private static FabricBlockSettings glassProps() {
+        return defaultProps(Material.GLASS)
+                .sounds(BlockSoundGroup.GLASS)
+                .nonOpaque()
+                .allowsSpawning((state, world, pos, type) -> false)
+                .solidBlock((state, world, pos) -> false)
+                .suffocates((state, world, pos) -> false)
+                .blockVision((state, world, pos) -> false);
+    }
+
+    public ApiBlocks(FeatureFactory registry) {
+        this.quartzOre = registry.block("quartz_ore", () -> new QuartzOreBlock(QUARTZ_PROPERTIES))
+                .features(AEFeature.CERTUS_ORE).build();
+        this.quartzOreCharged = registry.block("charged_quartz_ore", () -> new ChargedQuartzOreBlock(QUARTZ_PROPERTIES))
+                .features(AEFeature.CERTUS_ORE, AEFeature.CHARGED_CERTUS_ORE).rendering(new BlockRenderingCustomizer() {
+                    @Override
+                    @Environment(EnvType.CLIENT)
+                    public void customize(IBlockRendering rendering, IItemRendering itemRendering) {
+                        rendering.renderType(RenderLayer.getCutout());
+                    }
+                }).build();
+// FIXME FABRIC        this.matrixFrame = registry.block("matrix_frame", MatrixFrameBlock::new).features(AEFeature.SPATIAL_IO).build();
+
+        FeatureFactory deco = registry.features(AEFeature.DECORATIVE_BLOCKS);
+        this.quartzBlock = deco.block("quartz_block", () -> new AEDecorativeBlock(QUARTZ_PROPERTIES)).build();
+        this.quartzPillar = deco.block("quartz_pillar", () -> new QuartzPillarBlock(QUARTZ_PROPERTIES)).build();
+        this.chiseledQuartzBlock = deco.block("chiseled_quartz_block", () -> new AEDecorativeBlock(QUARTZ_PROPERTIES))
+                .build();
+
+        this.quartzGlass = registry.features(AEFeature.QUARTZ_GLASS)
+                .block("quartz_glass", () -> new QuartzGlassBlock(glassProps()))
+                .rendering(new BlockRenderingCustomizer() {
+                    @Override
+                    @Environment(EnvType.CLIENT)
+                    public void customize(IBlockRendering rendering, IItemRendering itemRendering) {
+                        rendering.renderType(RenderLayer.getCutout());
+                    }
+                }).build();
+        this.quartzVibrantGlass = deco
+                .block("quartz_vibrant_glass",
+                        () -> new QuartzLampBlock(glassProps().lightLevel(15)))
+                .addFeatures(AEFeature.DECORATIVE_LIGHTS, AEFeature.QUARTZ_GLASS)
+                .rendering(new BlockRenderingCustomizer() {
+                    @Override
+                    @Environment(EnvType.CLIENT)
+                    public void customize(IBlockRendering rendering, IItemRendering itemRendering) {
+                        rendering.renderType(RenderLayer.getCutout());
+                    }
+                }).build();
+
+        this.quartzFixture = registry.block("quartz_fixture", QuartzFixtureBlock::new)
+                .features(AEFeature.DECORATIVE_LIGHTS).rendering(new BlockRenderingCustomizer() {
+                    @Override
+                    @Environment(EnvType.CLIENT)
+                    public void customize(IBlockRendering rendering, IItemRendering itemRendering) {
+                        rendering.renderType(RenderLayer.getCutout());
+                    }
+                }).build();
+
+        this.fluixBlock = registry.features(AEFeature.FLUIX)
+                .block("fluix_block", () -> new AEDecorativeBlock(QUARTZ_PROPERTIES)).build();
+
+        this.skyStoneBlock = registry
+                .features(
+                        AEFeature.SKY_STONE)
+                .block("sky_stone_block", () -> new SkyStoneBlock(SkystoneType.STONE,
+                        defaultProps(Material.STONE).strength(50, 150).breakByTool(FabricToolTags.PICKAXES, 3)))
+                .build();
+
+        this.smoothSkyStoneBlock = registry.features(AEFeature.SKY_STONE)
+                .block("smooth_sky_stone_block", () -> new SkyStoneBlock(SkystoneType.BLOCK, SKYSTONE_PROPERTIES))
+                .build();
+        this.skyStoneBrick = deco
+                .block("sky_stone_brick", () -> new SkyStoneBlock(SkystoneType.BRICK, SKYSTONE_PROPERTIES))
+                .addFeatures(AEFeature.SKY_STONE).build();
+        this.skyStoneSmallBrick = deco
+                .block("sky_stone_small_brick", () -> new SkyStoneBlock(SkystoneType.SMALL_BRICK, SKYSTONE_PROPERTIES))
+                .addFeatures(AEFeature.SKY_STONE).build();
+
+        AbstractBlock.Settings skyStoneChestProps = defaultProps(Material.STONE)
+                .strength(50, 150)
+                .solidBlock((state, world, pos) -> false);
+
+        TileEntityDefinition skyChestTile = registry
+                .tileEntity("sky_chest", SkyChestBlockEntity.class, SkyChestBlockEntity::new)
+                .rendering(new TileEntityRenderingCustomizer() {
+                    @Override
+                    @Environment(EnvType.CLIENT)
+                    public void customize(TileEntityRendering rendering) {
+                        rendering.tileEntityRenderer(SkyChestTESR::new);
+                    }
+                }).build();
+        this.skyStoneChest = registry
+                .block("sky_stone_chest", () -> new SkyChestBlock(SkyChestBlock.SkyChestType.STONE, skyStoneChestProps))
+                .features(AEFeature.SKY_STONE, AEFeature.SKY_STONE_CHESTS).tileEntity(skyChestTile).build();
+        this.smoothSkyStoneChest = registry
+                .block("smooth_sky_stone_chest",
+                        () -> new SkyChestBlock(SkyChestBlock.SkyChestType.BLOCK, skyStoneChestProps))
+                .features(AEFeature.SKY_STONE, AEFeature.SKY_STONE_CHESTS).tileEntity(skyChestTile).build();
+
+        this.skyCompass = registry.block("sky_compass", () -> new SkyCompassBlock(defaultProps(Material.SUPPORTED)))
+                .features(AEFeature.METEORITE_COMPASS)
+                .tileEntity(registry.tileEntity("sky_compass", SkyCompassBlockEntity.class, SkyCompassBlockEntity::new)
+                        .rendering(new SkyCompassRendering()).build())
+                .build();
+// FIXME FABRIC        this.grindstone = registry
+// FIXME FABRIC                .block("grindstone", () -> new GrinderBlock(defaultProps(Material.STONE).strength(3.2f)))
+// FIXME FABRIC                .features(AEFeature.GRIND_STONE)
+// FIXME FABRIC                .tileEntity(registry.tileEntity("grindstone", GrinderBlockEntity.class, GrinderBlockEntity::new).build())
+// FIXME FABRIC                .build();
+// FIXME FABRIC        this.crank = registry
+// FIXME FABRIC                .block("crank",
+// FIXME FABRIC                        () -> new CrankBlock(
+// FIXME FABRIC                                defaultProps(Material.WOOD).breakByTool(FabricToolTags.AXES, 0).notSolid()))
+// FIXME FABRIC                .features(AEFeature.GRIND_STONE)
+// FIXME FABRIC                .tileEntity(registry.tileEntity("crank", CrankBlockEntity.class, CrankBlockEntity::new)
+// FIXME FABRIC                        .rendering(new TileEntityRenderingCustomizer() {
+// FIXME FABRIC                            @Override
+// FIXME FABRIC                            @Environment(EnvType.CLIENT)
+// FIXME FABRIC                            public void customize(TileEntityRendering rendering) {
+// FIXME FABRIC                                rendering.tileEntityRenderer(CrankTESR::new);
+// FIXME FABRIC                            }
+// FIXME FABRIC                        }).build())
+// FIXME FABRIC                .build();
+// FIXME FABRIC        this.inscriber = registry.block("inscriber", () -> new InscriberBlock(defaultProps(Material.METAL).notSolid()))
+// FIXME FABRIC                .features(AEFeature.INSCRIBER)
+// FIXME FABRIC                .tileEntity(registry.tileEntity("inscriber", InscriberBlockEntity.class, InscriberBlockEntity::new)
+// FIXME FABRIC                        .rendering(new InscriberRendering()).build())
+// FIXME FABRIC                .build();
+// FIXME FABRIC        this.wirelessAccessPoint = registry.block("wireless_access_point", WirelessBlock::new)
+// FIXME FABRIC                .features(AEFeature.WIRELESS_ACCESS_TERMINAL)
+// FIXME FABRIC                .tileEntity(registry
+// FIXME FABRIC                        .tileEntity("wireless_access_point", WirelessBlockEntity.class, WirelessBlockEntity::new).build())
+// FIXME FABRIC                .rendering(new WirelessRendering()).build();
+// FIXME FABRIC        this.charger = registry.block("charger", ChargerBlock::new).features(AEFeature.CHARGER)
+// FIXME FABRIC                .tileEntity(registry.tileEntity("charger", ChargerBlockEntity.class, ChargerBlockEntity::new)
+// FIXME FABRIC                        .rendering(new TileEntityRenderingCustomizer() {
+// FIXME FABRIC                            @Override
+// FIXME FABRIC                            @Environment(EnvType.CLIENT)
+// FIXME FABRIC                            public void customize(TileEntityRendering rendering) {
+// FIXME FABRIC                                rendering.tileEntityRenderer(ChargerBlock.createTesr());
+// FIXME FABRIC                            }
+// FIXME FABRIC                        }).build())
+// FIXME FABRIC                .build();
+
+        TinyTNTPrimedEntity.TYPE = registry
+                .entity("tiny_tnt_primed", TinyTNTPrimedEntity::new, SpawnGroup.MISC)
+                .customize(p -> p.trackable(16, 4, true))
+                .build();
+
+        this.tinyTNT = registry
+                .block("tiny_tnt",
+                        () -> new TinyTNTBlock(
+                                defaultProps(Material.TNT).sounds(BlockSoundGroup.GRASS).breakInstantly()))
+                .features(AEFeature.TINY_TNT).bootstrap((block, item) -> (IInitComponent) () -> DispenserBlock
+                        .registerBehavior(item, new TinyTNTDispenseItemBehavior()))
+                .build();
+// FIXME       this.securityStation = registry.block("security_station", SecurityStationBlock::new)
+// FIXME               .features(AEFeature.SECURITY)
+// FIXME               .tileEntity(registry
+// FIXME                       .tileEntity("security_station", SecurityStationBlockEntity.class, SecurityStationBlockEntity::new)
+// FIXME                       .build())
+// FIXME               .rendering(new SecurityStationRendering()).build();
+// FIXME
+// FIXME       TileEntityDefinition quantumRingTile = registry
+// FIXME               .tileEntity("quantum_ring", QuantumBridgeBlockEntity.class, QuantumBridgeBlockEntity::new).build();
+// FIXME       this.quantumRing = registry.block("quantum_ring", QuantumRingBlock::new)
+// FIXME               .features(AEFeature.QUANTUM_NETWORK_BRIDGE).tileEntity(quantumRingTile)
+// FIXME               .rendering(new QuantumBridgeRendering()).build();
+// FIXME       this.quantumLink = registry.block("quantum_link", QuantumLinkChamberBlock::new)
+// FIXME               .features(AEFeature.QUANTUM_NETWORK_BRIDGE).tileEntity(quantumRingTile)
+// FIXME               .rendering(new QuantumBridgeRendering()).build();
+// FIXME       this.spatialPylon = registry.block("spatial_pylon", SpatialPylonBlock::new).features(AEFeature.SPATIAL_IO)
+// FIXME               .tileEntity(registry
+// FIXME                       .tileEntity("spatial_pylon", SpatialPylonBlockEntity.class, SpatialPylonBlockEntity::new).build())
+// FIXME               .rendering(new SpatialPylonRendering()).build();
+// FIXME       this.spatialIOPort = registry.block("spatial_io_port", SpatialIOPortBlock::new).features(AEFeature.SPATIAL_IO)
+// FIXME               .tileEntity(registry
+// FIXME                       .tileEntity("spatial_io_port", SpatialIOPortBlockEntity.class, SpatialIOPortBlockEntity::new)
+// FIXME                       .build())
+// FIXME               .build();
+// FIXME       this.controller = registry
+// FIXME               .block("controller", ControllerBlock::new).features(AEFeature.CHANNELS).tileEntity(registry
+// FIXME                       .tileEntity("controller", ControllerBlockEntity.class, ControllerBlockEntity::new).build())
+// FIXME               .rendering(new ControllerRendering()).build();
+// FIXME       this.drive = registry.block("drive", DriveBlock::new).features(AEFeature.STORAGE_CELLS, AEFeature.ME_DRIVE)
+// FIXME               .tileEntity(registry.tileEntity("drive", DriveBlockEntity.class, DriveBlockEntity::new)
+// FIXME                       .rendering(new TileEntityRenderingCustomizer() {
+// FIXME                           @Override
+// FIXME                           @Environment(EnvType.CLIENT)
+// FIXME                           public void customize(TileEntityRendering rendering) {
+// FIXME                               rendering.tileEntityRenderer(DriveLedTileEntityRenderer::new);
+// FIXME                           }
+// FIXME                       }).build())
+// FIXME               .rendering(new DriveRendering()).build();
+// FIXME       this.chest = registry.block("chest", ChestBlock::new).features(AEFeature.STORAGE_CELLS, AEFeature.ME_CHEST)
+// FIXME               .tileEntity(registry.tileEntity("chest", ChestBlockEntity.class, ChestBlockEntity::new).build())
+// FIXME               .rendering(new ChestRendering()).build();
+// FIXME       this.iface = registry.block("interface", InterfaceBlock::new).features(AEFeature.INTERFACE)
+// FIXME               .tileEntity(
+// FIXME                       registry.tileEntity("interface", InterfaceBlockEntity.class, InterfaceBlockEntity::new).build())
+// FIXME               .build();
+// FIXME       this.fluidIface = registry.block("fluid_interface", FluidInterfaceBlock::new)
+// FIXME               .features(AEFeature.FLUID_INTERFACE)
+// FIXME               .tileEntity(registry
+// FIXME                       .tileEntity("fluid_interface", FluidInterfaceBlockEntity.class, FluidInterfaceBlockEntity::new)
+// FIXME                       .build())
+// FIXME               .build();
+// FIXME       this.cellWorkbench = registry.block("cell_workbench", CellWorkbenchBlock::new).features(AEFeature.STORAGE_CELLS)
+// FIXME               .tileEntity(registry
+// FIXME                       .tileEntity("cell_workbench", CellWorkbenchBlockEntity.class, CellWorkbenchBlockEntity::new)
+// FIXME                       .build())
+// FIXME               .build();
+// FIXME       this.iOPort = registry.block("io_port", IOPortBlock::new).features(AEFeature.STORAGE_CELLS, AEFeature.IO_PORT)
+// FIXME               .tileEntity(registry.tileEntity("io_port", IOPortBlockEntity.class, IOPortBlockEntity::new).build())
+// FIXME               .build();
+// FIXME       this.condenser = registry.block("condenser", CondenserBlock::new).features(AEFeature.CONDENSER)
+// FIXME               .tileEntity(
+// FIXME                       registry.tileEntity("condenser", CondenserBlockEntity.class, CondenserBlockEntity::new).build())
+// FIXME               .build();
+// FIXME       this.energyAcceptor = registry.block("energy_acceptor", EnergyAcceptorBlock::new)
+// FIXME               .features(AEFeature.ENERGY_ACCEPTOR)
+// FIXME               .tileEntity(registry
+// FIXME                       .tileEntity("energy_acceptor", EnergyAcceptorBlockEntity.class, EnergyAcceptorBlockEntity::new)
+// FIXME                       .build())
+// FIXME               .build();
+// FIXME       this.vibrationChamber = registry.block("vibration_chamber", VibrationChamberBlock::new)
+// FIXME               .features(AEFeature.POWER_GEN).tileEntity(registry.tileEntity("vibration_chamber",
+// FIXME                       VibrationChamberBlockEntity.class, VibrationChamberBlockEntity::new).build())
+// FIXME               .build();
+// FIXME       this.quartzGrowthAccelerator = registry.block("quartz_growth_accelerator", QuartzGrowthAcceleratorBlock::new)
+// FIXME               .tileEntity(registry.tileEntity("quartz_growth_accelerator", QuartzGrowthAcceleratorBlockEntity.class,
+// FIXME                       QuartzGrowthAcceleratorBlockEntity::new).build())
+// FIXME               .features(AEFeature.CRYSTAL_GROWTH_ACCELERATOR).build();
+// FIXME       this.energyCell = registry.block("energy_cell", EnergyCellBlock::new).features(AEFeature.ENERGY_CELLS)
+// FIXME               .item(AEBaseBlockItemChargeable::new).tileEntity(registry
+// FIXME                       .tileEntity("energy_cell", EnergyCellBlockEntity.class, EnergyCellBlockEntity::new).build())
+// FIXME               .build();
+// FIXME       this.energyCellDense = registry.block("dense_energy_cell", DenseEnergyCellBlock::new)
+// FIXME               .features(AEFeature.ENERGY_CELLS, AEFeature.DENSE_ENERGY_CELLS).item(AEBaseBlockItemChargeable::new)
+// FIXME               .tileEntity(registry.tileEntity("dense_energy_cell", DenseEnergyCellBlockEntity.class,
+// FIXME                       DenseEnergyCellBlockEntity::new).build())
+// FIXME               .build();
+// FIXME       this.energyCellCreative = registry.block("creative_energy_cell", CreativeEnergyCellBlock::new)
+// FIXME               .features(AEFeature.CREATIVE).tileEntity(registry.tileEntity("creative_energy_cell",
+// FIXME                       CreativeEnergyCellBlockEntity.class, CreativeEnergyCellBlockEntity::new).build())
+// FIXME               .build();
+// FIXME
+// FIXME       TileEntityDefinition craftingUnit = registry
+// FIXME               .tileEntity("crafting_unit", CraftingBlockEntity.class, CraftingBlockEntity::new).build();
+// FIXME
+// FIXME       FeatureFactory crafting = registry.features(AEFeature.CRAFTING_CPU);
+// FIXME       AbstractBlock.Settings craftingBlockProps = defaultProps(Material.METAL);
+// FIXME       this.craftingUnit = crafting
+// FIXME               .block("crafting_unit", () -> new CraftingUnitBlock(craftingBlockProps, CraftingUnitType.UNIT))
+// FIXME               .rendering(new CraftingCubeRendering()).tileEntity(craftingUnit).build();
+// FIXME       this.craftingAccelerator = crafting
+// FIXME               .block("crafting_accelerator",
+// FIXME                       () -> new CraftingUnitBlock(craftingBlockProps, CraftingUnitType.ACCELERATOR))
+// FIXME               .rendering(new CraftingCubeRendering()).tileEntity(craftingUnit).build();
+// FIXME
+// FIXME       TileEntityDefinition craftingStorage = registry
+// FIXME               .tileEntity("crafting_storage", CraftingStorageBlockEntity.class, CraftingStorageBlockEntity::new)
+// FIXME               .build();
+// FIXME       this.craftingStorage1k = crafting
+// FIXME               .block("1k_crafting_storage",
+// FIXME                       () -> new CraftingStorageBlock(craftingBlockProps, CraftingUnitType.STORAGE_1K))
+// FIXME               .item(CraftingStorageItem::new).tileEntity(craftingStorage).rendering(new CraftingCubeRendering())
+// FIXME               .build();
+// FIXME       this.craftingStorage4k = crafting
+// FIXME               .block("4k_crafting_storage",
+// FIXME                       () -> new CraftingStorageBlock(craftingBlockProps, CraftingUnitType.STORAGE_4K))
+// FIXME               .item(CraftingStorageItem::new).tileEntity(craftingStorage).rendering(new CraftingCubeRendering())
+// FIXME               .build();
+// FIXME       this.craftingStorage16k = crafting
+// FIXME               .block("16k_crafting_storage",
+// FIXME                       () -> new CraftingStorageBlock(craftingBlockProps, CraftingUnitType.STORAGE_16K))
+// FIXME               .item(CraftingStorageItem::new).tileEntity(craftingStorage).rendering(new CraftingCubeRendering())
+// FIXME               .build();
+// FIXME       this.craftingStorage64k = crafting
+// FIXME               .block("64k_crafting_storage",
+// FIXME                       () -> new CraftingStorageBlock(craftingBlockProps, CraftingUnitType.STORAGE_64K))
+// FIXME               .item(CraftingStorageItem::new).tileEntity(craftingStorage).rendering(new CraftingCubeRendering())
+// FIXME               .build();
+// FIXME       this.craftingMonitor = crafting.block("crafting_monitor", () -> new CraftingMonitorBlock(craftingBlockProps))
+// FIXME               .tileEntity(registry
+// FIXME                       .tileEntity("crafting_monitor", CraftingMonitorBlockEntity.class, CraftingMonitorBlockEntity::new)
+// FIXME                       .rendering(new TileEntityRenderingCustomizer() {
+// FIXME                           @Environment(EnvType.CLIENT)
+// FIXME                           @Override
+// FIXME                           public void customize(TileEntityRendering rendering) {
+// FIXME                               rendering.tileEntityRenderer(CraftingMonitorTESR::new);
+// FIXME                           }
+// FIXME                       }).build())
+// FIXME               .rendering(new BlockRenderingCustomizer() {
+// FIXME                   @Override
+// FIXME                   @Environment(EnvType.CLIENT)
+// FIXME                   public void customize(IBlockRendering rendering, IItemRendering itemRendering) {
+// FIXME                       rendering.renderType(RenderLayer.getCutout());
+// FIXME                       rendering.modelCustomizer((path, model) -> {
+// FIXME                           // The formed model handles rotations itself, the unformed one does not
+// FIXME                           if (model instanceof MonitorBakedModel) {
+// FIXME                               return model;
+// FIXME                           }
+// FIXME                           return new AutoRotatingBakedModel(model);
+// FIXME                       });
+// FIXME                   }
+// FIXME               }).build();
+// FIXME
+// FIXME       this.molecularAssembler = registry
+// FIXME               .block("molecular_assembler", () -> new MolecularAssemblerBlock(defaultProps(Material.METAL).notSolid()))
+// FIXME               .features(AEFeature.MOLECULAR_ASSEMBLER).rendering(new BlockRenderingCustomizer() {
+// FIXME                   @Environment(EnvType.CLIENT)
+// FIXME                   @Override
+// FIXME                   public void customize(IBlockRendering rendering, IItemRendering itemRendering) {
+// FIXME                       rendering.renderType(RenderLayer.getCutout());
+// FIXME                   }
+// FIXME               })
+// FIXME               .tileEntity(registry
+// FIXME                       .tileEntity("molecular_assembler", MolecularAssemblerBlockEntity.class,
+// FIXME                               MolecularAssemblerBlockEntity::new)
+// FIXME                       .rendering(new TileEntityRenderingCustomizer() {
+// FIXME                           @Override
+// FIXME                           @Environment(EnvType.CLIENT)
+// FIXME                           public void customize(TileEntityRendering rendering) {
+// FIXME                               rendering.tileEntityRenderer(MolecularAssemblerRenderer::new);
+// FIXME                           }
+// FIXME                       }).build())
+// FIXME               .build();
+
+        this.lightDetector = registry.block("light_detector", LightDetectorBlock::new)
+                .features(AEFeature.LIGHT_DETECTOR)
+                .tileEntity(registry
+                        .tileEntity("light_detector", LightDetectorBlockEntity.class, LightDetectorBlockEntity::new)
+                        .build())
+                .rendering(new BlockRenderingCustomizer() {
+                    @Override
+                    @Environment(EnvType.CLIENT)
+                    public void customize(IBlockRendering rendering, IItemRendering itemRendering) {
+                        rendering.renderType(RenderLayer.getCutout());
+                    }
+                }).build();
+// FIXME        this.paint = registry
+// FIXME                .block("paint", PaintSplotchesBlock::new).features(AEFeature.PAINT_BALLS).tileEntity(registry
+// FIXME                        .tileEntity("paint", PaintSplotchesBlockEntity.class, PaintSplotchesBlockEntity::new).build())
+// FIXME                .rendering(new PaintSplotchesRendering()).build();
+
+        this.skyStoneStairs = deco
+                .block("sky_stone_stairs",
+                        () -> new AEStairsBlock(this.skyStoneBlock().block().getDefaultState(), SKYSTONE_PROPERTIES))
+                .addFeatures(AEFeature.SKY_STONE).build();
+        this.smoothSkyStoneStairs = deco
+                .block("smooth_sky_stone_stairs",
+                        () -> new AEStairsBlock(this.smoothSkyStoneBlock().block().getDefaultState(), SKYSTONE_PROPERTIES))
+                .addFeatures(AEFeature.SKY_STONE).build();
+        this.skyStoneBrickStairs = deco
+                .block("sky_stone_brick_stairs",
+                        () -> new AEStairsBlock(this.skyStoneBrick().block().getDefaultState(), SKYSTONE_PROPERTIES))
+                .addFeatures(AEFeature.SKY_STONE).build();
+        this.skyStoneSmallBrickStairs = deco
+                .block("sky_stone_small_brick_stairs",
+                        () -> new AEStairsBlock(this.skyStoneSmallBrick().block().getDefaultState(), SKYSTONE_PROPERTIES))
+                .addFeatures(AEFeature.SKY_STONE).build();
+
+        this.fluixStairs = deco
+                .block("fluix_stairs",
+                        () -> new AEStairsBlock(this.fluixBlock().block().getDefaultState(), QUARTZ_PROPERTIES))
+                .addFeatures(AEFeature.FLUIX).build();
+        this.quartzStairs = deco
+                .block("quartz_stairs",
+                        () -> new AEStairsBlock(this.quartzBlock().block().getDefaultState(), QUARTZ_PROPERTIES))
+                .addFeatures(AEFeature.CERTUS).build();
+        this.chiseledQuartzStairs = deco
+                .block("chiseled_quartz_stairs",
+                        () -> new AEStairsBlock(this.chiseledQuartzBlock().block().getDefaultState(), QUARTZ_PROPERTIES))
+                .addFeatures(AEFeature.CERTUS).build();
+        this.quartzPillarStairs = deco
+                .block("quartz_pillar_stairs",
+                        () -> new AEStairsBlock(this.quartzPillar().block().getDefaultState(), QUARTZ_PROPERTIES))
+                .addFeatures(AEFeature.CERTUS).build();
+
+// FIXME        this.multiPart = registry.block("cable_bus", CableBusBlock::new).rendering(new CableBusRendering())
+// FIXME                .tileEntity(registry.tileEntity("cable_bus", CableBusBlockEntity.class, CableBusBlockEntity::new)
+// FIXME                        .rendering(new TileEntityRenderingCustomizer() {
+// FIXME                            @Override
+// FIXME                            @Environment(EnvType.CLIENT)
+// FIXME                            public void customize(TileEntityRendering rendering) {
+// FIXME                                rendering.tileEntityRenderer(CableBusTESR::new);
+// FIXME                            }
+// FIXME                        }).build())
+// FIXME                .build();
+
+        this.skyStoneSlab = deco.block("sky_stone_slab", () -> new SlabBlock(SKYSTONE_PROPERTIES))
+                .addFeatures(AEFeature.SKY_STONE).build();
+        this.smoothSkyStoneSlab = deco.block("smooth_sky_stone_slab", () -> new SlabBlock(SKYSTONE_PROPERTIES))
+                .addFeatures(AEFeature.SKY_STONE).build();
+        this.skyStoneBrickSlab = deco.block("sky_stone_brick_slab", () -> new SlabBlock(SKYSTONE_PROPERTIES))
+                .addFeatures(AEFeature.SKY_STONE).build();
+        this.skyStoneSmallBrickSlab = deco.block("sky_stone_small_brick_slab", () -> new SlabBlock(SKYSTONE_PROPERTIES))
+                .addFeatures(AEFeature.SKY_STONE).build();
+
+        this.fluixSlab = deco.block("fluix_slab", () -> new SlabBlock(QUARTZ_PROPERTIES)).addFeatures(AEFeature.FLUIX)
+                .build();
+        this.quartzSlab = deco.block("quartz_slab", () -> new SlabBlock(QUARTZ_PROPERTIES))
+                .addFeatures(AEFeature.CERTUS).build();
+        this.chiseledQuartzSlab = deco.block("chiseled_quartz_slab", () -> new SlabBlock(QUARTZ_PROPERTIES))
+                .addFeatures(AEFeature.CERTUS).build();
+        this.quartzPillarSlab = deco.block("quartz_pillar_slab", () -> new SlabBlock(QUARTZ_PROPERTIES))
+                .addFeatures(AEFeature.CERTUS).build();
+
+// FIXME        this.itemGen = registry.block("debug_item_gen", ItemGenBlock::new)
+// FIXME                .features(AEFeature.UNSUPPORTED_DEVELOPER_TOOLS, AEFeature.CREATIVE)
+// FIXME                .tileEntity(
+// FIXME                        registry.tileEntity("debug_item_gen", ItemGenBlockEntity.class, ItemGenBlockEntity::new).build())
+// FIXME                .build();
+// FIXME        this.chunkLoader = registry.block("debug_chunk_loader", ChunkLoaderBlock::new)
+// FIXME                .features(AEFeature.UNSUPPORTED_DEVELOPER_TOOLS, AEFeature.CREATIVE)
+// FIXME                .tileEntity(registry
+// FIXME                        .tileEntity("debug_chunk_loader", ChunkLoaderBlockEntity.class, ChunkLoaderBlockEntity::new)
+// FIXME                        .build())
+// FIXME                .build();
+// FIXME        this.phantomNode = registry.block("debug_phantom_node", PhantomNodeBlock::new)
+// FIXME                .features(AEFeature.UNSUPPORTED_DEVELOPER_TOOLS, AEFeature.CREATIVE)
+// FIXME                .tileEntity(registry
+// FIXME                        .tileEntity("debug_phantom_node", PhantomNodeBlockEntity.class, PhantomNodeBlockEntity::new)
+// FIXME                        .build())
+// FIXME                .build();
+// FIXME        this.cubeGenerator = registry.block("debug_cube_gen", CubeGeneratorBlock::new)
+// FIXME                .features(AEFeature.UNSUPPORTED_DEVELOPER_TOOLS, AEFeature.CREATIVE)
+// FIXME                .tileEntity(registry
+// FIXME                        .tileEntity("debug_cube_gen", CubeGeneratorBlockEntity.class, CubeGeneratorBlockEntity::new)
+// FIXME                        .build())
+// FIXME                .build();
+// FIXME        this.energyGenerator = registry.block("debug_energy_gen", EnergyGeneratorBlock::new)
+// FIXME                .features(AEFeature.UNSUPPORTED_DEVELOPER_TOOLS, AEFeature.CREATIVE)
+// FIXME                .tileEntity(registry
+// FIXME                        .tileEntity("debug_energy_gen", EnergyGeneratorBlockEntity.class, EnergyGeneratorBlockEntity::new)
+// FIXME                        .build())
+// FIXME                .build();
+    }
+
+    @Override
+    public IBlockDefinition quartzOre() {
+        return this.quartzOre;
+    }
+
+    @Override
+    public IBlockDefinition quartzOreCharged() {
+        return this.quartzOreCharged;
+    }
+
+    @Override
+    public IBlockDefinition matrixFrame() {
+        return this.matrixFrame;
+    }
+
+    @Override
+    public IBlockDefinition quartzBlock() {
+        return this.quartzBlock;
+    }
+
+    @Override
+    public IBlockDefinition quartzPillar() {
+        return this.quartzPillar;
+    }
+
+    @Override
+    public IBlockDefinition chiseledQuartzBlock() {
+        return this.chiseledQuartzBlock;
+    }
+
+    @Override
+    public IBlockDefinition quartzGlass() {
+        return this.quartzGlass;
+    }
+
+    @Override
+    public IBlockDefinition quartzVibrantGlass() {
+        return this.quartzVibrantGlass;
+    }
+
+    @Override
+    public IBlockDefinition quartzFixture() {
+        return this.quartzFixture;
+    }
+
+    @Override
+    public IBlockDefinition fluixBlock() {
+        return this.fluixBlock;
+    }
+
+    @Override
+    public IBlockDefinition skyStoneBlock() {
+        return this.skyStoneBlock;
+    }
+
+    @Override
+    public IBlockDefinition smoothSkyStoneBlock() {
+        return this.smoothSkyStoneBlock;
+    }
+
+    @Override
+    public IBlockDefinition skyStoneBrick() {
+        return this.skyStoneBrick;
+    }
+
+    @Override
+    public IBlockDefinition skyStoneSmallBrick() {
+        return this.skyStoneSmallBrick;
+    }
+
+    @Override
+    public IBlockDefinition skyStoneChest() {
+        return this.skyStoneChest;
+    }
+
+    @Override
+    public IBlockDefinition smoothSkyStoneChest() {
+        return this.smoothSkyStoneChest;
+    }
+
+    @Override
+    public IBlockDefinition skyCompass() {
+        return this.skyCompass;
+    }
+
+    @Override
+    public IBlockDefinition skyStoneStairs() {
+        return this.skyStoneStairs;
+    }
+
+    @Override
+    public IBlockDefinition smoothSkyStoneStairs() {
+        return this.smoothSkyStoneStairs;
+    }
+
+    @Override
+    public IBlockDefinition skyStoneBrickStairs() {
+        return this.skyStoneBrickStairs;
+    }
+
+    @Override
+    public IBlockDefinition skyStoneSmallBrickStairs() {
+        return this.skyStoneSmallBrickStairs;
+    }
+
+    @Override
+    public IBlockDefinition fluixStairs() {
+        return this.fluixStairs;
+    }
+
+    @Override
+    public IBlockDefinition quartzStairs() {
+        return this.quartzStairs;
+    }
+
+    @Override
+    public IBlockDefinition chiseledQuartzStairs() {
+        return this.chiseledQuartzStairs;
+    }
+
+    @Override
+    public IBlockDefinition quartzPillarStairs() {
+        return this.quartzPillarStairs;
+    }
+
+    @Override
+    public IBlockDefinition skyStoneSlab() {
+        return this.skyStoneSlab;
+    }
+
+    @Override
+    public IBlockDefinition smoothSkyStoneSlab() {
+        return this.smoothSkyStoneSlab;
+    }
+
+    @Override
+    public IBlockDefinition skyStoneBrickSlab() {
+        return this.skyStoneBrickSlab;
+    }
+
+    @Override
+    public IBlockDefinition skyStoneSmallBrickSlab() {
+        return this.skyStoneSmallBrickSlab;
+    }
+
+    @Override
+    public IBlockDefinition fluixSlab() {
+        return this.fluixSlab;
+    }
+
+    @Override
+    public IBlockDefinition quartzSlab() {
+        return this.quartzSlab;
+    }
+
+    @Override
+    public IBlockDefinition chiseledQuartzSlab() {
+        return this.chiseledQuartzSlab;
+    }
+
+    @Override
+    public IBlockDefinition quartzPillarSlab() {
+        return this.quartzPillarSlab;
+    }
+
+    @Override
+    public ITileDefinition grindstone() {
+        return this.grindstone;
+    }
+
+    @Override
+    public ITileDefinition crank() {
+        return this.crank;
+    }
+
+    @Override
+    public ITileDefinition inscriber() {
+        return this.inscriber;
+    }
+
+    @Override
+    public ITileDefinition wirelessAccessPoint() {
+        return this.wirelessAccessPoint;
+    }
+
+    @Override
+    public ITileDefinition charger() {
+        return this.charger;
+    }
+
+    @Override
+    public IBlockDefinition tinyTNT() {
+        return this.tinyTNT;
+    }
+
+    @Override
+    public ITileDefinition securityStation() {
+        return this.securityStation;
+    }
+
+    @Override
+    public ITileDefinition quantumRing() {
+        return this.quantumRing;
+    }
+
+    @Override
+    public ITileDefinition quantumLink() {
+        return this.quantumLink;
+    }
+
+    @Override
+    public ITileDefinition spatialPylon() {
+        return this.spatialPylon;
+    }
+
+    @Override
+    public ITileDefinition spatialIOPort() {
+        return this.spatialIOPort;
+    }
+
+    @Override
+    public ITileDefinition multiPart() {
+        return this.multiPart;
+    }
+
+    @Override
+    public ITileDefinition controller() {
+        return this.controller;
+    }
+
+    @Override
+    public ITileDefinition drive() {
+        return this.drive;
+    }
+
+    @Override
+    public ITileDefinition chest() {
+        return this.chest;
+    }
+
+    @Override
+    public ITileDefinition iface() {
+        return this.iface;
+    }
+
+    @Override
+    public ITileDefinition fluidIface() {
+        return this.fluidIface;
+    }
+
+    @Override
+    public ITileDefinition cellWorkbench() {
+        return this.cellWorkbench;
+    }
+
+    @Override
+    public ITileDefinition iOPort() {
+        return this.iOPort;
+    }
+
+    @Override
+    public ITileDefinition condenser() {
+        return this.condenser;
+    }
+
+    @Override
+    public ITileDefinition energyAcceptor() {
+        return this.energyAcceptor;
+    }
+
+    @Override
+    public ITileDefinition vibrationChamber() {
+        return this.vibrationChamber;
+    }
+
+    @Override
+    public ITileDefinition quartzGrowthAccelerator() {
+        return this.quartzGrowthAccelerator;
+    }
+
+    @Override
+    public ITileDefinition energyCell() {
+        return this.energyCell;
+    }
+
+    @Override
+    public ITileDefinition energyCellDense() {
+        return this.energyCellDense;
+    }
+
+    @Override
+    public ITileDefinition energyCellCreative() {
+        return this.energyCellCreative;
+    }
+
+    @Override
+    public ITileDefinition craftingUnit() {
+        return this.craftingUnit;
+    }
+
+    @Override
+    public ITileDefinition craftingAccelerator() {
+        return this.craftingAccelerator;
+    }
+
+    @Override
+    public ITileDefinition craftingStorage1k() {
+        return this.craftingStorage1k;
+    }
+
+    @Override
+    public ITileDefinition craftingStorage4k() {
+        return this.craftingStorage4k;
+    }
+
+    @Override
+    public ITileDefinition craftingStorage16k() {
+        return this.craftingStorage16k;
+    }
+
+    @Override
+    public ITileDefinition craftingStorage64k() {
+        return this.craftingStorage64k;
+    }
+
+    @Override
+    public ITileDefinition craftingMonitor() {
+        return this.craftingMonitor;
+    }
+
+    @Override
+    public ITileDefinition molecularAssembler() {
+        return this.molecularAssembler;
+    }
+
+    @Override
+    public ITileDefinition lightDetector() {
+        return this.lightDetector;
+    }
+
+    @Override
+    public ITileDefinition paint() {
+        return this.paint;
+    }
+
+    public IBlockDefinition chunkLoader() {
+        return this.chunkLoader;
+    }
+
+    public IBlockDefinition itemGen() {
+        return this.itemGen;
+    }
+
+    public IBlockDefinition phantomNode() {
+        return this.phantomNode;
+    }
+
+    public IBlockDefinition cubeGenerator() {
+        return this.cubeGenerator;
+    }
+
+    public IBlockDefinition energyGenerator() {
+        return this.energyGenerator;
+    }
+}
diff --git a/core/src/main/java/appeng/core/api/definitions/ApiItems.java b/core/src/main/java/appeng/core/api/definitions/ApiItems.java
new file mode 100644
index 000000000..93a1d437e
--- /dev/null
+++ b/core/src/main/java/appeng/core/api/definitions/ApiItems.java
@@ -0,0 +1,509 @@
+/*
+ * This file is part of Applied Energistics 2.
+ * Copyright (c) 2013 - 2015, AlgorithmX2, All rights reserved.
+ *
+ * Applied Energistics 2 is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Applied Energistics 2 is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Applied Energistics 2.  If not, see .
+ */
+
+package appeng.core.api.definitions;
+
+import appeng.api.definitions.IItemDefinition;
+import appeng.api.definitions.IItems;
+import appeng.api.util.AEColoredItemDefinition;
+import appeng.bootstrap.FeatureFactory;
+
+/**
+ * Internal implementation for the API items
+ */
+public final class ApiItems implements IItems {
+    private IItemDefinition certusQuartzAxe;
+    private IItemDefinition certusQuartzHoe;
+    private IItemDefinition certusQuartzShovel;
+    private IItemDefinition certusQuartzPick;
+    private IItemDefinition certusQuartzSword;
+    private IItemDefinition certusQuartzWrench;
+    private IItemDefinition certusQuartzKnife;
+
+    private IItemDefinition netherQuartzAxe;
+    private IItemDefinition netherQuartzHoe;
+    private IItemDefinition netherQuartzShovel;
+    private IItemDefinition netherQuartzPick;
+    private IItemDefinition netherQuartzSword;
+    private IItemDefinition netherQuartzWrench;
+    private IItemDefinition netherQuartzKnife;
+
+    private IItemDefinition entropyManipulator;
+    private IItemDefinition wirelessTerminal;
+    private IItemDefinition biometricCard;
+    private IItemDefinition chargedStaff;
+    private IItemDefinition massCannon;
+    private IItemDefinition memoryCard;
+    private IItemDefinition networkTool;
+    private IItemDefinition portableCell;
+
+    private IItemDefinition cellCreative;
+    private IItemDefinition viewCell;
+
+    private IItemDefinition cell1k;
+    private IItemDefinition cell4k;
+    private IItemDefinition cell16k;
+    private IItemDefinition cell64k;
+
+    private IItemDefinition fluidCell1k;
+    private IItemDefinition fluidCell4k;
+    private IItemDefinition fluidCell16k;
+    private IItemDefinition fluidCell64k;
+
+    private IItemDefinition spatialCell2;
+    private IItemDefinition spatialCell16;
+    private IItemDefinition spatialCell128;
+
+    private IItemDefinition facade;
+    private IItemDefinition certusCrystalSeed;
+    private IItemDefinition fluixCrystalSeed;
+    private IItemDefinition netherQuartzSeed;
+
+    // rv1
+    private IItemDefinition encodedPattern;
+    private IItemDefinition colorApplicator;
+
+    private AEColoredItemDefinition coloredPaintBall;
+    private AEColoredItemDefinition coloredLumenPaintBall;
+
+    // unsupported dev tools
+    private IItemDefinition toolEraser;
+    private IItemDefinition toolMeteoritePlacer;
+    private IItemDefinition toolDebugCard;
+    private IItemDefinition toolReplicatorCard;
+
+    private IItemDefinition dummyFluidItem;
+
+    public ApiItems(FeatureFactory registry, ApiMaterials materials) {
+//        FeatureFactory certusTools = registry.features(AEFeature.CERTUS_QUARTZ_TOOLS);
+//        this.certusQuartzAxe = certusTools
+//                .item("certus_quartz_axe", props -> new QuartzAxeItem(props, AEFeature.CERTUS_QUARTZ_TOOLS))
+//                .itemGroup(ItemGroup.TOOLS).addFeatures(AEFeature.QUARTZ_AXE).build();
+//        this.certusQuartzHoe = certusTools
+//                .item("certus_quartz_hoe", props -> new QuartzHoeItem(props, AEFeature.CERTUS_QUARTZ_TOOLS))
+//                .itemGroup(ItemGroup.TOOLS).addFeatures(AEFeature.QUARTZ_HOE).build();
+//        this.certusQuartzShovel = certusTools
+//                .item("certus_quartz_shovel", props -> new QuartzSpadeItem(props, AEFeature.CERTUS_QUARTZ_TOOLS))
+//                .itemGroup(ItemGroup.TOOLS).addFeatures(AEFeature.QUARTZ_SPADE).build();
+//        this.certusQuartzPick = certusTools
+//                .item("certus_quartz_pickaxe", props -> new QuartzPickaxeItem(props, AEFeature.CERTUS_QUARTZ_TOOLS))
+//                .itemGroup(ItemGroup.TOOLS).addFeatures(AEFeature.QUARTZ_PICKAXE).build();
+//        this.certusQuartzSword = certusTools
+//                .item("certus_quartz_sword", props -> new QuartzSwordItem(props, AEFeature.CERTUS_QUARTZ_TOOLS))
+//                .itemGroup(ItemGroup.COMBAT).addFeatures(AEFeature.QUARTZ_SWORD).build();
+//        this.certusQuartzWrench = certusTools.item("certus_quartz_wrench", QuartzWrenchItem::new)
+//                .itemGroup(ItemGroup.TOOLS).props(props -> props.maxStackSize(1)).addFeatures(AEFeature.QUARTZ_WRENCH)
+//                .build();
+//        this.certusQuartzKnife = certusTools
+//                .item("certus_quartz_cutting_knife",
+//                        props -> new QuartzCuttingKnifeItem(props, AEFeature.CERTUS_QUARTZ_TOOLS))
+//                .itemGroup(ItemGroup.TOOLS).props(props -> props.maxStackSize(1).maxDamage(50).setNoRepair())
+//                .addFeatures(AEFeature.QUARTZ_KNIFE).build();
+//
+//        FeatureFactory netherTools = registry.features(AEFeature.NETHER_QUARTZ_TOOLS);
+//        this.netherQuartzAxe = netherTools
+//                .item("nether_quartz_axe", props -> new QuartzAxeItem(props, AEFeature.NETHER_QUARTZ_TOOLS))
+//                .itemGroup(ItemGroup.TOOLS).addFeatures(AEFeature.QUARTZ_AXE).build();
+//        this.netherQuartzHoe = netherTools
+//                .item("nether_quartz_hoe", props -> new QuartzHoeItem(props, AEFeature.NETHER_QUARTZ_TOOLS))
+//                .itemGroup(ItemGroup.TOOLS).addFeatures(AEFeature.QUARTZ_HOE).build();
+//        this.netherQuartzShovel = netherTools
+//                .item("nether_quartz_shovel", props -> new QuartzSpadeItem(props, AEFeature.NETHER_QUARTZ_TOOLS))
+//                .itemGroup(ItemGroup.TOOLS).addFeatures(AEFeature.QUARTZ_SPADE).build();
+//        this.netherQuartzPick = netherTools
+//                .item("nether_quartz_pickaxe", props -> new QuartzPickaxeItem(props, AEFeature.NETHER_QUARTZ_TOOLS))
+//                .itemGroup(ItemGroup.TOOLS).addFeatures(AEFeature.QUARTZ_PICKAXE).build();
+//        this.netherQuartzSword = netherTools
+//                .item("nether_quartz_sword", props -> new QuartzSwordItem(props, AEFeature.NETHER_QUARTZ_TOOLS))
+//                .itemGroup(ItemGroup.COMBAT).addFeatures(AEFeature.QUARTZ_SWORD).build();
+//        this.netherQuartzWrench = netherTools.item("nether_quartz_wrench", QuartzWrenchItem::new)
+//                .itemGroup(ItemGroup.TOOLS).props(props -> props.maxStackSize(1)).addFeatures(AEFeature.QUARTZ_WRENCH)
+//                .build();
+//        this.netherQuartzKnife = netherTools
+//                .item("nether_quartz_cutting_knife",
+//                        props -> new QuartzCuttingKnifeItem(props, AEFeature.NETHER_QUARTZ_TOOLS))
+//                .itemGroup(ItemGroup.TOOLS).props(props -> props.maxStackSize(1).maxDamage(50).setNoRepair())
+//                .addFeatures(AEFeature.QUARTZ_KNIFE).build();
+//
+//        Consumer chargedDefaults = props -> props.maxStackSize(1).maxDamage(32).setNoRepair();
+//
+//        FeatureFactory powerTools = registry.features(AEFeature.POWERED_TOOLS);
+//        this.entropyManipulator = powerTools.item("entropy_manipulator", EntropyManipulatorItem::new)
+//                .props(chargedDefaults).addFeatures(AEFeature.ENTROPY_MANIPULATOR)
+//                .dispenserBehavior(BlockToolDispenseItemBehavior::new).build();
+//        this.wirelessTerminal = powerTools.item("wireless_terminal", WirelessTerminalItem::new).props(chargedDefaults)
+//                .addFeatures(AEFeature.WIRELESS_ACCESS_TERMINAL).build();
+//        this.chargedStaff = powerTools.item("charged_staff", ChargedStaffItem::new).props(chargedDefaults)
+//                .addFeatures(AEFeature.CHARGED_STAFF).build();
+//        this.massCannon = powerTools.item("matter_cannon", MatterCannonItem::new).props(chargedDefaults)
+//                .addFeatures(AEFeature.MATTER_CANNON).dispenserBehavior(MatterCannonDispenseItemBehavior::new).build();
+//        this.portableCell = powerTools.item("portable_cell", PortableCellItem::new).props(chargedDefaults)
+//                .addFeatures(AEFeature.PORTABLE_CELL, AEFeature.STORAGE_CELLS).build();
+//        this.colorApplicator = powerTools.item("color_applicator", ColorApplicatorItem::new).props(chargedDefaults)
+//                .addFeatures(AEFeature.COLOR_APPLICATOR).dispenserBehavior(BlockToolDispenseItemBehavior::new)
+//                .rendering(new ColorApplicatorItemRendering()).build();
+//
+//        this.biometricCard = registry.item("biometric_card", BiometricCardItem::new)
+//                .props(props -> props.maxStackSize(1)).features(AEFeature.SECURITY).build();
+//        this.memoryCard = registry.item("memory_card", MemoryCardItem::new).props(props -> props.maxStackSize(1))
+//                .features(AEFeature.MEMORY_CARD).build();
+//        this.networkTool = registry.item("network_tool", NetworkToolItem::new)
+//                .props(props -> props.maxStackSize(1).addToolType(FabricToolTags.get("wrench"), 0))
+//                .features(AEFeature.NETWORK_TOOL).build();
+//
+//        this.cellCreative = registry.item("creative_storage_cell", CreativeStorageCellItem::new)
+//                .props(props -> props.maxStackSize(1)).features(AEFeature.STORAGE_CELLS, AEFeature.CREATIVE).build();
+//        this.viewCell = registry.item("view_cell", ViewCellItem::new).props(props -> props.maxStackSize(1))
+//                .features(AEFeature.VIEW_CELL).build();
+//
+//        Consumer storageCellProps = p -> p.maxStackSize(1);
+//
+//        FeatureFactory storageCells = registry.features(AEFeature.STORAGE_CELLS);
+//        this.cell1k = storageCells
+//                .item("1k_storage_cell",
+//                        props -> new BasicStorageCellItem(props, MaterialType.ITEM_1K_CELL_COMPONENT, 1))
+//                .props(storageCellProps).build();
+//        this.cell4k = storageCells
+//                .item("4k_storage_cell",
+//                        props -> new BasicStorageCellItem(props, MaterialType.ITEM_4K_CELL_COMPONENT, 4))
+//                .props(storageCellProps).build();
+//        this.cell16k = storageCells
+//                .item("16k_storage_cell",
+//                        props -> new BasicStorageCellItem(props, MaterialType.ITEM_16K_CELL_COMPONENT, 16))
+//                .props(storageCellProps).build();
+//        this.cell64k = storageCells
+//                .item("64k_storage_cell",
+//                        props -> new BasicStorageCellItem(props, MaterialType.ITEM_64K_CELL_COMPONENT, 64))
+//                .props(storageCellProps).build();
+//
+//        this.fluidCell1k = storageCells
+//                .item("1k_fluid_storage_cell",
+//                        props -> new BasicFluidStorageCell(props, MaterialType.FLUID_1K_CELL_COMPONENT, 1))
+//                .props(storageCellProps).build();
+//        this.fluidCell4k = storageCells
+//                .item("4k_fluid_storage_cell",
+//                        props -> new BasicFluidStorageCell(props, MaterialType.FLUID_4K_CELL_COMPONENT, 4))
+//                .props(storageCellProps).build();
+//        this.fluidCell16k = storageCells
+//                .item("16k_fluid_storage_cell",
+//                        props -> new BasicFluidStorageCell(props, MaterialType.FLUID_16K_CELL_COMPONENT, 16))
+//                .props(storageCellProps).build();
+//        this.fluidCell64k = storageCells
+//                .item("64k_fluid_storage_cell",
+//                        props -> new BasicFluidStorageCell(props, MaterialType.FLUID_64K_CELL_COMPONENT, 64))
+//                .props(storageCellProps).build();
+//
+//        FeatureFactory spatialCells = registry.features(AEFeature.SPATIAL_IO);
+//        this.spatialCell2 = spatialCells
+//                .item("2_cubed_spatial_storage_cell", props -> new SpatialStorageCellItem(props, 2))
+//                .props(storageCellProps).build();
+//        this.spatialCell16 = spatialCells
+//                .item("16_cubed_spatial_storage_cell", props -> new SpatialStorageCellItem(props, 16))
+//                .props(storageCellProps).build();
+//        this.spatialCell128 = spatialCells
+//                .item("128_cubed_spatial_storage_cell", props -> new SpatialStorageCellItem(props, 128))
+//                .props(storageCellProps).build();
+//
+//        this.facade = registry.item("facade", FacadeItem::new).features(AEFeature.FACADES).build();
+//
+//        this.certusCrystalSeed = registry
+//                .item("certus_crystal_seed",
+//                        props -> new CrystalSeedItem(props, materials.purifiedCertusQuartzCrystal().item()))
+//                .features(AEFeature.CRYSTAL_SEEDS).build();
+//        this.fluixCrystalSeed = registry
+//                .item("fluix_crystal_seed",
+//                        props -> new CrystalSeedItem(props, materials.purifiedFluixCrystal().item()))
+//                .features(AEFeature.CRYSTAL_SEEDS).build();
+//        this.netherQuartzSeed = registry
+//                .item("nether_quartz_seed",
+//                        props -> new CrystalSeedItem(props, materials.purifiedNetherQuartzCrystal().item()))
+//                .features(AEFeature.CRYSTAL_SEEDS).build();
+//
+//        GrowingCrystalEntity.TYPE = registry
+//                .entity("growing_crystal", GrowingCrystalEntity::new, SpawnGroup.MISC)
+//                .customize(builder -> builder.size(0.25F, 0.25F)).build();
+//
+//        // rv1
+//        this.encodedPattern = registry.item("encoded_pattern", EncodedPatternItem::new)
+//                .props(props -> props.maxStackSize(1)).features(AEFeature.PATTERNS).build();
+//
+//        this.coloredPaintBall = createPaintBalls(registry, "_paint_ball", false);
+//        this.coloredLumenPaintBall = createPaintBalls(registry, "_lumen_paint_ball", true);
+//
+//        FeatureFactory debugTools = registry.features(AEFeature.UNSUPPORTED_DEVELOPER_TOOLS, AEFeature.CREATIVE);
+//        this.toolEraser = debugTools.item("debug_eraser", EraserItem::new).build();
+//        this.toolMeteoritePlacer = debugTools.item("debug_meteorite_placer", MeteoritePlacerItem::new).build();
+//        this.toolDebugCard = debugTools.item("debug_card", DebugCardItem::new).build();
+//        this.toolReplicatorCard = debugTools.item("debug_replicator_card", ReplicatorCardItem::new).build();
+//        debugTools.item("debug_part_placer", DebugPartPlacerItem::new).build();
+//
+//        this.dummyFluidItem = registry.item("dummy_fluid_item", FluidDummyItem::new)
+//                .rendering(new FluidDummyItemRendering()).build();
+    }
+
+//    private static AEColoredItemDefinition createPaintBalls(FeatureFactory registry, String idSuffix, boolean lumen) {
+//        ColoredItemDefinition colors = new ColoredItemDefinition();
+//        for (AEColor color : AEColor.values()) {
+//            if (color == AEColor.TRANSPARENT) {
+//                continue; // Fluix paintballs don't exist
+//            }
+//
+//            String id = color.registryPrefix + idSuffix;
+//            IItemDefinition paintBall = registry.item(id, props -> new PaintBallItem(props, color, lumen))
+//                    .features(AEFeature.PAINT_BALLS).rendering(new PaintBallItemRendering(color, lumen)).build();
+//            colors.add(color, new ItemStackSrc(paintBall.item(), ActivityState.Enabled));
+//        }
+//        return colors;
+//    }
+//
+    @Override
+    public IItemDefinition certusQuartzAxe() {
+        return this.certusQuartzAxe;
+    }
+
+    @Override
+    public IItemDefinition certusQuartzHoe() {
+        return this.certusQuartzHoe;
+    }
+
+    @Override
+    public IItemDefinition certusQuartzShovel() {
+        return this.certusQuartzShovel;
+    }
+
+    @Override
+    public IItemDefinition certusQuartzPick() {
+        return this.certusQuartzPick;
+    }
+
+    @Override
+    public IItemDefinition certusQuartzSword() {
+        return this.certusQuartzSword;
+    }
+
+    @Override
+    public IItemDefinition certusQuartzWrench() {
+        return this.certusQuartzWrench;
+    }
+
+    @Override
+    public IItemDefinition certusQuartzKnife() {
+        return this.certusQuartzKnife;
+    }
+
+    @Override
+    public IItemDefinition netherQuartzAxe() {
+        return this.netherQuartzAxe;
+    }
+
+    @Override
+    public IItemDefinition netherQuartzHoe() {
+        return this.netherQuartzHoe;
+    }
+
+    @Override
+    public IItemDefinition netherQuartzShovel() {
+        return this.netherQuartzShovel;
+    }
+
+    @Override
+    public IItemDefinition netherQuartzPick() {
+        return this.netherQuartzPick;
+    }
+
+    @Override
+    public IItemDefinition netherQuartzSword() {
+        return this.netherQuartzSword;
+    }
+
+    @Override
+    public IItemDefinition netherQuartzWrench() {
+        return this.netherQuartzWrench;
+    }
+
+    @Override
+    public IItemDefinition netherQuartzKnife() {
+        return this.netherQuartzKnife;
+    }
+
+    @Override
+    public IItemDefinition entropyManipulator() {
+        return this.entropyManipulator;
+    }
+
+    @Override
+    public IItemDefinition wirelessTerminal() {
+        return this.wirelessTerminal;
+    }
+
+    @Override
+    public IItemDefinition biometricCard() {
+        return this.biometricCard;
+    }
+
+    @Override
+    public IItemDefinition chargedStaff() {
+        return this.chargedStaff;
+    }
+
+    @Override
+    public IItemDefinition massCannon() {
+        return this.massCannon;
+    }
+
+    @Override
+    public IItemDefinition memoryCard() {
+        return this.memoryCard;
+    }
+
+    @Override
+    public IItemDefinition networkTool() {
+        return this.networkTool;
+    }
+
+    @Override
+    public IItemDefinition portableCell() {
+        return this.portableCell;
+    }
+
+    @Override
+    public IItemDefinition cellCreative() {
+        return this.cellCreative;
+    }
+
+    @Override
+    public IItemDefinition viewCell() {
+        return this.viewCell;
+    }
+
+    @Override
+    public IItemDefinition cell1k() {
+        return this.cell1k;
+    }
+
+    @Override
+    public IItemDefinition cell4k() {
+        return this.cell4k;
+    }
+
+    @Override
+    public IItemDefinition cell16k() {
+        return this.cell16k;
+    }
+
+    @Override
+    public IItemDefinition cell64k() {
+        return this.cell64k;
+    }
+
+    @Override
+    public IItemDefinition fluidCell1k() {
+        return this.fluidCell1k;
+    }
+
+    @Override
+    public IItemDefinition fluidCell4k() {
+        return this.fluidCell4k;
+    }
+
+    @Override
+    public IItemDefinition fluidCell16k() {
+        return this.fluidCell16k;
+    }
+
+    @Override
+    public IItemDefinition fluidCell64k() {
+        return this.fluidCell64k;
+    }
+
+    @Override
+    public IItemDefinition spatialCell2() {
+        return this.spatialCell2;
+    }
+
+    @Override
+    public IItemDefinition spatialCell16() {
+        return this.spatialCell16;
+    }
+
+    @Override
+    public IItemDefinition spatialCell128() {
+        return this.spatialCell128;
+    }
+
+    @Override
+    public IItemDefinition facade() {
+        return this.facade;
+    }
+
+    @Override
+    public IItemDefinition certusCrystalSeed() {
+        return certusCrystalSeed;
+    }
+
+    @Override
+    public IItemDefinition fluixCrystalSeed() {
+        return fluixCrystalSeed;
+    }
+
+    @Override
+    public IItemDefinition netherQuartzSeed() {
+        return netherQuartzSeed;
+    }
+
+    @Override
+    public IItemDefinition encodedPattern() {
+        return this.encodedPattern;
+    }
+
+    @Override
+    public IItemDefinition colorApplicator() {
+        return this.colorApplicator;
+    }
+
+    @Override
+    public AEColoredItemDefinition coloredPaintBall() {
+        return this.coloredPaintBall;
+    }
+
+    @Override
+    public AEColoredItemDefinition coloredLumenPaintBall() {
+        return this.coloredLumenPaintBall;
+    }
+
+    public IItemDefinition toolEraser() {
+        return this.toolEraser;
+    }
+
+    public IItemDefinition toolMeteoritePlacer() {
+        return this.toolMeteoritePlacer;
+    }
+
+    public IItemDefinition toolDebugCard() {
+        return this.toolDebugCard;
+    }
+
+    public IItemDefinition toolReplicatorCard() {
+        return this.toolReplicatorCard;
+    }
+
+    @Override
+    public IItemDefinition dummyFluidItem() {
+        return this.dummyFluidItem;
+    }
+}
diff --git a/src/main/java/appeng/core/api/definitions/ApiMaterials.java b/core/src/main/java/appeng/core/api/definitions/ApiMaterials.java
similarity index 100%
rename from src/main/java/appeng/core/api/definitions/ApiMaterials.java
rename to core/src/main/java/appeng/core/api/definitions/ApiMaterials.java
diff --git a/core/src/main/java/appeng/core/api/definitions/ApiParts.java b/core/src/main/java/appeng/core/api/definitions/ApiParts.java
new file mode 100644
index 000000000..8f2264c91
--- /dev/null
+++ b/core/src/main/java/appeng/core/api/definitions/ApiParts.java
@@ -0,0 +1,385 @@
+/*
+ * This file is part of Applied Energistics 2.
+ * Copyright (c) 2013 - 2015, AlgorithmX2, All rights reserved.
+ *
+ * Applied Energistics 2 is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Applied Energistics 2 is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Applied Energistics 2.  If not, see .
+ */
+
+package appeng.core.api.definitions;
+
+import appeng.api.definitions.IItemDefinition;
+import appeng.api.definitions.IParts;
+import appeng.api.util.AEColoredItemDefinition;
+import appeng.bootstrap.FeatureFactory;
+import appeng.core.features.registries.PartModels;
+
+/**
+ * Internal implementation for the API parts
+ */
+public final class ApiParts implements IParts {
+    private AEColoredItemDefinition cableSmart;
+    private AEColoredItemDefinition cableCovered;
+    private AEColoredItemDefinition cableGlass;
+    private AEColoredItemDefinition cableDenseCovered;
+    private AEColoredItemDefinition cableDenseSmart;
+    private IItemDefinition quartzFiber;
+    private IItemDefinition toggleBus;
+    private IItemDefinition invertedToggleBus;
+    private IItemDefinition storageBus;
+    private IItemDefinition importBus;
+    private IItemDefinition exportBus;
+    private IItemDefinition iface;
+    private IItemDefinition fluidIface;
+    private IItemDefinition levelEmitter;
+    private IItemDefinition fluidLevelEmitter;
+    private IItemDefinition annihilationPlane;
+    private IItemDefinition identityAnnihilationPlane;
+    private IItemDefinition fluidAnnihilationPlane;
+    private IItemDefinition formationPlane;
+    private IItemDefinition fluidFormationPlane;
+    private IItemDefinition p2PTunnelME;
+    private IItemDefinition p2PTunnelRedstone;
+    private IItemDefinition p2PTunnelItems;
+    private IItemDefinition p2PTunnelFluids;
+    private IItemDefinition p2PTunnelEU;
+    private IItemDefinition p2PTunnelFE;
+    private IItemDefinition p2PTunnelLight;
+    private IItemDefinition cableAnchor;
+    private IItemDefinition monitor;
+    private IItemDefinition semiDarkMonitor;
+    private IItemDefinition darkMonitor;
+    private IItemDefinition interfaceTerminal;
+    private IItemDefinition patternTerminal;
+    private IItemDefinition craftingTerminal;
+    private IItemDefinition terminal;
+    private IItemDefinition storageMonitor;
+    private IItemDefinition conversionMonitor;
+    private IItemDefinition fluidImportBus;
+    private IItemDefinition fluidExportBus;
+    private IItemDefinition fluidTerminal;
+    private IItemDefinition fluidStorageBus;
+
+    public ApiParts(FeatureFactory registry, PartModels partModels) {
+        registerPartModels(partModels);
+
+// FIXME       this.cableSmart = constructColoredDefinition(registry, "smart_cable", PartType.CABLE_SMART,
+// FIXME               SmartCablePart::new);
+// FIXME       this.cableCovered = constructColoredDefinition(registry, "covered_cable", PartType.CABLE_COVERED,
+// FIXME               CoveredCablePart::new);
+// FIXME       this.cableGlass = constructColoredDefinition(registry, "glass_cable", PartType.CABLE_GLASS,
+// FIXME               GlassCablePart::new);
+// FIXME       this.cableDenseCovered = constructColoredDefinition(registry, "covered_dense_cable",
+// FIXME               PartType.CABLE_DENSE_COVERED, CoveredDenseCablePart::new);
+// FIXME       this.cableDenseSmart = constructColoredDefinition(registry, "smart_dense_cable", PartType.CABLE_DENSE_SMART,
+// FIXME               SmartDenseCablePart::new);
+// FIXME       this.quartzFiber = createPart(registry, "quartz_fiber", PartType.QUARTZ_FIBER, QuartzFiberPart::new);
+// FIXME       this.toggleBus = createPart(registry, "toggle_bus", PartType.TOGGLE_BUS, ToggleBusPart::new);
+// FIXME       this.invertedToggleBus = createPart(registry, "inverted_toggle_bus", PartType.INVERTED_TOGGLE_BUS,
+// FIXME               InvertedToggleBusPart::new);
+// FIXME       this.cableAnchor = createPart(registry, "cable_anchor", PartType.CABLE_ANCHOR, CableAnchorPart::new);
+// FIXME       this.monitor = createPart(registry, "monitor", PartType.MONITOR, PanelPart::new);
+// FIXME       this.semiDarkMonitor = createPart(registry, "semi_dark_monitor", PartType.SEMI_DARK_MONITOR,
+// FIXME               SemiDarkPanelPart::new);
+// FIXME       this.darkMonitor = createPart(registry, "dark_monitor", PartType.DARK_MONITOR, DarkPanelPart::new);
+// FIXME       this.storageBus = createPart(registry, "storage_bus", PartType.STORAGE_BUS, StorageBusPart::new);
+// FIXME       this.fluidStorageBus = createPart(registry, "fluid_storage_bus", PartType.FLUID_STORAGE_BUS,
+// FIXME               FluidStorageBusPart::new);
+// FIXME       this.importBus = createPart(registry, "import_bus", PartType.IMPORT_BUS, ImportBusPart::new);
+// FIXME       this.fluidImportBus = createPart(registry, "fluid_import_bus", PartType.FLUID_IMPORT_BUS,
+// FIXME               FluidImportBusPart::new);
+// FIXME       this.exportBus = createPart(registry, "export_bus", PartType.EXPORT_BUS, ExportBusPart::new);
+// FIXME       this.fluidExportBus = createPart(registry, "fluid_export_bus", PartType.FLUID_EXPORT_BUS,
+// FIXME               FluidExportBusPart::new);
+// FIXME       this.levelEmitter = createPart(registry, "level_emitter", PartType.LEVEL_EMITTER, LevelEmitterPart::new);
+// FIXME       this.fluidLevelEmitter = createPart(registry, "fluid_level_emitter", PartType.FLUID_LEVEL_EMITTER,
+// FIXME               FluidLevelEmitterPart::new);
+// FIXME       this.annihilationPlane = createPart(registry, "annihilation_plane", PartType.ANNIHILATION_PLANE,
+// FIXME               AnnihilationPlanePart::new);
+// FIXME       this.identityAnnihilationPlane = createPart(registry, "identity_annihilation_plane",
+// FIXME               PartType.IDENTITY_ANNIHILATION_PLANE, IdentityAnnihilationPlanePart::new);
+// FIXME       this.fluidAnnihilationPlane = createPart(registry, "fluid_annihilation_plane",
+// FIXME               PartType.FLUID_ANNIHILATION_PLANE, FluidAnnihilationPlanePart::new);
+// FIXME       this.formationPlane = createPart(registry, "formation_plane", PartType.FORMATION_PLANE,
+// FIXME               FormationPlanePart::new);
+// FIXME       this.fluidFormationPlane = createPart(registry, "fluid_formation_plane", PartType.FLUID_FORMATION_PLANE,
+// FIXME               FluidFormationPlanePart::new);
+// FIXME       this.patternTerminal = createPart(registry, "pattern_terminal", PartType.PATTERN_TERMINAL,
+// FIXME               PatternTerminalPart::new);
+// FIXME       this.craftingTerminal = createPart(registry, "crafting_terminal", PartType.CRAFTING_TERMINAL,
+// FIXME               CraftingTerminalPart::new);
+// FIXME       this.terminal = createPart(registry, "terminal", PartType.TERMINAL, TerminalPart::new);
+// FIXME       this.storageMonitor = createPart(registry, "storage_monitor", PartType.STORAGE_MONITOR,
+// FIXME               StorageMonitorPart::new);
+// FIXME       this.conversionMonitor = createPart(registry, "conversion_monitor", PartType.CONVERSION_MONITOR,
+// FIXME               ConversionMonitorPart::new);
+// FIXME       this.iface = createPart(registry, "cable_interface", PartType.INTERFACE, InterfacePart::new);
+// FIXME       this.fluidIface = createPart(registry, "cable_fluid_interface", PartType.FLUID_INTERFACE,
+// FIXME               FluidInterfacePart::new);
+// FIXME       this.p2PTunnelME = createPart(registry, "me_p2p_tunnel", PartType.P2P_TUNNEL_ME, MEP2PTunnelPart::new);
+// FIXME       this.p2PTunnelRedstone = createPart(registry, "redstone_p2p_tunnel", PartType.P2P_TUNNEL_REDSTONE,
+// FIXME               RedstoneP2PTunnelPart::new);
+// FIXME       this.p2PTunnelItems = createPart(registry, "item_p2p_tunnel", PartType.P2P_TUNNEL_ITEM, ItemP2PTunnelPart::new);
+// FIXME       this.p2PTunnelFluids = createPart(registry, "fluid_p2p_tunnel", PartType.P2P_TUNNEL_FLUID,
+// FIXME               FluidP2PTunnelPart::new);
+// FIXME       this.p2PTunnelEU = null; // FIXME createPart( "ic2_p2p_tunnel", PartType.P2P_TUNNEL_IC2,
+// FIXME                                // PartP2PIC2Power::new);
+// FIXME       this.p2PTunnelFE = createPart(registry, "fe_p2p_tunnel", PartType.P2P_TUNNEL_FE, FEP2PTunnelPart::new);
+// FIXME       this.p2PTunnelLight = createPart(registry, "light_p2p_tunnel", PartType.P2P_TUNNEL_LIGHT,
+// FIXME               LightP2PTunnelPart::new);
+// FIXME       this.interfaceTerminal = createPart(registry, "interface_terminal", PartType.INTERFACE_TERMINAL,
+// FIXME               InterfaceTerminalPart::new);
+// FIXME       this.fluidTerminal = createPart(registry, "fluid_terminal", PartType.FLUID_TERMINAL, FluidTerminalPart::new);
+    }
+
+    private void registerPartModels(PartModels partModels) {
+
+// FIXME        // Register the built-in models for annihilation planes
+// FIXME        Identifier fluidFormationPlaneTexture = new Identifier(AppEng.MOD_ID,
+// FIXME                "item/part/fluid_formation_plane");
+// FIXME        Identifier fluidFormationPlaneOnTexture = new Identifier(AppEng.MOD_ID,
+// FIXME                "parts/fluid_formation_plane_on");
+// FIXME
+// FIXME        // Register all part models
+// FIXME        for (PartType partType : PartType.values()) {
+// FIXME            partModels.registerModels(partType.getModels());
+// FIXME        }
+    }
+
+// FIXME    private  IItemDefinition createPart(FeatureFactory registry, String id, PartType type,
+// FIXME            Function factory) {
+// FIXME        return registry.item(id, props -> new PartItem<>(props, type, factory)).itemGroup(CreativeTab.INSTANCE)
+// FIXME                .rendering(new PartItemRendering()).build();
+// FIXME    }
+// FIXME
+// FIXME    private  AEColoredItemDefinition constructColoredDefinition(FeatureFactory registry,
+// FIXME            String idSuffix, PartType type, Function factory) {
+// FIXME        final ColoredItemDefinition definition = new ColoredItemDefinition();
+// FIXME
+// FIXME        for (final AEColor color : AEColor.values()) {
+// FIXME            String id = color.registryPrefix + '_' + idSuffix;
+// FIXME
+// FIXME            IItemDefinition itemDef = registry.item(id, props -> new ColoredPartItem<>(props, type, factory, color))
+// FIXME                    .itemGroup(CreativeTab.INSTANCE).rendering(new PartItemRendering(color)).build();
+// FIXME
+// FIXME            definition.add(color, new ItemStackSrc(itemDef.item(), ActivityState.Enabled));
+// FIXME        }
+// FIXME
+// FIXME        return definition;
+// FIXME    }
+
+    @Override
+    public AEColoredItemDefinition cableSmart() {
+        return this.cableSmart;
+    }
+
+    @Override
+    public AEColoredItemDefinition cableCovered() {
+        return this.cableCovered;
+    }
+
+    @Override
+    public AEColoredItemDefinition cableGlass() {
+        return this.cableGlass;
+    }
+
+    @Override
+    public AEColoredItemDefinition cableDenseCovered() {
+        return this.cableDenseCovered;
+    }
+
+    @Override
+    public AEColoredItemDefinition cableDenseSmart() {
+        return this.cableDenseSmart;
+    }
+
+    @Override
+    public IItemDefinition quartzFiber() {
+        return this.quartzFiber;
+    }
+
+    @Override
+    public IItemDefinition toggleBus() {
+        return this.toggleBus;
+    }
+
+    @Override
+    public IItemDefinition invertedToggleBus() {
+        return this.invertedToggleBus;
+    }
+
+    @Override
+    public IItemDefinition storageBus() {
+        return this.storageBus;
+    }
+
+    @Override
+    public IItemDefinition importBus() {
+        return this.importBus;
+    }
+
+    @Override
+    public IItemDefinition exportBus() {
+        return this.exportBus;
+    }
+
+    @Override
+    public IItemDefinition iface() {
+        return this.iface;
+    }
+
+    @Override
+    public IItemDefinition fluidIface() {
+        return this.fluidIface;
+    }
+
+    @Override
+    public IItemDefinition levelEmitter() {
+        return this.levelEmitter;
+    }
+
+    @Override
+    public IItemDefinition annihilationPlane() {
+        return this.annihilationPlane;
+    }
+
+    @Override
+    public IItemDefinition identityAnnihilationPlane() {
+        return this.identityAnnihilationPlane;
+    }
+
+    @Override
+    public IItemDefinition formationPlane() {
+        return this.formationPlane;
+    }
+
+    @Override
+    public IItemDefinition p2PTunnelME() {
+        return this.p2PTunnelME;
+    }
+
+    @Override
+    public IItemDefinition p2PTunnelRedstone() {
+        return this.p2PTunnelRedstone;
+    }
+
+    @Override
+    public IItemDefinition p2PTunnelItems() {
+        return this.p2PTunnelItems;
+    }
+
+    @Override
+    public IItemDefinition p2PTunnelFluids() {
+        return this.p2PTunnelFluids;
+    }
+
+    @Override
+    public IItemDefinition p2PTunnelEU() {
+        return this.p2PTunnelEU;
+    }
+
+    @Override
+    public IItemDefinition p2PTunnelFE() {
+        return this.p2PTunnelFE;
+    }
+
+    @Override
+    public IItemDefinition p2PTunnelLight() {
+        return this.p2PTunnelLight;
+    }
+
+    @Override
+    public IItemDefinition cableAnchor() {
+        return this.cableAnchor;
+    }
+
+    @Override
+    public IItemDefinition monitor() {
+        return this.monitor;
+    }
+
+    @Override
+    public IItemDefinition semiDarkMonitor() {
+        return this.semiDarkMonitor;
+    }
+
+    @Override
+    public IItemDefinition darkMonitor() {
+        return this.darkMonitor;
+    }
+
+    @Override
+    public IItemDefinition interfaceTerminal() {
+        return this.interfaceTerminal;
+    }
+
+    @Override
+    public IItemDefinition patternTerminal() {
+        return this.patternTerminal;
+    }
+
+    @Override
+    public IItemDefinition craftingTerminal() {
+        return this.craftingTerminal;
+    }
+
+    @Override
+    public IItemDefinition terminal() {
+        return this.terminal;
+    }
+
+    @Override
+    public IItemDefinition storageMonitor() {
+        return this.storageMonitor;
+    }
+
+    @Override
+    public IItemDefinition conversionMonitor() {
+        return this.conversionMonitor;
+    }
+
+    @Override
+    public IItemDefinition fluidTerminal() {
+        return this.fluidTerminal;
+    }
+
+    @Override
+    public IItemDefinition fluidImportBus() {
+        return this.fluidImportBus;
+    }
+
+    @Override
+    public IItemDefinition fluidExportBus() {
+        return this.fluidExportBus;
+    }
+
+    @Override
+    public IItemDefinition fluidStorageBus() {
+        return this.fluidStorageBus;
+    }
+
+    @Override
+    public IItemDefinition fluidLevelEmitter() {
+        return this.fluidLevelEmitter;
+    }
+
+    @Override
+    public IItemDefinition fluidAnnihilationPlane() {
+        return this.fluidAnnihilationPlane;
+    }
+
+    @Override
+    public IItemDefinition fluidFormationnPlane() {
+        return this.fluidFormationPlane;
+    }
+}
diff --git a/src/main/java/appeng/core/features/registries/GridCacheRegistry.java b/core/src/main/java/appeng/core/features/registries/GridCacheRegistry.java
similarity index 100%
rename from src/main/java/appeng/core/features/registries/GridCacheRegistry.java
rename to core/src/main/java/appeng/core/features/registries/GridCacheRegistry.java
diff --git a/src/main/java/appeng/core/features/registries/LocatableRegistry.java b/core/src/main/java/appeng/core/features/registries/LocatableRegistry.java
similarity index 71%
rename from src/main/java/appeng/core/features/registries/LocatableRegistry.java
rename to core/src/main/java/appeng/core/features/registries/LocatableRegistry.java
index 4fe02f849..970bab4f1 100644
--- a/src/main/java/appeng/core/features/registries/LocatableRegistry.java
+++ b/core/src/main/java/appeng/core/features/registries/LocatableRegistry.java
@@ -21,9 +21,6 @@ package appeng.core.features.registries;
 import java.util.HashMap;
 import java.util.Map;
 
-import net.minecraftforge.common.MinecraftForge;
-import net.minecraftforge.eventbus.api.SubscribeEvent;
-
 import appeng.api.events.LocatableEventAnnounce;
 import appeng.api.events.LocatableEventAnnounce.LocatableEvent;
 import appeng.api.features.ILocatable;
@@ -35,20 +32,18 @@ public final class LocatableRegistry implements ILocatableRegistry {
 
     public LocatableRegistry() {
         this.set = new HashMap<>();
-        MinecraftForge.EVENT_BUS.register(this);
-    }
 
-    @SubscribeEvent
-    public void updateLocatable(final LocatableEventAnnounce e) {
-        if (Platform.isClient()) {
-            return; // IGNORE!
-        }
+        LocatableEventAnnounce.EVENT.register((target, change) -> {
+            if (Platform.isClient()) {
+                return; // IGNORE!
+            }
 
-        if (e.change == LocatableEvent.REGISTER) {
-            this.set.put(e.target.getLocatableSerial(), e.target);
-        } else if (e.change == LocatableEvent.UNREGISTER) {
-            this.set.remove(e.target.getLocatableSerial());
-        }
+            if (change == LocatableEvent.REGISTER) {
+                this.set.put(target.getLocatableSerial(), target);
+            } else if (change == LocatableEvent.UNREGISTER) {
+                this.set.remove(target.getLocatableSerial());
+            }
+        });
     }
 
     @Override
diff --git a/src/main/java/appeng/core/features/registries/MatterCannonAmmoRegistry.java b/core/src/main/java/appeng/core/features/registries/MatterCannonAmmoRegistry.java
similarity index 94%
rename from src/main/java/appeng/core/features/registries/MatterCannonAmmoRegistry.java
rename to core/src/main/java/appeng/core/features/registries/MatterCannonAmmoRegistry.java
index ac4895f9d..b2e8e8856 100644
--- a/src/main/java/appeng/core/features/registries/MatterCannonAmmoRegistry.java
+++ b/core/src/main/java/appeng/core/features/registries/MatterCannonAmmoRegistry.java
@@ -24,6 +24,8 @@ import java.util.Map;
 
 import net.minecraft.item.Item;
 import net.minecraft.item.ItemStack;
+import net.minecraft.tag.ItemTags;
+import net.minecraft.tag.Tag;
 import net.minecraft.util.Identifier;
 
 import appeng.api.features.IMatterCannonAmmoRegistry;
@@ -131,10 +133,10 @@ public class MatterCannonAmmoRegistry implements IMatterCannonAmmoRegistry {
         }
 
         // Next, check each item tag
-        for (Identifier tag : item.getTags()) {
-            weight = tagDamageModifiers.get(tag);
-            if (weight != null) {
-                return weight.floatValue();
+        for (Map.Entry entry : tagDamageModifiers.entrySet()) {
+            Tag itemTag = ItemTags.getContainer().get(entry.getKey());
+            if (itemTag != null && itemTag.contains(item)) {
+                return entry.getValue().floatValue();
             }
         }
 
diff --git a/src/main/java/appeng/core/features/registries/MovableTileRegistry.java b/core/src/main/java/appeng/core/features/registries/MovableTileRegistry.java
similarity index 99%
rename from src/main/java/appeng/core/features/registries/MovableTileRegistry.java
rename to core/src/main/java/appeng/core/features/registries/MovableTileRegistry.java
index eff0c5286..2ae967103 100644
--- a/src/main/java/appeng/core/features/registries/MovableTileRegistry.java
+++ b/core/src/main/java/appeng/core/features/registries/MovableTileRegistry.java
@@ -72,7 +72,7 @@ public class MovableTileRegistry implements IMovableRegistry {
                 ((IMovableTile) te).prepareToMove();
             }
 
-            te.remove();
+            te.markRemoved();
             return true;
         }
 
diff --git a/src/main/java/appeng/core/features/registries/P2PTunnelRegistry.java b/core/src/main/java/appeng/core/features/registries/P2PTunnelRegistry.java
similarity index 88%
rename from src/main/java/appeng/core/features/registries/P2PTunnelRegistry.java
rename to core/src/main/java/appeng/core/features/registries/P2PTunnelRegistry.java
index bbc4520ae..6f9be252c 100644
--- a/src/main/java/appeng/core/features/registries/P2PTunnelRegistry.java
+++ b/core/src/main/java/appeng/core/features/registries/P2PTunnelRegistry.java
@@ -25,15 +25,14 @@ import java.util.Map.Entry;
 import javax.annotation.Nonnull;
 import javax.annotation.Nullable;
 
+import alexiil.mc.lib.attributes.Attribute;
+import alexiil.mc.lib.attributes.fluid.FluidAttributes;
 import net.minecraft.block.Blocks;
 import net.minecraft.item.Item;
 import net.minecraft.item.ItemStack;
 import net.minecraft.item.Items;
 import net.minecraft.util.math.Direction;
 import net.minecraft.util.Identifier;
-import net.minecraftforge.common.capabilities.Capability;
-import net.minecraftforge.fluids.capability.CapabilityFluidHandler;
-import net.minecraftforge.registries.ForgeRegistries;
 
 import appeng.api.AEApi;
 import appeng.api.config.TunnelType;
@@ -43,14 +42,14 @@ import appeng.api.definitions.IItemDefinition;
 import appeng.api.definitions.IParts;
 import appeng.api.features.IP2PTunnelRegistry;
 import appeng.api.util.AEColor;
-import appeng.capabilities.Capabilities;
+import net.minecraft.util.registry.Registry;
 
 public final class P2PTunnelRegistry implements IP2PTunnelRegistry {
     private static final int INITIAL_CAPACITY = 40;
 
     private final Map tunnels = new HashMap<>(INITIAL_CAPACITY);
     private final Map modIdTunnels = new HashMap<>(INITIAL_CAPACITY);
-    private final Map, TunnelType> capTunnels = new HashMap<>(INITIAL_CAPACITY);
+    private final Map, TunnelType> attrTunnels = new HashMap<>(INITIAL_CAPACITY);
 
     public void configure() {
 
@@ -58,13 +57,13 @@ public final class P2PTunnelRegistry implements IP2PTunnelRegistry {
         final IBlocks blocks = definitions.blocks();
         final IParts parts = definitions.parts();
 
-        /**
+        /*
          * light!
          */
         this.addNewAttunement(new ItemStack(Blocks.TORCH), TunnelType.LIGHT);
         this.addNewAttunement(new ItemStack(Blocks.GLOWSTONE), TunnelType.LIGHT);
 
-        /**
+        /*
          * Forge energy tunnel items
          */
 
@@ -155,8 +154,11 @@ public final class P2PTunnelRegistry implements IP2PTunnelRegistry {
         /**
          * attune based caps
          */
-        this.addNewAttunement(Capabilities.FORGE_ENERGY, TunnelType.FE_POWER);
-        this.addNewAttunement(CapabilityFluidHandler.FLUID_HANDLER_ITEM_CAPABILITY, TunnelType.FLUID);
+        // FIXME FABRIC this.addNewAttunement(Capabilities.FORGE_ENERGY, TunnelType.FE_POWER);
+        this.addNewAttunement(FluidAttributes.EXTRACTABLE, TunnelType.FLUID);
+        this.addNewAttunement(FluidAttributes.INSERTABLE, TunnelType.FLUID);
+        this.addNewAttunement(FluidAttributes.FIXED_INV, TunnelType.FLUID);
+        this.addNewAttunement(FluidAttributes.GROUPED_INV, TunnelType.FLUID);
 
         /**
          * attune based on the ItemStack's modId
@@ -186,11 +188,11 @@ public final class P2PTunnelRegistry implements IP2PTunnelRegistry {
     }
 
     @Override
-    public void addNewAttunement(@Nonnull final Capability cap, @Nullable final TunnelType type) {
-        if (type == null || cap == null) {
+    public void addNewAttunement(@Nonnull final Attribute attr, @Nullable final TunnelType type) {
+        if (type == null || attr == null) {
             return;
         }
-        this.capTunnels.put(cap, type);
+        this.attrTunnels.put(attr, type);
     }
 
     @Override
@@ -220,18 +222,20 @@ public final class P2PTunnelRegistry implements IP2PTunnelRegistry {
             }
 
             // Next, check if the Item you're holding supports any registered capability
-            for (Direction face : Direction.values()) {
-                for (Entry, TunnelType> entry : this.capTunnels.entrySet()) {
-                    if (trigger.getCapability(entry.getKey(), face).isPresent()) {
-                        return entry.getValue();
-                    }
+            for (Entry, TunnelType> entry : this.attrTunnels.entrySet()) {
+                if (entry.getKey().getFirstOrNull(trigger) != null) {
+                    return entry.getValue();
                 }
             }
 
             // Use the mod id as last option.
+            Identifier itemId = Registry.ITEM.getId(trigger.getItem());
+            if (itemId == Registry.ITEM.getDefaultId()) {
+                return null; // Unregistered item
+            }
+
             for (final Entry entry : this.modIdTunnels.entrySet()) {
-                if (trigger.getItem().getRegistryName() != null
-                        && trigger.getItem().getRegistryName().getNamespace().equals(entry.getKey())) {
+                if (itemId.getNamespace().equals(entry.getKey())) {
                     return entry.getValue();
                 }
             }
@@ -243,14 +247,13 @@ public final class P2PTunnelRegistry implements IP2PTunnelRegistry {
     @Nonnull
     private ItemStack getModItem(final String modID, final String name) {
 
-        final Item item = ForgeRegistries.ITEMS.getValue(new Identifier(modID + ":" + name));
+        final Item item = Registry.ITEM.getOrEmpty(new Identifier(modID, name)).orElse(null);
 
         if (item == null) {
             return ItemStack.EMPTY;
         }
 
-        final ItemStack myItemStack = new ItemStack(item, 1);
-        return myItemStack;
+        return new ItemStack(item);
     }
 
     private void addNewAttunement(final IItemDefinition definition, final TunnelType type) {
diff --git a/src/main/java/appeng/core/features/registries/PartModels.java b/core/src/main/java/appeng/core/features/registries/PartModels.java
similarity index 100%
rename from src/main/java/appeng/core/features/registries/PartModels.java
rename to core/src/main/java/appeng/core/features/registries/PartModels.java
diff --git a/src/main/java/appeng/core/features/registries/PlayerRegistry.java b/core/src/main/java/appeng/core/features/registries/PlayerRegistry.java
similarity index 92%
rename from src/main/java/appeng/core/features/registries/PlayerRegistry.java
rename to core/src/main/java/appeng/core/features/registries/PlayerRegistry.java
index b300ce995..3ea7f1c5b 100644
--- a/src/main/java/appeng/core/features/registries/PlayerRegistry.java
+++ b/core/src/main/java/appeng/core/features/registries/PlayerRegistry.java
@@ -54,8 +54,8 @@ public class PlayerRegistry implements IPlayerRegistry {
             return null;
         }
 
-        for (final PlayerEntity player : AppEng.proxy.getPlayers()) {
-            if (player.getUniqueID().equals(profileId)) {
+        for (final PlayerEntity player : AppEng.instance().getPlayers()) {
+            if (player.getGameProfile().getId().equals(profileId)) {
                 return player;
             }
         }
diff --git a/src/main/java/appeng/core/features/registries/RegistryContainer.java b/core/src/main/java/appeng/core/features/registries/RegistryContainer.java
similarity index 100%
rename from src/main/java/appeng/core/features/registries/RegistryContainer.java
rename to core/src/main/java/appeng/core/features/registries/RegistryContainer.java
diff --git a/src/main/java/appeng/core/features/registries/WirelessRegistry.java b/core/src/main/java/appeng/core/features/registries/WirelessRegistry.java
similarity index 92%
rename from src/main/java/appeng/core/features/registries/WirelessRegistry.java
rename to core/src/main/java/appeng/core/features/registries/WirelessRegistry.java
index 9d7a14aaa..db8ecc95e 100644
--- a/src/main/java/appeng/core/features/registries/WirelessRegistry.java
+++ b/core/src/main/java/appeng/core/features/registries/WirelessRegistry.java
@@ -31,9 +31,6 @@ import appeng.api.AEApi;
 import appeng.api.features.ILocatable;
 import appeng.api.features.IWirelessTermHandler;
 import appeng.api.features.IWirelessTermRegistry;
-import appeng.container.ContainerLocator;
-import appeng.container.ContainerOpener;
-import appeng.container.implementations.WirelessTermContainer;
 import appeng.core.localization.PlayerMessages;
 import appeng.util.Platform;
 
@@ -97,7 +94,8 @@ public final class WirelessRegistry implements IWirelessTermRegistry {
         }
 
         if (handler.hasPower(player, 0.5, item)) {
-            ContainerOpener.openContainer(WirelessTermContainer.TYPE, player, ContainerLocator.forHand(player, hand));
+            // FIXME FABRIC ContainerOpener.openContainer(WirelessTermContainer.TYPE, player, ContainerLocator.forHand(player, hand));
+            throw new IllegalStateException();
         } else {
             player.sendSystemMessage(PlayerMessages.DeviceNotPowered.get(), Util.NIL_UUID);
         }
diff --git a/src/main/java/appeng/core/features/registries/WorldGenRegistry.java b/core/src/main/java/appeng/core/features/registries/WorldGenRegistry.java
similarity index 76%
rename from src/main/java/appeng/core/features/registries/WorldGenRegistry.java
rename to core/src/main/java/appeng/core/features/registries/WorldGenRegistry.java
index 84c5e327e..79b8bbbcc 100644
--- a/src/main/java/appeng/core/features/registries/WorldGenRegistry.java
+++ b/core/src/main/java/appeng/core/features/registries/WorldGenRegistry.java
@@ -18,13 +18,11 @@
 
 package appeng.core.features.registries;
 
-import java.util.HashSet;
-
-import net.minecraft.util.Identifier;
-import net.minecraft.world.WorldAccess;
-import net.minecraft.world.dimension.DimensionType;
-
 import appeng.api.features.IWorldGen;
+import net.minecraft.server.world.ServerWorld;
+import net.minecraft.util.Identifier;
+
+import java.util.HashSet;
 
 public final class WorldGenRegistry implements IWorldGen {
 
@@ -40,19 +38,6 @@ public final class WorldGenRegistry implements IWorldGen {
         }
     }
 
-    @Override
-    public void disableWorldGenForProviderID(WorldGenType type, Class provider) {
-        if (type == null) {
-            throw new IllegalArgumentException("Bad Type Passed");
-        }
-
-        if (provider == null) {
-            throw new IllegalArgumentException("Bad Provider Passed");
-        }
-
-        this.types[type.ordinal()].badProviders.add(provider);
-    }
-
     @Override
     public void enableWorldGenForDimension(final WorldGenType type, final Identifier dimensionID) {
         if (type == null) {
@@ -72,7 +57,7 @@ public final class WorldGenRegistry implements IWorldGen {
     }
 
     @Override
-    public boolean isWorldGenEnabled(final WorldGenType type, final WorldAccess w) {
+    public boolean isWorldGenEnabled(final WorldGenType type, final ServerWorld w) {
         if (type == null) {
             throw new IllegalArgumentException("Bad Type Passed");
         }
@@ -81,12 +66,11 @@ public final class WorldGenRegistry implements IWorldGen {
             throw new IllegalArgumentException("Bad Provider Passed");
         }
 
-        Identifier id = w.getDimension().getType().getRegistryName();
-        final boolean isBadProvider = this.types[type.ordinal()].badProviders.contains(w.getDimension().getClass());
+        Identifier id = w.getDimensionRegistryKey().getValue();
         final boolean isBadDimension = this.types[type.ordinal()].badDimensions.contains(id);
         final boolean isGoodDimension = this.types[type.ordinal()].enabledDimensions.contains(id);
 
-        if (isBadProvider || isBadDimension) {
+        if (isBadDimension) {
             return false;
         }
 
@@ -98,8 +82,6 @@ public final class WorldGenRegistry implements IWorldGen {
     }
 
     private static class TypeSet {
-
-        final HashSet> badProviders = new HashSet<>();
         final HashSet badDimensions = new HashSet<>();
         final HashSet enabledDimensions = new HashSet<>();
     }
diff --git a/src/main/java/appeng/core/features/registries/cell/BasicCellHandler.java b/core/src/main/java/appeng/core/features/registries/cell/BasicCellHandler.java
similarity index 100%
rename from src/main/java/appeng/core/features/registries/cell/BasicCellHandler.java
rename to core/src/main/java/appeng/core/features/registries/cell/BasicCellHandler.java
diff --git a/src/main/java/appeng/core/features/registries/cell/BasicItemCellGuiHandler.java b/core/src/main/java/appeng/core/features/registries/cell/BasicItemCellGuiHandler.java
similarity index 77%
rename from src/main/java/appeng/core/features/registries/cell/BasicItemCellGuiHandler.java
rename to core/src/main/java/appeng/core/features/registries/cell/BasicItemCellGuiHandler.java
index fd19c8e3c..097bfb9b2 100644
--- a/src/main/java/appeng/core/features/registries/cell/BasicItemCellGuiHandler.java
+++ b/core/src/main/java/appeng/core/features/registries/cell/BasicItemCellGuiHandler.java
@@ -13,9 +13,6 @@ import appeng.api.storage.cells.ICellGuiHandler;
 import appeng.api.storage.cells.ICellHandler;
 import appeng.api.storage.channels.IItemStorageChannel;
 import appeng.api.storage.data.IAEStack;
-import appeng.container.ContainerLocator;
-import appeng.container.ContainerOpener;
-import appeng.container.implementations.MEMonitorableContainer;
 
 public class BasicItemCellGuiHandler implements ICellGuiHandler {
     @Override
@@ -26,7 +23,7 @@ public class BasicItemCellGuiHandler implements ICellGuiHandler {
     @Override
     public void openChestGui(final PlayerEntity player, final IChestOrDrive chest, final ICellHandler cellHandler,
             final IMEInventoryHandler inv, final ItemStack is, final IStorageChannel chan) {
-        ContainerOpener.openContainer(MEMonitorableContainer.TYPE, player,
-                ContainerLocator.forTileEntitySide((BlockEntity) chest, chest.getUp()));
+   // FIXME FABRIC     ContainerOpener.openContainer(MEMonitorableContainer.TYPE, player,
+   // FIXME FABRIC             ContainerLocator.forTileEntitySide((BlockEntity) chest, chest.getUp()));
     }
 }
diff --git a/src/main/java/appeng/core/features/registries/cell/CellRegistry.java b/core/src/main/java/appeng/core/features/registries/cell/CellRegistry.java
similarity index 100%
rename from src/main/java/appeng/core/features/registries/cell/CellRegistry.java
rename to core/src/main/java/appeng/core/features/registries/cell/CellRegistry.java
diff --git a/src/main/java/appeng/core/features/registries/cell/CreativeCellHandler.java b/core/src/main/java/appeng/core/features/registries/cell/CreativeCellHandler.java
similarity index 100%
rename from src/main/java/appeng/core/features/registries/cell/CreativeCellHandler.java
rename to core/src/main/java/appeng/core/features/registries/cell/CreativeCellHandler.java
diff --git a/src/main/java/appeng/core/features/registries/charger/ChargerRegistry.java b/core/src/main/java/appeng/core/features/registries/charger/ChargerRegistry.java
similarity index 100%
rename from src/main/java/appeng/core/features/registries/charger/ChargerRegistry.java
rename to core/src/main/java/appeng/core/features/registries/charger/ChargerRegistry.java
diff --git a/core/src/main/java/appeng/decorative/solid/AEStairsBlock.java b/core/src/main/java/appeng/decorative/solid/AEStairsBlock.java
new file mode 100644
index 000000000..6511bb1cf
--- /dev/null
+++ b/core/src/main/java/appeng/decorative/solid/AEStairsBlock.java
@@ -0,0 +1,12 @@
+package appeng.decorative.solid;
+
+import net.minecraft.block.BlockState;
+import net.minecraft.block.StairsBlock;
+
+public class AEStairsBlock extends StairsBlock {
+
+    public AEStairsBlock(BlockState baseBlockState, Settings settings) {
+        super(baseBlockState, settings);
+    }
+
+}
diff --git a/core/src/main/java/appeng/decorative/solid/ChargedQuartzOreBlock.java b/core/src/main/java/appeng/decorative/solid/ChargedQuartzOreBlock.java
index 6696c6dad..6d64c5ee5 100644
--- a/core/src/main/java/appeng/decorative/solid/ChargedQuartzOreBlock.java
+++ b/core/src/main/java/appeng/decorative/solid/ChargedQuartzOreBlock.java
@@ -71,7 +71,7 @@ public class ChargedQuartzOreBlock extends QuartzOreBlock {
                 break;
         }
 
-        if (AppEng.INSTANCE.shouldAddParticles(r)) {
+        if (AppEng.instance().shouldAddParticles(r)) {
             MinecraftClient.getInstance().particleManager.addParticle(ParticleTypes.CHARGED_ORE, pos.getX() + xOff,
                     pos.getY() + yOff, pos.getZ() + zOff, 0.0f, 0.0f, 0.0f);
         }
diff --git a/core/src/main/java/appeng/decorative/solid/QuartzLampBlock.java b/core/src/main/java/appeng/decorative/solid/QuartzLampBlock.java
index a5cc258aa..0725ed298 100644
--- a/core/src/main/java/appeng/decorative/solid/QuartzLampBlock.java
+++ b/core/src/main/java/appeng/decorative/solid/QuartzLampBlock.java
@@ -43,7 +43,7 @@ public class QuartzLampBlock extends QuartzGlassBlock {
             return;
         }
 
-        if (AppEng.INSTANCE.shouldAddParticles(r)) {
+        if (AppEng.instance().shouldAddParticles(r)) {
             final double d0 = (r.nextFloat() - 0.5F) * 0.96D;
             final double d1 = (r.nextFloat() - 0.5F) * 0.96D;
             final double d2 = (r.nextFloat() - 0.5F) * 0.96D;
diff --git a/src/main/java/appeng/fluids/util/FluidList.java b/core/src/main/java/appeng/fluids/util/FluidList.java
similarity index 100%
rename from src/main/java/appeng/fluids/util/FluidList.java
rename to core/src/main/java/appeng/fluids/util/FluidList.java
diff --git a/src/main/java/appeng/fluids/util/MeaningfulFluidIterator.java b/core/src/main/java/appeng/fluids/util/MeaningfulFluidIterator.java
similarity index 100%
rename from src/main/java/appeng/fluids/util/MeaningfulFluidIterator.java
rename to core/src/main/java/appeng/fluids/util/MeaningfulFluidIterator.java
diff --git a/core/src/main/java/appeng/hooks/AEToolItem.java b/core/src/main/java/appeng/hooks/AEToolItem.java
new file mode 100644
index 000000000..5896332e3
--- /dev/null
+++ b/core/src/main/java/appeng/hooks/AEToolItem.java
@@ -0,0 +1,9 @@
+package appeng.hooks;
+
+import net.minecraft.item.ItemStack;
+import net.minecraft.item.ItemUsageContext;
+import net.minecraft.util.ActionResult;
+
+public interface AEToolItem {
+    ActionResult onItemUseFirst(ItemStack stack, ItemUsageContext context);
+}
diff --git a/src/main/java/appeng/hooks/TinyTNTDispenseItemBehavior.java b/core/src/main/java/appeng/hooks/TinyTNTDispenseItemBehavior.java
similarity index 85%
rename from src/main/java/appeng/hooks/TinyTNTDispenseItemBehavior.java
rename to core/src/main/java/appeng/hooks/TinyTNTDispenseItemBehavior.java
index d936366db..7458b1c53 100644
--- a/src/main/java/appeng/hooks/TinyTNTDispenseItemBehavior.java
+++ b/core/src/main/java/appeng/hooks/TinyTNTDispenseItemBehavior.java
@@ -19,18 +19,18 @@
 package appeng.hooks;
 
 import net.minecraft.block.DispenserBlock;
-import net.minecraft.dispenser.DefaultDispenseItemBehavior;
-import net.minecraft.dispenser.IBlockSource;
+import net.minecraft.block.dispenser.ItemDispenserBehavior;
+import net.minecraft.util.math.BlockPointer;
 import net.minecraft.item.ItemStack;
 import net.minecraft.util.math.Direction;
 import net.minecraft.world.World;
 
 import appeng.entity.TinyTNTPrimedEntity;
 
-public final class TinyTNTDispenseItemBehavior extends DefaultDispenseItemBehavior {
+public final class TinyTNTDispenseItemBehavior extends ItemDispenserBehavior {
 
     @Override
-    protected ItemStack dispenseStack(final IBlockSource dispenser, final ItemStack dispensedItem) {
+    protected ItemStack dispenseSilently(final BlockPointer dispenser, final ItemStack dispensedItem) {
         final Direction Direction = dispenser.getBlockState().get(DispenserBlock.FACING);
         final World world = dispenser.getWorld();
         final int i = dispenser.getBlockPos().getX() + Direction.getOffsetX();
diff --git a/core/src/main/java/appeng/hooks/ToolItemHook.java b/core/src/main/java/appeng/hooks/ToolItemHook.java
new file mode 100644
index 000000000..679a060ae
--- /dev/null
+++ b/core/src/main/java/appeng/hooks/ToolItemHook.java
@@ -0,0 +1,40 @@
+package appeng.hooks;
+
+import net.fabricmc.fabric.api.event.player.UseBlockCallback;
+import net.minecraft.entity.player.PlayerEntity;
+import net.minecraft.item.Item;
+import net.minecraft.item.ItemStack;
+import net.minecraft.item.ItemUsageContext;
+import net.minecraft.util.ActionResult;
+import net.minecraft.util.Hand;
+import net.minecraft.util.hit.BlockHitResult;
+import net.minecraft.world.World;
+
+/**
+ * This hooks allows item-specific behavior to be triggered when an item is used on a block,
+ * without shift being held or the block being called first.
+ */
+public class ToolItemHook {
+
+    public static void install() {
+        UseBlockCallback.EVENT.register(ToolItemHook::handleItemUse);
+    }
+
+    private static ActionResult handleItemUse(PlayerEntity playerEntity, World world, Hand hand, BlockHitResult blockHitResult) {
+
+        if (playerEntity.isSpectator()) {
+            return ActionResult.PASS;
+        }
+
+        ItemStack itemStack = playerEntity.getStackInHand(hand);
+        Item item = itemStack.getItem();
+        if (item instanceof AEToolItem) {
+            ItemUsageContext context = new ItemUsageContext(playerEntity, hand, blockHitResult);
+            AEToolItem toolItem = (AEToolItem) item;
+            return toolItem.onItemUseFirst(itemStack, context);
+        }
+
+        return ActionResult.PASS;
+    }
+
+}
diff --git a/src/main/java/appeng/items/contents/CellConfig.java b/core/src/main/java/appeng/items/contents/CellConfig.java
similarity index 88%
rename from src/main/java/appeng/items/contents/CellConfig.java
rename to core/src/main/java/appeng/items/contents/CellConfig.java
index 32d317487..b53c6044a 100644
--- a/src/main/java/appeng/items/contents/CellConfig.java
+++ b/core/src/main/java/appeng/items/contents/CellConfig.java
@@ -18,6 +18,7 @@
 
 package appeng.items.contents;
 
+import alexiil.mc.lib.attributes.item.FixedItemInvView;
 import net.minecraft.item.ItemStack;
 
 import appeng.tile.inventory.AppEngInternalInventory;
@@ -33,7 +34,7 @@ public class CellConfig extends AppEngInternalInventory {
     }
 
     @Override
-    protected void onContentsChanged(int slot) {
+    protected void onContentsChanged(FixedItemInvView inv, int slot, ItemStack previous, ItemStack current) {
         this.writeToNBT(this.is.getOrCreateTag(), "list");
     }
 }
\ No newline at end of file
diff --git a/src/main/java/appeng/items/materials/MaterialItem.java b/core/src/main/java/appeng/items/materials/MaterialItem.java
similarity index 82%
rename from src/main/java/appeng/items/materials/MaterialItem.java
rename to core/src/main/java/appeng/items/materials/MaterialItem.java
index 248c823eb..0ce1d75af 100644
--- a/src/main/java/appeng/items/materials/MaterialItem.java
+++ b/core/src/main/java/appeng/items/materials/MaterialItem.java
@@ -25,9 +25,8 @@ import java.util.Map.Entry;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
+import appeng.hooks.AEToolItem;
 import net.minecraft.client.item.TooltipContext;
-import net.minecraft.entity.Entity;
-import net.minecraft.entity.ItemEntity;
 import net.minecraft.entity.player.PlayerEntity;
 import net.minecraft.item.ItemStack;
 import net.minecraft.item.ItemUsageContext;
@@ -38,6 +37,7 @@ import net.minecraft.util.ActionResult;
 import net.minecraft.util.Hand;
 import net.minecraft.text.Text;
 import net.minecraft.text.TranslatableText;
+import net.minecraft.util.TypedActionResult;
 import net.minecraft.world.World;
 import net.fabricmc.api.EnvType;
 import net.fabricmc.api.Environment;
@@ -55,7 +55,7 @@ import appeng.items.AEBaseItem;
 import appeng.util.InventoryAdaptor;
 import appeng.util.inv.AdaptorFixedInv;
 
-public final class MaterialItem extends AEBaseItem implements IStorageComponent, IUpgradeModule {
+public final class MaterialItem extends AEBaseItem implements IStorageComponent, IUpgradeModule, AEToolItem {
 
     /**
      * NBT property used by the name press to store the name to be inscribed.
@@ -101,7 +101,7 @@ public final class MaterialItem extends AEBaseItem implements IStorageComponent,
                 }
 
                 if (name == null) {
-                    name = j.getKey().getName().append((limit > 1 ? " (" + limit + ')' : ""));
+                    name = j.getKey().getName().copy().append((limit > 1 ? " (" + limit + ')' : ""));
                 }
 
                 if (!textList.contains(name)) {
@@ -137,6 +137,11 @@ public final class MaterialItem extends AEBaseItem implements IStorageComponent,
         }
     }
 
+    @Override
+    public TypedActionResult use(World world, PlayerEntity user, Hand hand) {
+        return super.use(world, user, hand);
+    }
+
     @Override
     public ActionResult onItemUseFirst(ItemStack stack, ItemUsageContext context) {
         PlayerEntity player = context.getPlayer();
@@ -146,7 +151,7 @@ public final class MaterialItem extends AEBaseItem implements IStorageComponent,
             FixedItemInv upgrades = null;
 
             if (te instanceof IPartHost) {
-                final SelectedPart sp = ((IPartHost) te).selectPart(context.getHitVec());
+                final SelectedPart sp = ((IPartHost) te).selectPart(context.getHitPos());
                 if (sp.part instanceof IUpgradeableHost) {
                     upgrades = ((ISegmentedInventory) sp.part).getInventoryByName("upgrades");
                 }
@@ -165,40 +170,40 @@ public final class MaterialItem extends AEBaseItem implements IStorageComponent,
                     }
 
                     final InventoryAdaptor ad = new AdaptorFixedInv(upgrades);
-                    player.setHeldItem(hand, ad.addItems(player.getStackInHand(hand)));
+                    player.setStackInHand(hand, ad.addItems(player.getStackInHand(hand)));
                     return ActionResult.SUCCESS;
                 }
             }
         }
 
-        return super.onItemUseFirst(stack, context);
+        return ActionResult.PASS;
     }
 
-    @Override
-    public boolean hasCustomEntity(final ItemStack is) {
-        return materialType.hasCustomEntity();
-    }
+// FIXME FABRIC    @Override
+// FIXME FABRIC    public boolean hasCustomEntity(final ItemStack is) {
+// FIXME FABRIC        return materialType.hasCustomEntity();
+// FIXME FABRIC    }
 
-    @Override
-    public Entity createEntity(final World w, final Entity location, final ItemStack itemstack) {
-        final Class droppedEntity = materialType.getCustomEntityClass();
-        final Entity eqi;
+// FIXME FABRIC    @Override
+// FIXME FABRIC    public Entity createEntity(final World w, final Entity location, final ItemStack itemstack) {
+// FIXME FABRIC        final Class droppedEntity = materialType.getCustomEntityClass();
+// FIXME FABRIC        final Entity eqi;
 
-        try {
-            eqi = droppedEntity.getConstructor(World.class, double.class, double.class, double.class, ItemStack.class)
-                    .newInstance(w, location.getX(), location.getY(), location.getZ(), itemstack);
-        } catch (final Throwable t) {
-            throw new IllegalStateException(t);
-        }
+// FIXME FABRIC        try {
+// FIXME FABRIC            eqi = droppedEntity.getConstructor(World.class, double.class, double.class, double.class, ItemStack.class)
+// FIXME FABRIC                    .newInstance(w, location.getX(), location.getY(), location.getZ(), itemstack);
+// FIXME FABRIC        } catch (final Throwable t) {
+// FIXME FABRIC            throw new IllegalStateException(t);
+// FIXME FABRIC        }
 
-        eqi.setVelocity(location.getVelocity());
+// FIXME FABRIC        eqi.setVelocity(location.getVelocity());
 
-        if (location instanceof ItemEntity && eqi instanceof ItemEntity) {
-            ((ItemEntity) eqi).setDefaultPickupDelay();
-        }
+// FIXME FABRIC        if (location instanceof ItemEntity && eqi instanceof ItemEntity) {
+// FIXME FABRIC            ((ItemEntity) eqi).setDefaultPickupDelay();
+// FIXME FABRIC        }
 
-        return eqi;
-    }
+// FIXME FABRIC        return eqi;
+// FIXME FABRIC    }
 
     @Override
     public int getBytes(final ItemStack is) {
diff --git a/src/main/java/appeng/items/storage/CreativeStorageCellItem.java b/core/src/main/java/appeng/items/storage/CreativeStorageCellItem.java
similarity index 100%
rename from src/main/java/appeng/items/storage/CreativeStorageCellItem.java
rename to core/src/main/java/appeng/items/storage/CreativeStorageCellItem.java
diff --git a/src/main/java/appeng/me/storage/AbstractCellInventory.java b/core/src/main/java/appeng/me/storage/AbstractCellInventory.java
similarity index 100%
rename from src/main/java/appeng/me/storage/AbstractCellInventory.java
rename to core/src/main/java/appeng/me/storage/AbstractCellInventory.java
diff --git a/src/main/java/appeng/me/storage/BasicCellInventory.java b/core/src/main/java/appeng/me/storage/BasicCellInventory.java
similarity index 100%
rename from src/main/java/appeng/me/storage/BasicCellInventory.java
rename to core/src/main/java/appeng/me/storage/BasicCellInventory.java
diff --git a/src/main/java/appeng/me/storage/BasicCellInventoryHandler.java b/core/src/main/java/appeng/me/storage/BasicCellInventoryHandler.java
similarity index 100%
rename from src/main/java/appeng/me/storage/BasicCellInventoryHandler.java
rename to core/src/main/java/appeng/me/storage/BasicCellInventoryHandler.java
diff --git a/src/main/java/appeng/me/storage/CreativeCellInventory.java b/core/src/main/java/appeng/me/storage/CreativeCellInventory.java
similarity index 100%
rename from src/main/java/appeng/me/storage/CreativeCellInventory.java
rename to core/src/main/java/appeng/me/storage/CreativeCellInventory.java
diff --git a/src/main/java/appeng/me/storage/MEInventoryHandler.java b/core/src/main/java/appeng/me/storage/MEInventoryHandler.java
similarity index 100%
rename from src/main/java/appeng/me/storage/MEInventoryHandler.java
rename to core/src/main/java/appeng/me/storage/MEInventoryHandler.java
diff --git a/src/main/java/appeng/me/storage/MEPassThrough.java b/core/src/main/java/appeng/me/storage/MEPassThrough.java
similarity index 100%
rename from src/main/java/appeng/me/storage/MEPassThrough.java
rename to core/src/main/java/appeng/me/storage/MEPassThrough.java
diff --git a/core/src/main/java/appeng/mixins/CriteriaRegisterMixin.java b/core/src/main/java/appeng/mixins/CriteriaRegisterMixin.java
new file mode 100644
index 000000000..64d7e6fe1
--- /dev/null
+++ b/core/src/main/java/appeng/mixins/CriteriaRegisterMixin.java
@@ -0,0 +1,16 @@
+package appeng.mixins;
+
+import net.minecraft.advancement.criterion.Criteria;
+import net.minecraft.advancement.criterion.Criterion;
+import org.spongepowered.asm.mixin.Mixin;
+import org.spongepowered.asm.mixin.gen.Invoker;
+
+@Mixin(Criteria.class)
+public interface CriteriaRegisterMixin {
+
+    @Invoker("register")
+    static > T callRegister(T object) {
+        throw new AssertionError("Mixin dummy");
+    }
+
+}
diff --git a/src/main/java/appeng/spatial/DefaultSpatialHandler.java b/core/src/main/java/appeng/spatial/DefaultSpatialHandler.java
similarity index 83%
rename from src/main/java/appeng/spatial/DefaultSpatialHandler.java
rename to core/src/main/java/appeng/spatial/DefaultSpatialHandler.java
index 1c9e2cd3f..72a490ff5 100644
--- a/src/main/java/appeng/spatial/DefaultSpatialHandler.java
+++ b/core/src/main/java/appeng/spatial/DefaultSpatialHandler.java
@@ -21,6 +21,7 @@ package appeng.spatial;
 import net.minecraft.block.BlockState;
 import net.minecraft.block.entity.BlockEntity;
 import net.minecraft.util.math.BlockPos;
+import net.minecraft.util.math.ChunkPos;
 import net.minecraft.world.World;
 import net.minecraft.world.chunk.Chunk;
 
@@ -42,14 +43,15 @@ public class DefaultSpatialHandler implements IMovableHandler {
 
     @Override
     public void moveTile(final BlockEntity te, final World w, final BlockPos newPosition) {
-        te.setWorldAndPos(w, newPosition);
+        te.setLocation(w, newPosition);
 
-        final Chunk c = w.getChunkAt(newPosition);
-        c.addTileEntity(newPosition, te);
+        final Chunk c = w.getChunk(newPosition);
+        c.setBlockEntity(newPosition, te);
 
-        if (w.getChunkManager().isChunkLoaded(c.getPos())) {
+        ChunkPos chunkPos = c.getPos();
+        if (w.getChunkManager().isChunkLoaded(chunkPos.x, chunkPos.z)) {
             final BlockState state = w.getBlockState(newPosition);
-            w.addTileEntity(te);
+            w.addBlockEntity(te);
             w.updateListeners(newPosition, state, state, 1);
         }
     }
diff --git a/core/src/main/java/appeng/tile/AEBaseBlockEntity.java b/core/src/main/java/appeng/tile/AEBaseBlockEntity.java
index cbd1f8ee6..f3ff32e4c 100644
--- a/core/src/main/java/appeng/tile/AEBaseBlockEntity.java
+++ b/core/src/main/java/appeng/tile/AEBaseBlockEntity.java
@@ -35,7 +35,6 @@ import appeng.helpers.IPriorityHost;
 import appeng.tile.inventory.AppEngInternalAEInventory;
 import appeng.util.Platform;
 import appeng.util.SettingsFrom;
-import com.sun.org.apache.bcel.internal.classfile.AttributeReader;
 import io.netty.buffer.Unpooled;
 import net.fabricmc.fabric.api.block.entity.BlockEntityClientSerializable;
 import net.fabricmc.fabric.api.rendering.data.v1.RenderAttachmentBlockEntity;
diff --git a/core/src/main/resources/appliedenergistics2.mixins.json b/core/src/main/resources/appliedenergistics2.mixins.json
index 5539fae45..1d27e061c 100644
--- a/core/src/main/resources/appliedenergistics2.mixins.json
+++ b/core/src/main/resources/appliedenergistics2.mixins.json
@@ -3,7 +3,9 @@
   "minVersion": "0.8",
   "package": "appeng.mixins",
   "compatibilityLevel": "JAVA_8",
-  "mixins": [],
+  "mixins": [
+    "CriteriaRegisterMixin"
+  ],
   "client": [
     "ModelsReloadMixin"
   ],
diff --git a/core/src/main/resources/fabric.mod.json b/core/src/main/resources/fabric.mod.json
index d926743b2..a0da82883 100644
--- a/core/src/main/resources/fabric.mod.json
+++ b/core/src/main/resources/fabric.mod.json
@@ -19,6 +19,9 @@
   "environment": "*",
   "entrypoints": {
     "main": [
+    ],
+    "client": [
+      "appeng.core.AppEngClientStartup"
     ]
   },
   "mixins": [
diff --git a/src/main/java/appeng/block/paint/PaintSplotchesBakedModel.java b/src/main/java/appeng/block/paint/PaintSplotchesBakedModel.java
index b3e1f1dd2..bfaede0fd 100644
--- a/src/main/java/appeng/block/paint/PaintSplotchesBakedModel.java
+++ b/src/main/java/appeng/block/paint/PaintSplotchesBakedModel.java
@@ -15,7 +15,7 @@ import com.google.common.collect.ImmutableList;
 import net.minecraft.block.BlockState;
 import net.minecraft.client.render.model.BakedQuad;
 import net.minecraft.client.render.model.json.ModelOverrideList;
-import net.minecraft.client.render.model.Material;
+import net.minecraft.client.util.SpriteIdentifier;
 import net.minecraft.client.texture.SpriteAtlasTexture;
 import net.minecraft.client.texture.Sprite;
 import net.minecraft.util.Identifier;
@@ -35,16 +35,16 @@ import appeng.tile.misc.PaintSplotchesBlockEntity;
  */
 class PaintSplotchesBakedModel implements IDynamicBakedModel {
 
-    private static final Material TEXTURE_PAINT1 = new Material(SpriteAtlasTexture.BLOCK_ATLAS_TEX,
+    private static final SpriteIdentifier TEXTURE_PAINT1 = new SpriteIdentifier(SpriteAtlasTexture.BLOCK_ATLAS_TEX,
             new Identifier(AppEng.MOD_ID, "block/paint1"));
-    private static final Material TEXTURE_PAINT2 = new Material(SpriteAtlasTexture.BLOCK_ATLAS_TEX,
+    private static final SpriteIdentifier TEXTURE_PAINT2 = new SpriteIdentifier(SpriteAtlasTexture.BLOCK_ATLAS_TEX,
             new Identifier(AppEng.MOD_ID, "block/paint2"));
-    private static final Material TEXTURE_PAINT3 = new Material(SpriteAtlasTexture.BLOCK_ATLAS_TEX,
+    private static final SpriteIdentifier TEXTURE_PAINT3 = new SpriteIdentifier(SpriteAtlasTexture.BLOCK_ATLAS_TEX,
             new Identifier(AppEng.MOD_ID, "block/paint3"));
 
     private final Sprite[] textures;
 
-    PaintSplotchesBakedModel(Function bakedTextureGetter) {
+    PaintSplotchesBakedModel(Function bakedTextureGetter) {
         this.textures = new Sprite[] { bakedTextureGetter.apply(TEXTURE_PAINT1),
                 bakedTextureGetter.apply(TEXTURE_PAINT2), bakedTextureGetter.apply(TEXTURE_PAINT3) };
     }
@@ -171,7 +171,7 @@ class PaintSplotchesBakedModel implements IDynamicBakedModel {
         return false;
     }
 
-    static List getRequiredTextures() {
+    static List getRequiredTextures() {
         return ImmutableList.of(TEXTURE_PAINT1, TEXTURE_PAINT2, TEXTURE_PAINT3);
     }
 }
diff --git a/src/main/java/appeng/block/paint/PaintSplotchesModel.java b/src/main/java/appeng/block/paint/PaintSplotchesModel.java
index 37847a1b8..99f3710c1 100644
--- a/src/main/java/appeng/block/paint/PaintSplotchesModel.java
+++ b/src/main/java/appeng/block/paint/PaintSplotchesModel.java
@@ -11,7 +11,7 @@ import net.minecraft.client.render.model.BakedModel;
 import net.minecraft.client.render.model.IModelTransform;
 import net.minecraft.client.render.model.IUnbakedModel;
 import net.minecraft.client.render.model.json.ModelOverrideList;
-import net.minecraft.client.render.model.Material;
+import net.minecraft.client.util.SpriteIdentifier;
 import net.minecraft.client.render.model.ModelLoader;
 import net.minecraft.client.texture.Sprite;
 import net.minecraft.util.Identifier;
@@ -22,14 +22,14 @@ public class PaintSplotchesModel implements IModelGeometry
 
     @Override
     public BakedModel bake(IModelConfiguration owner, ModelLoader bakery,
-                           Function spriteGetter, IModelTransform modelTransform,
+                           Function spriteGetter, IModelTransform modelTransform,
                            ModelOverrideList overrides, Identifier modelLocation) {
         return new PaintSplotchesBakedModel(spriteGetter);
     }
 
     @Override
-    public Collection getTextures(IModelConfiguration owner,
-                                            Function modelGetter, Set> missingTextureErrors) {
+    public Collection getTextures(IModelConfiguration owner,
+                                                    Function modelGetter, Set> missingTextureErrors) {
         return PaintSplotchesBakedModel.getRequiredTextures();
     }
 
diff --git a/src/main/java/appeng/block/qnb/QnbFormedBakedModel.java b/src/main/java/appeng/block/qnb/QnbFormedBakedModel.java
index 807d10173..b32982f32 100644
--- a/src/main/java/appeng/block/qnb/QnbFormedBakedModel.java
+++ b/src/main/java/appeng/block/qnb/QnbFormedBakedModel.java
@@ -17,7 +17,7 @@ import net.minecraft.block.BlockState;
 import net.minecraft.client.render.model.BakedQuad;
 import net.minecraft.client.render.model.BakedModel;
 import net.minecraft.client.render.model.json.ModelOverrideList;
-import net.minecraft.client.render.model.Material;
+import net.minecraft.client.util.SpriteIdentifier;
 import net.minecraft.client.texture.SpriteAtlasTexture;
 import net.minecraft.client.texture.Sprite;
 import net.minecraft.util.Identifier;
@@ -32,17 +32,17 @@ import appeng.tile.qnb.QuantumBridgeBlockEntity;
 
 class QnbFormedBakedModel implements IDynamicBakedModel {
 
-    private static final Material TEXTURE_LINK = new Material(SpriteAtlasTexture.BLOCK_ATLAS_TEX,
+    private static final SpriteIdentifier TEXTURE_LINK = new SpriteIdentifier(SpriteAtlasTexture.BLOCK_ATLAS_TEX,
             new Identifier(AppEng.MOD_ID, "block/quantum_link"));
-    private static final Material TEXTURE_RING = new Material(SpriteAtlasTexture.BLOCK_ATLAS_TEX,
+    private static final SpriteIdentifier TEXTURE_RING = new SpriteIdentifier(SpriteAtlasTexture.BLOCK_ATLAS_TEX,
             new Identifier(AppEng.MOD_ID, "block/quantum_ring"));
-    private static final Material TEXTURE_RING_LIGHT = new Material(SpriteAtlasTexture.BLOCK_ATLAS_TEX,
+    private static final SpriteIdentifier TEXTURE_RING_LIGHT = new SpriteIdentifier(SpriteAtlasTexture.BLOCK_ATLAS_TEX,
             new Identifier(AppEng.MOD_ID, "block/quantum_ring_light"));
-    private static final Material TEXTURE_RING_LIGHT_CORNER = new Material(SpriteAtlasTexture.BLOCK_ATLAS_TEX,
+    private static final SpriteIdentifier TEXTURE_RING_LIGHT_CORNER = new SpriteIdentifier(SpriteAtlasTexture.BLOCK_ATLAS_TEX,
             new Identifier(AppEng.MOD_ID, "block/quantum_ring_light_corner"));
-    private static final Material TEXTURE_CABLE_GLASS = new Material(SpriteAtlasTexture.BLOCK_ATLAS_TEX,
+    private static final SpriteIdentifier TEXTURE_CABLE_GLASS = new SpriteIdentifier(SpriteAtlasTexture.BLOCK_ATLAS_TEX,
             new Identifier(AppEng.MOD_ID, "parts/cable/glass/transparent"));
-    private static final Material TEXTURE_COVERED_CABLE = new Material(SpriteAtlasTexture.BLOCK_ATLAS_TEX,
+    private static final SpriteIdentifier TEXTURE_COVERED_CABLE = new SpriteIdentifier(SpriteAtlasTexture.BLOCK_ATLAS_TEX,
             new Identifier(AppEng.MOD_ID, "parts/cable/covered/transparent"));
 
     private static final float DEFAULT_RENDER_MIN = 2.0f;
@@ -65,7 +65,7 @@ class QnbFormedBakedModel implements IDynamicBakedModel {
     private final Sprite lightTexture;
     private final Sprite lightCornerTexture;
 
-    public QnbFormedBakedModel(BakedModel baseModel, Function bakedTextureGetter) {
+    public QnbFormedBakedModel(BakedModel baseModel, Function bakedTextureGetter) {
         this.baseModel = baseModel;
         this.linkTexture = bakedTextureGetter.apply(TEXTURE_LINK);
         this.ringTexture = bakedTextureGetter.apply(TEXTURE_RING);
@@ -220,7 +220,7 @@ class QnbFormedBakedModel implements IDynamicBakedModel {
         return this.baseModel.getOverrides();
     }
 
-    public static List getRequiredTextures() {
+    public static List getRequiredTextures() {
         return ImmutableList.of(TEXTURE_LINK, TEXTURE_RING, TEXTURE_CABLE_GLASS, TEXTURE_COVERED_CABLE,
                 TEXTURE_RING_LIGHT, TEXTURE_RING_LIGHT_CORNER);
     }
diff --git a/src/main/java/appeng/block/qnb/QnbFormedModel.java b/src/main/java/appeng/block/qnb/QnbFormedModel.java
index 9b8639bca..068134569 100644
--- a/src/main/java/appeng/block/qnb/QnbFormedModel.java
+++ b/src/main/java/appeng/block/qnb/QnbFormedModel.java
@@ -11,7 +11,7 @@ import net.minecraft.client.render.model.BakedModel;
 import net.minecraft.client.render.model.IModelTransform;
 import net.minecraft.client.render.model.IUnbakedModel;
 import net.minecraft.client.render.model.json.ModelOverrideList;
-import net.minecraft.client.render.model.Material;
+import net.minecraft.client.util.SpriteIdentifier;
 import net.minecraft.client.render.model.ModelLoader;
 import net.minecraft.client.texture.Sprite;
 import net.minecraft.util.Identifier;
@@ -26,15 +26,15 @@ public class QnbFormedModel implements IModelGeometry {
 
     @Override
     public BakedModel bake(IModelConfiguration owner, ModelLoader bakery,
-                           Function spriteGetter, IModelTransform modelTransform,
+                           Function spriteGetter, IModelTransform modelTransform,
                            ModelOverrideList overrides, Identifier modelLocation) {
         BakedModel ringModel = bakery.getBakedModel(MODEL_RING, modelTransform, spriteGetter);
         return new QnbFormedBakedModel(ringModel, spriteGetter);
     }
 
     @Override
-    public Collection getTextures(IModelConfiguration owner,
-                                            Function modelGetter, Set> missingTextureErrors) {
+    public Collection getTextures(IModelConfiguration owner,
+                                                    Function modelGetter, Set> missingTextureErrors) {
         return QnbFormedBakedModel.getRequiredTextures();
     }
 
diff --git a/src/main/java/appeng/client/render/DummyFluidDispatcherBakedModel.java b/src/main/java/appeng/client/render/DummyFluidDispatcherBakedModel.java
index 691e4e00d..3691dfd6c 100644
--- a/src/main/java/appeng/client/render/DummyFluidDispatcherBakedModel.java
+++ b/src/main/java/appeng/client/render/DummyFluidDispatcherBakedModel.java
@@ -31,10 +31,10 @@ import com.google.common.collect.ImmutableList;
 import net.minecraft.block.BlockState;
 import net.minecraft.client.render.model.json.ModelOverrideList;
 import net.minecraft.client.texture.SpriteAtlasTexture;
+import net.minecraft.client.util.SpriteIdentifier;
 import net.minecraft.client.util.math.AffineTransformation;
 import net.minecraft.client.render.model.BakedQuad;
 import net.minecraft.client.render.model.BakedModel;
-import net.minecraft.client.render.model.Material;
 import net.minecraft.client.texture.Sprite;
 import net.minecraft.entity.LivingEntity;
 import net.minecraft.fluid.Fluids;
@@ -53,10 +53,10 @@ import appeng.fluids.items.FluidDummyItem;
  * Override List is used to accomplish this.
  */
 public class DummyFluidDispatcherBakedModel extends DelegateBakedModel {
-    private final Function bakedTextureGetter;
+    private final Function bakedTextureGetter;
 
     public DummyFluidDispatcherBakedModel(BakedModel baseModel,
-                                          Function bakedTextureGetter) {
+                                          Function bakedTextureGetter) {
         super(baseModel);
         this.bakedTextureGetter = bakedTextureGetter;
     }
@@ -101,7 +101,7 @@ public class DummyFluidDispatcherBakedModel extends DelegateBakedModel {
 
                 FluidAttributes attributes = fluidStack.getFluidKey().getAttributes();
                 Identifier stillTexture = attributes.getStillTexture(fluidStack);
-                Material stillMaterial = new Material(SpriteAtlasTexture.BLOCK_ATLAS_TEX, stillTexture);
+                SpriteIdentifier stillMaterial = new SpriteIdentifier(SpriteAtlasTexture.BLOCK_ATLAS_TEX, stillTexture);
                 Sprite sprite = DummyFluidDispatcherBakedModel.this.bakedTextureGetter.apply(stillMaterial);
                 if (sprite == null) {
                     return new DummyFluidBakedModel(ImmutableList.of());
diff --git a/src/main/java/appeng/client/render/DummyFluidItemModel.java b/src/main/java/appeng/client/render/DummyFluidItemModel.java
index be9bc786a..0fc0d5978 100644
--- a/src/main/java/appeng/client/render/DummyFluidItemModel.java
+++ b/src/main/java/appeng/client/render/DummyFluidItemModel.java
@@ -29,7 +29,7 @@ import net.minecraft.client.render.model.BakedModel;
 import net.minecraft.client.render.model.IModelTransform;
 import net.minecraft.client.render.model.IUnbakedModel;
 import net.minecraft.client.render.model.json.ModelOverrideList;
-import net.minecraft.client.render.model.Material;
+import net.minecraft.client.util.SpriteIdentifier;
 import net.minecraft.client.render.model.ModelLoader;
 import net.minecraft.client.texture.Sprite;
 import net.minecraft.util.Identifier;
@@ -49,7 +49,7 @@ public class DummyFluidItemModel implements IModelGeometry
 
     @Override
     public BakedModel bake(IModelConfiguration owner, ModelLoader bakery,
-                           Function spriteGetter, IModelTransform modelTransform,
+                           Function spriteGetter, IModelTransform modelTransform,
                            ModelOverrideList overrides, Identifier modelLocation) {
         BakedModel bakedBaseModel = bakery.getBakedModel(MODEL_BASE, modelTransform, spriteGetter);
 
@@ -57,8 +57,8 @@ public class DummyFluidItemModel implements IModelGeometry
     }
 
     @Override
-    public Collection getTextures(IModelConfiguration owner,
-                                            Function modelGetter, Set> missingTextureErrors) {
+    public Collection getTextures(IModelConfiguration owner,
+                                                    Function modelGetter, Set> missingTextureErrors) {
         return Collections.emptyList();
     }
 
diff --git a/src/main/java/appeng/client/render/FacadeItemModel.java b/src/main/java/appeng/client/render/FacadeItemModel.java
index 7d0441247..f38398e0c 100644
--- a/src/main/java/appeng/client/render/FacadeItemModel.java
+++ b/src/main/java/appeng/client/render/FacadeItemModel.java
@@ -27,6 +27,7 @@ import com.mojang.datafixers.util.Pair;
 import net.minecraft.client.render.model.*;
 import net.minecraft.client.render.model.json.ModelOverrideList;
 import net.minecraft.client.texture.Sprite;
+import net.minecraft.client.util.SpriteIdentifier;
 import net.minecraft.util.Identifier;
 import net.minecraftforge.client.model.IModelConfiguration;
 import net.minecraftforge.client.model.geometry.IModelGeometry;
@@ -45,7 +46,7 @@ public class FacadeItemModel implements IModelGeometry {
 
     @Override
     public BakedModel bake(IModelConfiguration owner, ModelLoader bakery,
-                           Function spriteGetter, IModelTransform modelTransform,
+                           Function spriteGetter, IModelTransform modelTransform,
                            ModelOverrideList overrides, Identifier modelLocation) {
         BakedModel bakedBaseModel = bakery.getBakedModel(MODEL_BASE, modelTransform, spriteGetter);
         FacadeBuilder facadeBuilder = new FacadeBuilder();
@@ -54,8 +55,8 @@ public class FacadeItemModel implements IModelGeometry {
     }
 
     @Override
-    public Collection getTextures(IModelConfiguration owner,
-                                            Function modelGetter, Set> missingTextureErrors) {
+    public Collection getTextures(IModelConfiguration owner,
+                                                    Function modelGetter, Set> missingTextureErrors) {
         return modelGetter.apply(MODEL_BASE).getTextures(modelGetter, missingTextureErrors);
     }
 
diff --git a/src/main/java/appeng/client/render/SpatialSkyRender.java b/src/main/java/appeng/client/render/SpatialSkyRender.java
index a1ab5ca84..99a165537 100644
--- a/src/main/java/appeng/client/render/SpatialSkyRender.java
+++ b/src/main/java/appeng/client/render/SpatialSkyRender.java
@@ -27,7 +27,7 @@ import org.lwjgl.opengl.GL11;
 
 import net.minecraft.client.MinecraftClient;
 import net.minecraft.client.renderer.BufferBuilder;
-import net.minecraft.client.renderer.Quaternion;
+import net.minecraft.util.math.Quaternion;
 import net.minecraft.client.renderer.RenderHelper;
 import net.minecraft.client.renderer.Tessellator;
 import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
diff --git a/src/main/java/appeng/client/render/TesrRenderHelper.java b/src/main/java/appeng/client/render/TesrRenderHelper.java
index 31d2c72f8..fd6b7217f 100644
--- a/src/main/java/appeng/client/render/TesrRenderHelper.java
+++ b/src/main/java/appeng/client/render/TesrRenderHelper.java
@@ -127,7 +127,7 @@ public class TesrRenderHelper {
         matrixStack.scale(1.0f / 62.0f, -1.0f / 62.0f, 1.0f / 62.0f);
         matrixStack.scale(0.5f, 0.5f, 0);
         matrixStack.translate(-0.5f * width, 0.0f, 0.5f);
-        fr.renderString(renderedStackSize, 0, 0, -1, false, matrixStack.getLast().getMatrix(), buffers, false, 0,
+        fr.renderString(renderedStackSize, 0, 0, -1, false, matrixStack.peek().getMatrix(), buffers, false, 0,
                 15728880);
         matrixStack.pop();
 
diff --git a/src/main/java/appeng/client/render/cablebus/CableBuilder.java b/src/main/java/appeng/client/render/cablebus/CableBuilder.java
index b12a0da2f..5d4171c3d 100644
--- a/src/main/java/appeng/client/render/cablebus/CableBuilder.java
+++ b/src/main/java/appeng/client/render/cablebus/CableBuilder.java
@@ -26,7 +26,7 @@ import java.util.List;
 import java.util.function.Function;
 
 import net.minecraft.client.render.model.BakedQuad;
-import net.minecraft.client.render.model.Material;
+import net.minecraft.client.util.SpriteIdentifier;
 import net.minecraft.client.texture.SpriteAtlasTexture;
 import net.minecraft.client.texture.Sprite;
 import net.minecraft.util.math.Direction;
@@ -49,7 +49,7 @@ class CableBuilder {
 
     private final SmartCableTextures smartCableTextures;
 
-    CableBuilder(Function bakedTextureGetter) {
+    CableBuilder(Function bakedTextureGetter) {
         this.coreTextures = new EnumMap<>(CableCoreType.class);
 
         for (CableCoreType type : CableCoreType.values()) {
@@ -77,7 +77,7 @@ class CableBuilder {
         this.smartCableTextures = new SmartCableTextures(bakedTextureGetter);
     }
 
-    static Material getConnectionTexture(AECableType cableType, AEColor color) {
+    static SpriteIdentifier getConnectionTexture(AECableType cableType, AEColor color) {
         String textureFolder;
         switch (cableType) {
             case GLASS:
@@ -99,7 +99,7 @@ class CableBuilder {
                 throw new IllegalStateException("Cable type " + cableType + " does not support connections.");
         }
 
-        return new Material(SpriteAtlasTexture.BLOCK_ATLAS_TEX,
+        return new SpriteIdentifier(SpriteAtlasTexture.BLOCK_ATLAS_TEX,
                 new Identifier(AppEng.MOD_ID, textureFolder + color.name().toLowerCase()));
     }
 
@@ -701,8 +701,8 @@ class CableBuilder {
     }
 
     // Get all textures needed for building the actual cable quads
-    public static List getTextures() {
-        List locations = new ArrayList<>();
+    public static List getTextures() {
+        List locations = new ArrayList<>();
 
         for (CableCoreType coreType : CableCoreType.values()) {
             for (AEColor color : AEColor.values()) {
diff --git a/src/main/java/appeng/client/render/cablebus/CableBusModel.java b/src/main/java/appeng/client/render/cablebus/CableBusModel.java
index 3cfe4f09a..5a3c1c4a7 100644
--- a/src/main/java/appeng/client/render/cablebus/CableBusModel.java
+++ b/src/main/java/appeng/client/render/cablebus/CableBusModel.java
@@ -31,7 +31,7 @@ import net.minecraft.client.render.model.BakedModel;
 import net.minecraft.client.render.model.IModelTransform;
 import net.minecraft.client.render.model.IUnbakedModel;
 import net.minecraft.client.render.model.json.ModelOverrideList;
-import net.minecraft.client.render.model.Material;
+import net.minecraft.client.util.SpriteIdentifier;
 import net.minecraft.client.render.model.ModelLoader;
 import net.minecraft.client.texture.Sprite;
 import net.minecraft.util.Identifier;
@@ -55,7 +55,7 @@ public class CableBusModel implements IModelGeometry {
 
     @Override
     public BakedModel bake(IModelConfiguration owner, ModelLoader bakery,
-                           Function spriteGetter, IModelTransform modelTransform,
+                           Function spriteGetter, IModelTransform modelTransform,
                            ModelOverrideList overrides, Identifier modelLocation) {
         Map partModels = this.loadPartModels(bakery, spriteGetter, modelTransform);
 
@@ -71,13 +71,13 @@ public class CableBusModel implements IModelGeometry {
     }
 
     @Override
-    public Collection getTextures(IModelConfiguration owner,
-                                            Function modelGetter, Set> missingTextureErrors) {
+    public Collection getTextures(IModelConfiguration owner,
+                                                    Function modelGetter, Set> missingTextureErrors) {
         return Collections.unmodifiableList(CableBuilder.getTextures());
     }
 
     private Map loadPartModels(ModelLoader bakery,
-                                                       Function spriteGetterIn, IModelTransform transformIn) {
+                                                       Function spriteGetterIn, IModelTransform transformIn) {
         ImmutableMap.Builder result = ImmutableMap.builder();
 
         for (Identifier location : this.partModels.getModels()) {
diff --git a/src/main/java/appeng/client/render/cablebus/CableCoreType.java b/src/main/java/appeng/client/render/cablebus/CableCoreType.java
index 13cc76306..734895e4c 100644
--- a/src/main/java/appeng/client/render/cablebus/CableCoreType.java
+++ b/src/main/java/appeng/client/render/cablebus/CableCoreType.java
@@ -23,7 +23,7 @@ import java.util.Map;
 
 import com.google.common.collect.ImmutableMap;
 
-import net.minecraft.client.render.model.Material;
+import net.minecraft.client.util.SpriteIdentifier;
 import net.minecraft.client.texture.SpriteAtlasTexture;
 import net.minecraft.util.Identifier;
 
@@ -72,8 +72,8 @@ public enum CableCoreType {
         return cableMapping.get(cableType);
     }
 
-    public Material getTexture(AEColor color) {
-        return new Material(SpriteAtlasTexture.BLOCK_ATLAS_TEX,
+    public SpriteIdentifier getTexture(AEColor color) {
+        return new SpriteIdentifier(SpriteAtlasTexture.BLOCK_ATLAS_TEX,
                 new Identifier(AppEng.MOD_ID, this.textureFolder + "/" + color.name().toLowerCase()));
     }
 
diff --git a/src/main/java/appeng/client/render/cablebus/CubeBuilder.java b/src/main/java/appeng/client/render/cablebus/CubeBuilder.java
index 81e00fc32..a2159b819 100644
--- a/src/main/java/appeng/client/render/cablebus/CubeBuilder.java
+++ b/src/main/java/appeng/client/render/cablebus/CubeBuilder.java
@@ -25,7 +25,7 @@ import java.util.List;
 
 import com.google.common.base.Preconditions;
 
-import net.minecraft.client.renderer.Vector4f;
+import net.minecraft.client.util.math.Vector4f;
 import net.minecraft.client.render.model.BakedQuad;
 import net.minecraft.client.texture.Sprite;
 import net.minecraft.client.renderer.vertex.VertexFormat;
diff --git a/src/main/java/appeng/client/render/cablebus/P2PTunnelFrequencyModel.java b/src/main/java/appeng/client/render/cablebus/P2PTunnelFrequencyModel.java
index 0363493d1..147664fbb 100644
--- a/src/main/java/appeng/client/render/cablebus/P2PTunnelFrequencyModel.java
+++ b/src/main/java/appeng/client/render/cablebus/P2PTunnelFrequencyModel.java
@@ -11,7 +11,7 @@ import net.minecraft.client.render.model.BakedModel;
 import net.minecraft.client.render.model.IModelTransform;
 import net.minecraft.client.render.model.IUnbakedModel;
 import net.minecraft.client.render.model.json.ModelOverrideList;
-import net.minecraft.client.render.model.Material;
+import net.minecraft.client.util.SpriteIdentifier;
 import net.minecraft.client.render.model.ModelLoader;
 import net.minecraft.client.texture.SpriteAtlasTexture;
 import net.minecraft.client.texture.Sprite;
@@ -22,12 +22,12 @@ import net.minecraftforge.client.model.geometry.IModelGeometry;
 import appeng.core.AppEng;
 
 public class P2PTunnelFrequencyModel implements IModelGeometry {
-    private static final Material TEXTURE = new Material(SpriteAtlasTexture.BLOCK_ATLAS_TEX,
+    private static final SpriteIdentifier TEXTURE = new SpriteIdentifier(SpriteAtlasTexture.BLOCK_ATLAS_TEX,
             new Identifier(AppEng.MOD_ID, "parts/p2p_tunnel_frequency"));
 
     @Override
     public BakedModel bake(IModelConfiguration owner, ModelLoader bakery,
-                           Function spriteGetter, IModelTransform modelTransform,
+                           Function spriteGetter, IModelTransform modelTransform,
                            ModelOverrideList overrides, Identifier modelLocation) {
         try {
             final Sprite texture = spriteGetter.apply(TEXTURE);
@@ -38,8 +38,8 @@ public class P2PTunnelFrequencyModel implements IModelGeometry getTextures(IModelConfiguration owner,
-                                            Function modelGetter, Set> missingTextureErrors) {
+    public Collection getTextures(IModelConfiguration owner,
+                                                    Function modelGetter, Set> missingTextureErrors) {
         return Collections.singleton(TEXTURE);
     }
 
diff --git a/src/main/java/appeng/client/render/cablebus/SmartCableTextures.java b/src/main/java/appeng/client/render/cablebus/SmartCableTextures.java
index 7915271ca..62a860e3f 100644
--- a/src/main/java/appeng/client/render/cablebus/SmartCableTextures.java
+++ b/src/main/java/appeng/client/render/cablebus/SmartCableTextures.java
@@ -21,7 +21,7 @@ package appeng.client.render.cablebus;
 import java.util.Arrays;
 import java.util.function.Function;
 
-import net.minecraft.client.render.model.Material;
+import net.minecraft.client.util.SpriteIdentifier;
 import net.minecraft.client.texture.SpriteAtlasTexture;
 import net.minecraft.client.texture.Sprite;
 import net.minecraft.util.Identifier;
@@ -33,7 +33,7 @@ import appeng.core.AppEng;
  */
 public class SmartCableTextures {
 
-    public static final Material[] SMART_CHANNELS_TEXTURES = Arrays
+    public static final SpriteIdentifier[] SMART_CHANNELS_TEXTURES = Arrays
             .stream(new Identifier[] { new Identifier(AppEng.MOD_ID, "parts/cable/smart/channels_00"), //
                     new Identifier(AppEng.MOD_ID, "parts/cable/smart/channels_01"), //
                     new Identifier(AppEng.MOD_ID, "parts/cable/smart/channels_02"), //
@@ -44,14 +44,14 @@ public class SmartCableTextures {
                     new Identifier(AppEng.MOD_ID, "parts/cable/smart/channels_12"), //
                     new Identifier(AppEng.MOD_ID, "parts/cable/smart/channels_13"), //
                     new Identifier(AppEng.MOD_ID, "parts/cable/smart/channels_14")//
-            }).map(e -> new Material(SpriteAtlasTexture.BLOCK_ATLAS_TEX, e)).toArray(Material[]::new);
+            }).map(e -> new SpriteIdentifier(SpriteAtlasTexture.BLOCK_ATLAS_TEX, e)).toArray(SpriteIdentifier[]::new);
 
     // Textures used to display channels on smart cables. There's two sets of 5
     // textures each, and
     // one of each set are composed together to get even/odd colored channels
     private final Sprite[] textures;
 
-    public SmartCableTextures(Function bakedTextureGetter) {
+    public SmartCableTextures(Function bakedTextureGetter) {
         this.textures = Arrays.stream(SMART_CHANNELS_TEXTURES)//
                 .map(bakedTextureGetter)//
                 .toArray(Sprite[]::new);
diff --git a/src/main/java/appeng/client/render/crafting/CraftingCubeModel.java b/src/main/java/appeng/client/render/crafting/CraftingCubeModel.java
index 9bc7d1eb7..c30c8e138 100644
--- a/src/main/java/appeng/client/render/crafting/CraftingCubeModel.java
+++ b/src/main/java/appeng/client/render/crafting/CraftingCubeModel.java
@@ -29,7 +29,7 @@ import net.minecraft.client.render.model.BakedModel;
 import net.minecraft.client.render.model.IModelTransform;
 import net.minecraft.client.render.model.IUnbakedModel;
 import net.minecraft.client.render.model.json.ModelOverrideList;
-import net.minecraft.client.render.model.Material;
+import net.minecraft.client.util.SpriteIdentifier;
 import net.minecraft.client.render.model.ModelLoader;
 import net.minecraft.client.texture.SpriteAtlasTexture;
 import net.minecraft.client.texture.Sprite;
@@ -45,20 +45,20 @@ import appeng.core.AppEng;
  */
 class CraftingCubeModel implements IModelGeometry {
 
-    private final static Material RING_CORNER = texture("ring_corner");
-    private final static Material RING_SIDE_HOR = texture("ring_side_hor");
-    private final static Material RING_SIDE_VER = texture("ring_side_ver");
-    private final static Material UNIT_BASE = texture("unit_base");
-    private final static Material LIGHT_BASE = texture("light_base");
-    private final static Material ACCELERATOR_LIGHT = texture("accelerator_light");
-    private final static Material STORAGE_1K_LIGHT = texture("1k_storage_light");
-    private final static Material STORAGE_4K_LIGHT = texture("4k_storage_light");
-    private final static Material STORAGE_16K_LIGHT = texture("16k_storage_light");
-    private final static Material STORAGE_64K_LIGHT = texture("64k_storage_light");
-    private final static Material MONITOR_BASE = texture("monitor_base");
-    private final static Material MONITOR_LIGHT_DARK = texture("monitor_light_dark");
-    private final static Material MONITOR_LIGHT_MEDIUM = texture("monitor_light_medium");
-    private final static Material MONITOR_LIGHT_BRIGHT = texture("monitor_light_bright");
+    private final static SpriteIdentifier RING_CORNER = texture("ring_corner");
+    private final static SpriteIdentifier RING_SIDE_HOR = texture("ring_side_hor");
+    private final static SpriteIdentifier RING_SIDE_VER = texture("ring_side_ver");
+    private final static SpriteIdentifier UNIT_BASE = texture("unit_base");
+    private final static SpriteIdentifier LIGHT_BASE = texture("light_base");
+    private final static SpriteIdentifier ACCELERATOR_LIGHT = texture("accelerator_light");
+    private final static SpriteIdentifier STORAGE_1K_LIGHT = texture("1k_storage_light");
+    private final static SpriteIdentifier STORAGE_4K_LIGHT = texture("4k_storage_light");
+    private final static SpriteIdentifier STORAGE_16K_LIGHT = texture("16k_storage_light");
+    private final static SpriteIdentifier STORAGE_64K_LIGHT = texture("64k_storage_light");
+    private final static SpriteIdentifier MONITOR_BASE = texture("monitor_base");
+    private final static SpriteIdentifier MONITOR_LIGHT_DARK = texture("monitor_light_dark");
+    private final static SpriteIdentifier MONITOR_LIGHT_MEDIUM = texture("monitor_light_medium");
+    private final static SpriteIdentifier MONITOR_LIGHT_BRIGHT = texture("monitor_light_bright");
 
     private final AbstractCraftingUnitBlock.CraftingUnitType type;
 
@@ -67,8 +67,8 @@ class CraftingCubeModel implements IModelGeometry {
     }
 
     @Override
-    public Collection getTextures(IModelConfiguration owner,
-                                            Function modelGetter, Set> missingTextureErrors) {
+    public Collection getTextures(IModelConfiguration owner,
+                                                    Function modelGetter, Set> missingTextureErrors) {
         return ImmutableList.of(RING_CORNER, RING_SIDE_HOR, RING_SIDE_VER, UNIT_BASE, LIGHT_BASE, ACCELERATOR_LIGHT,
                 STORAGE_1K_LIGHT, STORAGE_4K_LIGHT, STORAGE_16K_LIGHT, STORAGE_64K_LIGHT, MONITOR_BASE,
                 MONITOR_LIGHT_DARK, MONITOR_LIGHT_MEDIUM, MONITOR_LIGHT_BRIGHT);
@@ -76,7 +76,7 @@ class CraftingCubeModel implements IModelGeometry {
 
     @Override
     public BakedModel bake(IModelConfiguration owner, ModelLoader bakery,
-                           Function spriteGetter, IModelTransform modelTransform,
+                           Function spriteGetter, IModelTransform modelTransform,
                            ModelOverrideList overrides, Identifier modelLocation) {
         // Retrieve our textures and pass them on to the baked model
         Sprite ringCorner = spriteGetter.apply(RING_CORNER);
@@ -102,7 +102,7 @@ class CraftingCubeModel implements IModelGeometry {
         }
     }
 
-    private static Sprite getLightTexture(Function textureGetter,
+    private static Sprite getLightTexture(Function textureGetter,
                                           AbstractCraftingUnitBlock.CraftingUnitType type) {
         switch (type) {
             case ACCELERATOR:
@@ -120,8 +120,8 @@ class CraftingCubeModel implements IModelGeometry {
         }
     }
 
-    private static Material texture(String name) {
-        return new Material(SpriteAtlasTexture.BLOCK_ATLAS_TEX,
+    private static SpriteIdentifier texture(String name) {
+        return new SpriteIdentifier(SpriteAtlasTexture.BLOCK_ATLAS_TEX,
                 new Identifier(AppEng.MOD_ID, "block/crafting/" + name));
     }
 }
diff --git a/src/main/java/appeng/client/render/crafting/EncodedPatternModel.java b/src/main/java/appeng/client/render/crafting/EncodedPatternModel.java
index 457d5d497..67dc0f399 100644
--- a/src/main/java/appeng/client/render/crafting/EncodedPatternModel.java
+++ b/src/main/java/appeng/client/render/crafting/EncodedPatternModel.java
@@ -10,7 +10,7 @@ import net.minecraft.client.render.model.BakedModel;
 import net.minecraft.client.render.model.IModelTransform;
 import net.minecraft.client.render.model.IUnbakedModel;
 import net.minecraft.client.render.model.json.ModelOverrideList;
-import net.minecraft.client.render.model.Material;
+import net.minecraft.client.util.SpriteIdentifier;
 import net.minecraft.client.render.model.ModelLoader;
 import net.minecraft.client.texture.Sprite;
 import net.minecraft.util.Identifier;
@@ -29,14 +29,14 @@ public class EncodedPatternModel implements IModelGeometry
     }
 
     @Override
-    public Collection getTextures(IModelConfiguration owner,
-                                            Function modelGetter, Set> missingTextureErrors) {
+    public Collection getTextures(IModelConfiguration owner,
+                                                    Function modelGetter, Set> missingTextureErrors) {
         return modelGetter.apply(baseModel).getTextures(modelGetter, missingTextureErrors);
     }
 
     @Override
     public BakedModel bake(IModelConfiguration owner, ModelLoader bakery,
-                           Function spriteGetter, IModelTransform modelTransform,
+                           Function spriteGetter, IModelTransform modelTransform,
                            ModelOverrideList overrides, Identifier modelLocation) {
         BakedModel baseModel = bakery.getBakedModel(this.baseModel, modelTransform, spriteGetter);
         return new EncodedPatternBakedModel(baseModel);
diff --git a/src/main/java/appeng/client/render/model/AutoRotatingBakedModel.java b/src/main/java/appeng/client/render/model/AutoRotatingBakedModel.java
index 7b3c21351..aa74ececc 100644
--- a/src/main/java/appeng/client/render/model/AutoRotatingBakedModel.java
+++ b/src/main/java/appeng/client/render/model/AutoRotatingBakedModel.java
@@ -34,7 +34,7 @@ import com.google.common.collect.ImmutableList;
 import net.minecraft.block.BlockState;
 import net.minecraft.client.render.model.BakedModel;
 import net.minecraft.client.render.model.json.ModelTransformation;
-import net.minecraft.client.renderer.Vector4f;
+import net.minecraft.client.util.math.Vector4f;
 import net.minecraft.client.render.model.BakedQuad;
 import net.minecraft.client.render.model.json.ModelOverrideList;
 import net.minecraft.client.texture.Sprite;
@@ -262,11 +262,11 @@ public class AutoRotatingBakedModel implements BakedModel {
             } else {
                 switch (fs.length) {
                     case 3:
-                        Vec3i vec = this.f2r.rotate(this.face).getDirectionVec();
+                        Vec3i vec = this.f2r.rotate(this.face).getVector();
                         return new float[] { vec.getX(), vec.getY(), vec.getZ() };
                     case 4:
                         Vector4f veccc = new Vector4f(fs[0], fs[1], fs[2], fs[3]);
-                        Vec3i vecc = this.f2r.rotate(this.face).getDirectionVec();
+                        Vec3i vecc = this.f2r.rotate(this.face).getVector();
                         return new float[] { vecc.getX(), vecc.getY(), vecc.getZ(), veccc.getW() };
 
                     default:
diff --git a/src/main/java/appeng/client/render/model/BiometricCardModel.java b/src/main/java/appeng/client/render/model/BiometricCardModel.java
index ea82c496b..f282b68cf 100644
--- a/src/main/java/appeng/client/render/model/BiometricCardModel.java
+++ b/src/main/java/appeng/client/render/model/BiometricCardModel.java
@@ -13,7 +13,7 @@ import net.minecraft.client.render.model.BakedModel;
 import net.minecraft.client.render.model.IModelTransform;
 import net.minecraft.client.render.model.IUnbakedModel;
 import net.minecraft.client.render.model.json.ModelOverrideList;
-import net.minecraft.client.render.model.Material;
+import net.minecraft.client.util.SpriteIdentifier;
 import net.minecraft.client.render.model.ModelLoader;
 import net.minecraft.client.texture.SpriteAtlasTexture;
 import net.minecraft.client.texture.Sprite;
@@ -30,19 +30,19 @@ import appeng.core.AppEng;
 public class BiometricCardModel implements IModelGeometry {
 
     public static final Identifier MODEL_BASE = new Identifier(AppEng.MOD_ID, "item/biometric_card_base");
-    private static final Material TEXTURE = new Material(SpriteAtlasTexture.BLOCK_ATLAS_TEX,
+    private static final SpriteIdentifier TEXTURE = new SpriteIdentifier(SpriteAtlasTexture.BLOCK_ATLAS_TEX,
             new Identifier(AppEng.MOD_ID, "item/biometric_card_hash"));
 
     @Override
-    public Collection getTextures(IModelConfiguration owner,
-                                            Function modelGetter, Set> missingTextureErrors) {
+    public Collection getTextures(IModelConfiguration owner,
+                                                    Function modelGetter, Set> missingTextureErrors) {
         return Collections.singleton(TEXTURE);
     }
 
     @Nullable
     @Override
     public BakedModel bake(IModelConfiguration owner, ModelLoader bakery,
-                           Function spriteGetter, IModelTransform transformIn,
+                           Function spriteGetter, IModelTransform transformIn,
                            ModelOverrideList overrides, Identifier locationIn) {
         Sprite texture = spriteGetter.apply(TEXTURE);
 
diff --git a/src/main/java/appeng/client/render/model/ColorApplicatorModel.java b/src/main/java/appeng/client/render/model/ColorApplicatorModel.java
index a07ac85ec..3439db598 100644
--- a/src/main/java/appeng/client/render/model/ColorApplicatorModel.java
+++ b/src/main/java/appeng/client/render/model/ColorApplicatorModel.java
@@ -11,7 +11,7 @@ import net.minecraft.client.render.model.BakedModel;
 import net.minecraft.client.render.model.IModelTransform;
 import net.minecraft.client.render.model.IUnbakedModel;
 import net.minecraft.client.render.model.json.ModelOverrideList;
-import net.minecraft.client.render.model.Material;
+import net.minecraft.client.util.SpriteIdentifier;
 import net.minecraft.client.render.model.ModelLoader;
 import net.minecraft.client.texture.SpriteAtlasTexture;
 import net.minecraft.client.texture.Sprite;
@@ -30,22 +30,22 @@ public class ColorApplicatorModel implements IModelGeometry getTextures(IModelConfiguration owner,
-                                            Function modelGetter, Set> missingTextureErrors) {
+    public Collection getTextures(IModelConfiguration owner,
+                                                    Function modelGetter, Set> missingTextureErrors) {
         return Arrays.asList(TEXTURE_DARK, TEXTURE_MEDIUM, TEXTURE_DARK);
     }
 
     @Override
     public BakedModel bake(IModelConfiguration owner, ModelLoader bakery,
-                           Function spriteGetter, IModelTransform modelTransform,
+                           Function spriteGetter, IModelTransform modelTransform,
                            ModelOverrideList overrides, Identifier modelLocation) {
         BakedModel baseModel = bakery.getBakedModel(MODEL_BASE, modelTransform, spriteGetter);
 
diff --git a/src/main/java/appeng/client/render/model/DriveModel.java b/src/main/java/appeng/client/render/model/DriveModel.java
index 04b36bef7..f1d796527 100644
--- a/src/main/java/appeng/client/render/model/DriveModel.java
+++ b/src/main/java/appeng/client/render/model/DriveModel.java
@@ -33,7 +33,7 @@ import net.minecraft.client.render.model.BakedModel;
 import net.minecraft.client.render.model.IModelTransform;
 import net.minecraft.client.render.model.IUnbakedModel;
 import net.minecraft.client.render.model.json.ModelOverrideList;
-import net.minecraft.client.render.model.Material;
+import net.minecraft.client.util.SpriteIdentifier;
 import net.minecraft.client.render.model.ModelLoader;
 import net.minecraft.client.texture.Sprite;
 import net.minecraft.util.Identifier;
@@ -57,7 +57,7 @@ public class DriveModel implements IModelGeometry {
 
     @Override
     public BakedModel bake(IModelConfiguration owner, ModelLoader bakery,
-                           Function spriteGetter, IModelTransform modelTransform,
+                           Function spriteGetter, IModelTransform modelTransform,
                            ModelOverrideList overrides, Identifier modelLocation) {
         EnumMap cellModels = new EnumMap<>(DriveSlotCellType.class);
 
@@ -72,8 +72,8 @@ public class DriveModel implements IModelGeometry {
     }
 
     @Override
-    public Collection getTextures(IModelConfiguration owner,
-                                            Function modelGetter, Set> missingTextureErrors) {
+    public Collection getTextures(IModelConfiguration owner,
+                                                    Function modelGetter, Set> missingTextureErrors) {
         return Collections.emptyList();
     }
 
diff --git a/src/main/java/appeng/client/render/model/GlassBakedModel.java b/src/main/java/appeng/client/render/model/GlassBakedModel.java
index 3b7e56e7a..9f9924b7c 100644
--- a/src/main/java/appeng/client/render/model/GlassBakedModel.java
+++ b/src/main/java/appeng/client/render/model/GlassBakedModel.java
@@ -34,7 +34,7 @@ import com.google.common.base.Strings;
 import net.minecraft.block.BlockState;
 import net.minecraft.client.render.model.BakedQuad;
 import net.minecraft.client.render.model.json.ModelOverrideList;
-import net.minecraft.client.render.model.Material;
+import net.minecraft.client.util.SpriteIdentifier;
 import net.minecraft.client.texture.SpriteAtlasTexture;
 import net.minecraft.client.texture.Sprite;
 import net.minecraft.client.renderer.vertex.VertexFormat;
@@ -64,30 +64,30 @@ class GlassBakedModel implements IDynamicBakedModel {
     private static final byte[][][] OFFSETS = generateOffsets();
 
     // Alternating textures based on position
-    static final Material TEXTURE_A = new Material(SpriteAtlasTexture.BLOCK_ATLAS_TEX,
+    static final SpriteIdentifier TEXTURE_A = new SpriteIdentifier(SpriteAtlasTexture.BLOCK_ATLAS_TEX,
             new Identifier("appliedenergistics2:block/glass/quartz_glass_a"));
-    static final Material TEXTURE_B = new Material(SpriteAtlasTexture.BLOCK_ATLAS_TEX,
+    static final SpriteIdentifier TEXTURE_B = new SpriteIdentifier(SpriteAtlasTexture.BLOCK_ATLAS_TEX,
             new Identifier("appliedenergistics2:block/glass/quartz_glass_b"));
-    static final Material TEXTURE_C = new Material(SpriteAtlasTexture.BLOCK_ATLAS_TEX,
+    static final SpriteIdentifier TEXTURE_C = new SpriteIdentifier(SpriteAtlasTexture.BLOCK_ATLAS_TEX,
             new Identifier("appliedenergistics2:block/glass/quartz_glass_c"));
-    static final Material TEXTURE_D = new Material(SpriteAtlasTexture.BLOCK_ATLAS_TEX,
+    static final SpriteIdentifier TEXTURE_D = new SpriteIdentifier(SpriteAtlasTexture.BLOCK_ATLAS_TEX,
             new Identifier("appliedenergistics2:block/glass/quartz_glass_d"));
 
     // Frame texture
-    static final Material[] TEXTURES_FRAME = generateTexturesFrame();
+    static final SpriteIdentifier[] TEXTURES_FRAME = generateTexturesFrame();
 
     // Generates the required textures for the frame
-    private static Material[] generateTexturesFrame() {
+    private static SpriteIdentifier[] generateTexturesFrame() {
         return IntStream.range(1, 16).mapToObj(Integer::toBinaryString).map(s -> Strings.padStart(s, 4, '0'))
                 .map(s -> new Identifier("appliedenergistics2:block/glass/quartz_glass_frame" + s))
-                .map(rl -> new Material(SpriteAtlasTexture.BLOCK_ATLAS_TEX, rl)).toArray(Material[]::new);
+                .map(rl -> new SpriteIdentifier(SpriteAtlasTexture.BLOCK_ATLAS_TEX, rl)).toArray(SpriteIdentifier[]::new);
     }
 
     private final Sprite[] glassTextures;
 
     private final Sprite[] frameTextures;
 
-    public GlassBakedModel(Function bakedTextureGetter) {
+    public GlassBakedModel(Function bakedTextureGetter) {
         this.glassTextures = new Sprite[] { bakedTextureGetter.apply(TEXTURE_A),
                 bakedTextureGetter.apply(TEXTURE_B), bakedTextureGetter.apply(TEXTURE_C),
                 bakedTextureGetter.apply(TEXTURE_D) };
@@ -212,7 +212,7 @@ class GlassBakedModel implements IDynamicBakedModel {
 
     private BakedQuad createQuad(Direction side, Vec3d c1, Vec3d c2, Vec3d c3, Vec3d c4, Sprite sprite,
             float uOffset, float vOffset) {
-        Vec3d normal = new Vec3d(side.getDirectionVec());
+        Vec3d normal = new Vec3d(side.getVector());
 
         // Apply the u,v shift.
         // This mirrors the logic from OffsetIcon from 1.7
diff --git a/src/main/java/appeng/client/render/model/GlassModel.java b/src/main/java/appeng/client/render/model/GlassModel.java
index a41fae964..2c01f5858 100644
--- a/src/main/java/appeng/client/render/model/GlassModel.java
+++ b/src/main/java/appeng/client/render/model/GlassModel.java
@@ -29,7 +29,7 @@ import net.minecraft.client.render.model.BakedModel;
 import net.minecraft.client.render.model.IModelTransform;
 import net.minecraft.client.render.model.IUnbakedModel;
 import net.minecraft.client.render.model.json.ModelOverrideList;
-import net.minecraft.client.render.model.Material;
+import net.minecraft.client.util.SpriteIdentifier;
 import net.minecraft.client.render.model.ModelLoader;
 import net.minecraft.client.texture.Sprite;
 import net.minecraft.util.Identifier;
@@ -43,16 +43,16 @@ public class GlassModel implements IModelGeometry {
 
     @Override
     public BakedModel bake(IModelConfiguration owner, ModelLoader bakery,
-                           Function spriteGetter, IModelTransform modelTransform,
+                           Function spriteGetter, IModelTransform modelTransform,
                            ModelOverrideList overrides, Identifier modelLocation) {
         return new GlassBakedModel(spriteGetter);
     }
 
     @Override
-    public Collection getTextures(IModelConfiguration owner,
-                                            Function modelGetter, Set> missingTextureErrors) {
+    public Collection getTextures(IModelConfiguration owner,
+                                                    Function modelGetter, Set> missingTextureErrors) {
         return ImmutableSet
-                .builder().add(GlassBakedModel.TEXTURE_A, GlassBakedModel.TEXTURE_B,
+                .builder().add(GlassBakedModel.TEXTURE_A, GlassBakedModel.TEXTURE_B,
                         GlassBakedModel.TEXTURE_C, GlassBakedModel.TEXTURE_D)
                 .add(GlassBakedModel.TEXTURES_FRAME).build();
     }
diff --git a/src/main/java/appeng/client/render/model/MatrixVertexTransformer.java b/src/main/java/appeng/client/render/model/MatrixVertexTransformer.java
index 7c6581343..87e9e499c 100644
--- a/src/main/java/appeng/client/render/model/MatrixVertexTransformer.java
+++ b/src/main/java/appeng/client/render/model/MatrixVertexTransformer.java
@@ -20,8 +20,8 @@ package appeng.client.render.model;
 
 import java.util.List;
 
+import net.minecraft.client.util.math.Vector4f;
 import net.minecraft.util.math.Matrix4f;
-import net.minecraft.client.renderer.Vector4f;
 import net.minecraft.client.texture.Sprite;
 import net.minecraft.client.renderer.vertex.VertexFormat;
 import net.minecraft.client.renderer.vertex.VertexFormatElement;
diff --git a/src/main/java/appeng/client/render/model/MemoryCardModel.java b/src/main/java/appeng/client/render/model/MemoryCardModel.java
index eb632dea1..d0b48d358 100644
--- a/src/main/java/appeng/client/render/model/MemoryCardModel.java
+++ b/src/main/java/appeng/client/render/model/MemoryCardModel.java
@@ -13,7 +13,7 @@ import net.minecraft.client.render.model.BakedModel;
 import net.minecraft.client.render.model.IModelTransform;
 import net.minecraft.client.render.model.IUnbakedModel;
 import net.minecraft.client.render.model.json.ModelOverrideList;
-import net.minecraft.client.render.model.Material;
+import net.minecraft.client.util.SpriteIdentifier;
 import net.minecraft.client.render.model.ModelLoader;
 import net.minecraft.client.texture.SpriteAtlasTexture;
 import net.minecraft.client.texture.Sprite;
@@ -30,19 +30,19 @@ import appeng.core.AppEng;
 public class MemoryCardModel implements IModelGeometry {
 
     public static final Identifier MODEL_BASE = new Identifier(AppEng.MOD_ID, "item/memory_card_base");
-    private static final Material TEXTURE = new Material(SpriteAtlasTexture.BLOCK_ATLAS_TEX,
+    private static final SpriteIdentifier TEXTURE = new SpriteIdentifier(SpriteAtlasTexture.BLOCK_ATLAS_TEX,
             new Identifier(AppEng.MOD_ID, "item/memory_card_hash"));
 
     @Override
-    public Collection getTextures(IModelConfiguration owner,
-                                            Function modelGetter, Set> missingTextureErrors) {
+    public Collection getTextures(IModelConfiguration owner,
+                                                    Function modelGetter, Set> missingTextureErrors) {
         return Collections.singleton(TEXTURE);
     }
 
     @Nullable
     @Override
     public BakedModel bake(IModelConfiguration owner, ModelLoader bakery,
-                           Function spriteGetter, IModelTransform modelTransform,
+                           Function spriteGetter, IModelTransform modelTransform,
                            ModelOverrideList overrides, Identifier modelLocation) {
         Sprite texture = spriteGetter.apply(TEXTURE);
 
diff --git a/src/main/java/appeng/client/render/model/SkyCompassBakedModel.java b/src/main/java/appeng/client/render/model/SkyCompassBakedModel.java
index 9128989b5..7fdbef645 100644
--- a/src/main/java/appeng/client/render/model/SkyCompassBakedModel.java
+++ b/src/main/java/appeng/client/render/model/SkyCompassBakedModel.java
@@ -29,7 +29,7 @@ import net.minecraft.client.entity.player.ClientPlayerEntity;
 import net.minecraft.client.render.model.BakedModel;
 import net.minecraft.client.render.model.json.ModelTransformation;
 import net.minecraft.util.math.Matrix4f;
-import net.minecraft.client.renderer.Quaternion;
+import net.minecraft.util.math.Quaternion;
 import net.minecraft.client.render.model.BakedQuad;
 import net.minecraft.client.render.model.json.ModelOverrideList;
 import net.minecraft.client.texture.Sprite;
@@ -89,8 +89,8 @@ public class SkyCompassBakedModel implements IDynamicBakedModel {
         if (side == null) {
             // Set up the rotation around the Y-axis for the pointer
             Matrix4f matrix = new Matrix4f();
-            matrix.setIdentity();
-            matrix.mul(new Quaternion(0, rotation, 0, false));
+            matrix.loadIdentity();
+            matrix.multiply(new Quaternion(0, rotation, 0, false));
 
             MatrixVertexTransformer transformer = new MatrixVertexTransformer(matrix);
             for (BakedQuad bakedQuad : this.pointer.getQuads(state, side, rand, extraData)) {
diff --git a/src/main/java/appeng/client/render/model/SkyCompassModel.java b/src/main/java/appeng/client/render/model/SkyCompassModel.java
index 4f9b30a43..2844ae672 100644
--- a/src/main/java/appeng/client/render/model/SkyCompassModel.java
+++ b/src/main/java/appeng/client/render/model/SkyCompassModel.java
@@ -31,7 +31,7 @@ import net.minecraft.client.render.model.BakedModel;
 import net.minecraft.client.render.model.IModelTransform;
 import net.minecraft.client.render.model.IUnbakedModel;
 import net.minecraft.client.render.model.json.ModelOverrideList;
-import net.minecraft.client.render.model.Material;
+import net.minecraft.client.util.SpriteIdentifier;
 import net.minecraft.client.render.model.ModelLoader;
 import net.minecraft.client.texture.Sprite;
 import net.minecraft.util.Identifier;
@@ -54,7 +54,7 @@ public class SkyCompassModel implements IModelGeometry {
 
     @Override
     public BakedModel bake(IModelConfiguration owner, ModelLoader bakery,
-                           Function spriteGetter, IModelTransform modelTransform,
+                           Function spriteGetter, IModelTransform modelTransform,
                            ModelOverrideList overrides, Identifier modelLocation) {
         BakedModel baseModel = bakery.getBakedModel(MODEL_BASE, modelTransform, spriteGetter);
         BakedModel pointerModel = bakery.getBakedModel(MODEL_POINTER, modelTransform, spriteGetter);
@@ -62,8 +62,8 @@ public class SkyCompassModel implements IModelGeometry {
     }
 
     @Override
-    public Collection getTextures(IModelConfiguration owner,
-                                            Function modelGetter, Set> missingTextureErrors) {
+    public Collection getTextures(IModelConfiguration owner,
+                                                    Function modelGetter, Set> missingTextureErrors) {
         return Collections.emptyList();
     }
 
diff --git a/src/main/java/appeng/client/render/model/UVLModelLoader.java b/src/main/java/appeng/client/render/model/UVLModelLoader.java
index d6c28e8a8..53032f4c1 100644
--- a/src/main/java/appeng/client/render/model/UVLModelLoader.java
+++ b/src/main/java/appeng/client/render/model/UVLModelLoader.java
@@ -53,7 +53,7 @@ import net.minecraft.client.render.model.IUnbakedModel;
 import net.minecraft.client.render.model.ItemOverride;
 import net.minecraft.client.render.model.json.ModelOverrideList;
 import net.minecraft.client.render.model.ItemTransformVec3f;
-import net.minecraft.client.render.model.Material;
+import net.minecraft.client.util.SpriteIdentifier;
 import net.minecraft.resources.IResourceManager;
 import net.minecraft.util.math.Direction;
 import net.minecraft.util.JSONUtils;
@@ -143,7 +143,7 @@ public class UVLModelLoader implements IModelLoader spriteGetter, IModelTransform modelTransform,
+                               Function spriteGetter, IModelTransform modelTransform,
                                ModelOverrideList overrides, Identifier modelLocation) {
             Sprite particle = spriteGetter.apply(owner.resolveTexture("particle"));
 
@@ -199,9 +199,9 @@ public class UVLModelLoader implements IModelLoader getTextures(IModelConfiguration owner,
-                Function modelGetter,
-                Set> missingTextureErrors) {
+        public Collection getTextures(IModelConfiguration owner,
+                                                        Function modelGetter,
+                                                        Set> missingTextureErrors) {
             return parent.getTextures(modelGetter, missingTextureErrors);
         }
 
diff --git a/src/main/java/appeng/client/render/spatial/SpatialPylonModel.java b/src/main/java/appeng/client/render/spatial/SpatialPylonModel.java
index bc42a9ec9..febbd41d4 100644
--- a/src/main/java/appeng/client/render/spatial/SpatialPylonModel.java
+++ b/src/main/java/appeng/client/render/spatial/SpatialPylonModel.java
@@ -32,7 +32,7 @@ import net.minecraft.client.render.model.BakedModel;
 import net.minecraft.client.render.model.IModelTransform;
 import net.minecraft.client.render.model.IUnbakedModel;
 import net.minecraft.client.render.model.json.ModelOverrideList;
-import net.minecraft.client.render.model.Material;
+import net.minecraft.client.util.SpriteIdentifier;
 import net.minecraft.client.render.model.ModelLoader;
 import net.minecraft.client.texture.SpriteAtlasTexture;
 import net.minecraft.client.texture.Sprite;
@@ -46,7 +46,7 @@ public class SpatialPylonModel implements IModelGeometry {
 
     @Override
     public BakedModel bake(IModelConfiguration owner, ModelLoader bakery,
-                           Function spriteGetter, IModelTransform modelTransform,
+                           Function spriteGetter, IModelTransform modelTransform,
                            ModelOverrideList overrides, Identifier modelLocation) {
         Map textures = new EnumMap<>(SpatialPylonTextureType.class);
 
@@ -58,14 +58,14 @@ public class SpatialPylonModel implements IModelGeometry {
     }
 
     @Override
-    public Collection getTextures(IModelConfiguration owner,
-                                            Function modelGetter, Set> missingTextureErrors) {
+    public Collection getTextures(IModelConfiguration owner,
+                                                    Function modelGetter, Set> missingTextureErrors) {
         return Arrays.stream(SpatialPylonTextureType.values()).map(SpatialPylonModel::getTexturePath)
                 .collect(Collectors.toList());
     }
 
-    private static Material getTexturePath(SpatialPylonTextureType type) {
-        return new Material(SpriteAtlasTexture.BLOCK_ATLAS_TEX,
+    private static SpriteIdentifier getTexturePath(SpatialPylonTextureType type) {
+        return new SpriteIdentifier(SpriteAtlasTexture.BLOCK_ATLAS_TEX,
                 new Identifier(AppEng.MOD_ID, "block/spatial_pylon/" + type.name().toLowerCase()));
     }
 
diff --git a/src/main/java/appeng/client/render/tesr/CrankTESR.java b/src/main/java/appeng/client/render/tesr/CrankTESR.java
index 56285b670..d1a69dfc0 100644
--- a/src/main/java/appeng/client/render/tesr/CrankTESR.java
+++ b/src/main/java/appeng/client/render/tesr/CrankTESR.java
@@ -27,9 +27,9 @@ import net.minecraft.client.util.math.MatrixStack;
 import net.minecraft.client.render.VertexConsumer;
 
 import net.minecraft.block.BlockState;
-import net.minecraft.client.renderer.Atlases;
+import net.minecraft.client.render.TexturedRenderLayers;
 import net.minecraft.client.render.block.BlockRenderManager;
-import net.minecraft.client.renderer.Quaternion;
+import net.minecraft.util.math.Quaternion;
 import net.minecraft.client.render.block.entity.BlockEntityRenderer;
 import net.minecraft.client.render.block.entity.BlockEntityRenderDispatcher;
 
@@ -62,8 +62,8 @@ public class CrankTESR extends BlockEntityRenderer {
         BlockState blockState = te.getCachedState();
         BlockRenderManager dispatcher = MinecraftClient.getInstance().getBlockRenderManager();
         BakedModel model = dispatcher.getModelForState(blockState);
-        VertexConsumer buffer = buffers.getBuffer(Atlases.getTranslucentBlockType());
-        dispatcher.getBlockModelRenderer().renderModelBrightnessColor(ms.getLast(), buffer, null, model, 1, 1, 1,
+        VertexConsumer buffer = buffers.getBuffer(TexturedRenderLayers.getEntityTranslucentCull());
+        dispatcher.getModelRenderer().renderModelBrightnessColor(ms.peek(), buffer, null, model, 1, 1, 1,
                 combinedLightIn, combinedOverlayIn);
         ms.pop();
 
diff --git a/src/main/java/appeng/client/render/tesr/DriveLedTileEntityRenderer.java b/src/main/java/appeng/client/render/tesr/DriveLedTileEntityRenderer.java
index 87c970a6b..b731c5c9f 100644
--- a/src/main/java/appeng/client/render/tesr/DriveLedTileEntityRenderer.java
+++ b/src/main/java/appeng/client/render/tesr/DriveLedTileEntityRenderer.java
@@ -107,7 +107,7 @@ public class DriveLedTileEntityRenderer extends BlockEntityRenderer> event) {
-        final IForgeRegistry> registry = event.getRegistry();
-        // TODO: Do not use the internal API
-        final ApiDefinitions definitions = Api.INSTANCE.definitions();
-        definitions.getRegistry().getBootstrapComponents(ITileEntityRegistrationComponent.class)
-                .forEachRemaining(b -> b.register(registry));
-    }
-
     public void registerContainerTypes(RegistryEvent.Register> event) {
         final IForgeRegistry> registry = event.getRegistry();
 
@@ -321,29 +289,6 @@ final class Registration {
                 DisassembleRecipe.SERIALIZER);
     }
 
-    public void registerParticleTypes(RegistryEvent.Register> event) {
-        final IForgeRegistry> registry = event.getRegistry();
-        registry.register(ParticleTypes.CHARGED_ORE);
-        registry.register(ParticleTypes.CRAFTING);
-        registry.register(ParticleTypes.ENERGY);
-        registry.register(ParticleTypes.LIGHTNING_ARC);
-        registry.register(ParticleTypes.LIGHTNING);
-        registry.register(ParticleTypes.MATTER_CANNON);
-        registry.register(ParticleTypes.VIBRANT);
-    }
-
-    @Environment(EnvType.CLIENT)
-    public void registerParticleFactories(ParticleFactoryRegisterEvent event) {
-        ParticleManager particles = MinecraftClient.getInstance().particles;
-        particles.registerFactory(ParticleTypes.CHARGED_ORE, ChargedOreFX.Factory::new);
-        particles.registerFactory(ParticleTypes.CRAFTING, CraftingFx.Factory::new);
-        particles.registerFactory(ParticleTypes.ENERGY, EnergyFx.Factory::new);
-        particles.registerFactory(ParticleTypes.LIGHTNING_ARC, LightningArcFX.Factory::new);
-        particles.registerFactory(ParticleTypes.LIGHTNING, LightningFX.Factory::new);
-        particles.registerFactory(ParticleTypes.MATTER_CANNON, MatterCannonFX.Factory::new);
-        particles.registerFactory(ParticleTypes.VIBRANT, VibrantFX.Factory::new);
-    }
-
     // FIXME LATER
     public static void postInit() {
         final IRegistryContainer registries = AEApi.instance().registries();
@@ -575,32 +520,10 @@ final class Registration {
         evt.getRegistry().register(StorageCellModDimension.INSTANCE);
     }
 
-    @Environment(EnvType.CLIENT)
-    public void registerTextures(TextureStitchEvent.Pre event) {
-        SkyChestTESR.registerTextures(event);
-        InscriberTESR.registerTexture(event);
-    }
-
     public void registerCommands(final FMLServerStartingEvent evt) {
         new AECommand().register(evt.getCommandDispatcher());
     }
 
-    @Environment(EnvType.CLIENT)
-    public void registerItemColors(ColorHandlerEvent.Item event) {
-        // TODO: Do not use the internal API
-        final ApiDefinitions definitions = Api.INSTANCE.definitions();
-        definitions.getRegistry().getBootstrapComponents(IItemColorRegistrationComponent.class)
-                .forEachRemaining(c -> c.register(event.getItemColors(), event.getBlockColors()));
-    }
-
-    @Environment(EnvType.CLIENT)
-    public void onModelsReloaded(Map loadedModels) {
-        // TODO: Do not use the internal API
-        final ApiDefinitions definitions = Api.INSTANCE.definitions();
-        definitions.getRegistry().getBootstrapComponents(IModelBakeComponent.class)
-                .forEachRemaining(c -> c.onModelsReloaded(loadedModels));
-    }
-
     @Environment(EnvType.CLIENT)
     public void registerClientEvents() {
         IEventBus modEventBus = FMLJavaModLoadingContext.get().getModEventBus();
diff --git a/src/main/java/appeng/core/api/definitions/ApiBlocks.java b/src/main/java/appeng/core/api/definitions/ApiBlocks.java
deleted file mode 100644
index e8e0cf1ff..000000000
--- a/src/main/java/appeng/core/api/definitions/ApiBlocks.java
+++ /dev/null
@@ -1,1037 +0,0 @@
-/*
- * This file is part of Applied Energistics 2.
- * Copyright (c) 2013 - 2015, AlgorithmX2, All rights reserved.
- *
- * Applied Energistics 2 is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * Applied Energistics 2 is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with Applied Energistics 2.  If not, see .
- */
-
-package appeng.core.api.definitions;
-
-import static appeng.block.AEBaseBlock.defaultProps;
-
-import net.fabricmc.api.EnvType;
-import net.fabricmc.api.Environment;
-import net.fabricmc.fabric.api.tool.attribute.v1.FabricToolTags;
-import net.minecraft.block.DispenserBlock;
-import net.minecraft.block.SlabBlock;
-import net.minecraft.entity.SpawnGroup;
-import net.minecraft.sound.BlockSoundGroup;
-import net.minecraft.block.StairsBlock;
-import net.minecraft.block.Material;
-import net.minecraft.client.render.RenderLayer;
-
-import appeng.api.definitions.IBlockDefinition;
-import appeng.api.definitions.IBlocks;
-import appeng.api.definitions.ITileDefinition;
-import appeng.api.features.AEFeature;
-import appeng.block.AEBaseBlockItemChargeable;
-import appeng.block.crafting.AbstractCraftingUnitBlock.CraftingUnitType;
-import appeng.block.crafting.CraftingMonitorBlock;
-import appeng.block.crafting.CraftingStorageBlock;
-import appeng.block.crafting.CraftingStorageItem;
-import appeng.block.crafting.CraftingUnitBlock;
-import appeng.block.crafting.MolecularAssemblerBlock;
-import appeng.block.grindstone.CrankBlock;
-import appeng.block.grindstone.GrinderBlock;
-import appeng.block.misc.CellWorkbenchBlock;
-import appeng.block.misc.ChargerBlock;
-import appeng.block.misc.CondenserBlock;
-import appeng.block.misc.InscriberBlock;
-import appeng.block.misc.InscriberRendering;
-import appeng.block.misc.InterfaceBlock;
-import appeng.block.misc.LightDetectorBlock;
-import appeng.block.misc.QuartzFixtureBlock;
-import appeng.block.misc.QuartzGrowthAcceleratorBlock;
-import appeng.block.misc.SecurityStationBlock;
-import appeng.block.misc.SecurityStationRendering;
-import appeng.block.misc.SkyCompassBlock;
-import appeng.block.misc.SkyCompassRendering;
-import appeng.block.misc.TinyTNTBlock;
-import appeng.block.misc.VibrationChamberBlock;
-import appeng.block.networking.CableBusBlock;
-import appeng.block.networking.CableBusRendering;
-import appeng.block.networking.ControllerBlock;
-import appeng.block.networking.ControllerRendering;
-import appeng.block.networking.CreativeEnergyCellBlock;
-import appeng.block.networking.DenseEnergyCellBlock;
-import appeng.block.networking.EnergyAcceptorBlock;
-import appeng.block.networking.EnergyCellBlock;
-import appeng.block.networking.WirelessBlock;
-import appeng.block.networking.WirelessRendering;
-import appeng.block.paint.PaintSplotchesBlock;
-import appeng.block.paint.PaintSplotchesRendering;
-import appeng.block.qnb.QuantumBridgeRendering;
-import appeng.block.qnb.QuantumLinkChamberBlock;
-import appeng.block.qnb.QuantumRingBlock;
-import appeng.block.spatial.MatrixFrameBlock;
-import appeng.block.spatial.SpatialIOPortBlock;
-import appeng.block.spatial.SpatialPylonBlock;
-import appeng.block.storage.ChestBlock;
-import appeng.block.storage.ChestRendering;
-import appeng.block.storage.DriveBlock;
-import appeng.block.storage.DriveRendering;
-import appeng.block.storage.IOPortBlock;
-import appeng.block.storage.SkyChestBlock;
-import appeng.bootstrap.BlockRenderingCustomizer;
-import appeng.bootstrap.FeatureFactory;
-import appeng.bootstrap.IBlockRendering;
-import appeng.bootstrap.IItemRendering;
-import appeng.bootstrap.TileEntityRendering;
-import appeng.bootstrap.TileEntityRenderingCustomizer;
-import appeng.bootstrap.components.IInitComponent;
-import appeng.bootstrap.definitions.TileEntityDefinition;
-import appeng.client.render.crafting.CraftingCubeRendering;
-import appeng.client.render.crafting.CraftingMonitorTESR;
-import appeng.client.render.crafting.MonitorBakedModel;
-import appeng.client.render.model.AutoRotatingBakedModel;
-import appeng.client.render.spatial.SpatialPylonRendering;
-import appeng.client.render.tesr.CrankTESR;
-import appeng.client.render.tesr.DriveLedTileEntityRenderer;
-import appeng.client.render.tesr.SkyChestTESR;
-import appeng.debug.ChunkLoaderBlock;
-import appeng.debug.ChunkLoaderBlockEntity;
-import appeng.debug.CubeGeneratorBlock;
-import appeng.debug.CubeGeneratorBlockEntity;
-import appeng.debug.EnergyGeneratorBlock;
-import appeng.debug.EnergyGeneratorBlockEntity;
-import appeng.debug.ItemGenBlock;
-import appeng.debug.ItemGenBlockEntity;
-import appeng.debug.PhantomNodeBlock;
-import appeng.debug.PhantomNodeBlockEntity;
-import appeng.decorative.AEDecorativeBlock;
-import appeng.decorative.solid.ChargedQuartzOreBlock;
-import appeng.decorative.solid.QuartzGlassBlock;
-import appeng.decorative.solid.QuartzLampBlock;
-import appeng.decorative.solid.QuartzOreBlock;
-import appeng.decorative.solid.QuartzPillarBlock;
-import appeng.decorative.solid.SkyStoneBlock;
-import appeng.decorative.solid.SkyStoneBlock.SkystoneType;
-import appeng.entity.TinyTNTPrimedEntity;
-import appeng.fluids.block.FluidInterfaceBlock;
-import appeng.fluids.tile.FluidInterfaceBlockEntity;
-import appeng.hooks.TinyTNTDispenseItemBehavior;
-import appeng.tile.crafting.CraftingMonitorBlockEntity;
-import appeng.tile.crafting.CraftingStorageBlockEntity;
-import appeng.tile.crafting.CraftingBlockEntity;
-import appeng.tile.crafting.MolecularAssemblerRenderer;
-import appeng.tile.crafting.MolecularAssemblerBlockEntity;
-import appeng.tile.grindstone.CrankBlockEntity;
-import appeng.tile.grindstone.GrinderBlockEntity;
-import appeng.tile.misc.CellWorkbenchBlockEntity;
-import appeng.tile.misc.ChargerBlockEntity;
-import appeng.tile.misc.CondenserBlockEntity;
-import appeng.tile.misc.InscriberBlockEntity;
-import appeng.tile.misc.InterfaceBlockEntity;
-import appeng.tile.misc.LightDetectorBlockEntity;
-import appeng.tile.misc.PaintSplotchesBlockEntity;
-import appeng.tile.misc.QuartzGrowthAcceleratorBlockEntity;
-import appeng.tile.misc.SecurityStationBlockEntity;
-import appeng.tile.misc.SkyCompassBlockEntity;
-import appeng.tile.misc.VibrationChamberBlockEntity;
-import appeng.tile.networking.CableBusTESR;
-import appeng.tile.networking.CableBusBlockEntity;
-import appeng.tile.networking.ControllerBlockEntity;
-import appeng.tile.networking.CreativeEnergyCellBlockEntity;
-import appeng.tile.networking.DenseEnergyCellBlockEntity;
-import appeng.tile.networking.EnergyAcceptorBlockEntity;
-import appeng.tile.networking.EnergyCellBlockEntity;
-import appeng.tile.networking.WirelessBlockEntity;
-import appeng.tile.qnb.QuantumBridgeBlockEntity;
-import appeng.tile.spatial.SpatialIOPortBlockEntity;
-import appeng.tile.spatial.SpatialPylonBlockEntity;
-import appeng.tile.storage.ChestBlockEntity;
-import appeng.tile.storage.DriveBlockEntity;
-import appeng.tile.storage.IOPortBlockEntity;
-import appeng.tile.storage.SkyChestBlockEntity;
-
-/**
- * Internal implementation for the API blocks
- */
-public final class ApiBlocks implements IBlocks {
-    private final IBlockDefinition quartzOre;
-    private final IBlockDefinition quartzOreCharged;
-    private final IBlockDefinition matrixFrame;
-    private final IBlockDefinition quartzBlock;
-    private final IBlockDefinition quartzPillar;
-    private final IBlockDefinition chiseledQuartzBlock;
-    private final IBlockDefinition quartzGlass;
-    private final IBlockDefinition quartzVibrantGlass;
-    private final IBlockDefinition quartzFixture;
-    private final IBlockDefinition fluixBlock;
-    private final IBlockDefinition skyStoneBlock;
-    private final IBlockDefinition smoothSkyStoneBlock;
-    private final IBlockDefinition skyStoneBrick;
-    private final IBlockDefinition skyStoneSmallBrick;
-    private final IBlockDefinition skyStoneChest;
-    private final IBlockDefinition smoothSkyStoneChest;
-    private final IBlockDefinition skyCompass;
-    private final ITileDefinition grindstone;
-    private final ITileDefinition crank;
-    private final ITileDefinition inscriber;
-    private final ITileDefinition wirelessAccessPoint;
-    private final ITileDefinition charger;
-    private final IBlockDefinition tinyTNT;
-    private final ITileDefinition securityStation;
-    private final ITileDefinition quantumRing;
-    private final ITileDefinition quantumLink;
-    private final ITileDefinition spatialPylon;
-    private final ITileDefinition spatialIOPort;
-    private final ITileDefinition multiPart;
-    private final ITileDefinition controller;
-    private final ITileDefinition drive;
-    private final ITileDefinition chest;
-    private final ITileDefinition iface;
-    private final ITileDefinition fluidIface;
-    private final ITileDefinition cellWorkbench;
-    private final ITileDefinition iOPort;
-    private final ITileDefinition condenser;
-    private final ITileDefinition energyAcceptor;
-    private final ITileDefinition vibrationChamber;
-    private final ITileDefinition quartzGrowthAccelerator;
-    private final ITileDefinition energyCell;
-    private final ITileDefinition energyCellDense;
-    private final ITileDefinition energyCellCreative;
-    private final ITileDefinition craftingUnit;
-    private final ITileDefinition craftingAccelerator;
-    private final ITileDefinition craftingStorage1k;
-    private final ITileDefinition craftingStorage4k;
-    private final ITileDefinition craftingStorage16k;
-    private final ITileDefinition craftingStorage64k;
-    private final ITileDefinition craftingMonitor;
-    private final ITileDefinition molecularAssembler;
-    private final ITileDefinition lightDetector;
-    private final ITileDefinition paint;
-    private final IBlockDefinition skyStoneStairs;
-    private final IBlockDefinition smoothSkyStoneStairs;
-    private final IBlockDefinition skyStoneBrickStairs;
-    private final IBlockDefinition skyStoneSmallBrickStairs;
-    private final IBlockDefinition fluixStairs;
-    private final IBlockDefinition quartzStairs;
-    private final IBlockDefinition chiseledQuartzStairs;
-    private final IBlockDefinition quartzPillarStairs;
-
-    private final IBlockDefinition skyStoneSlab;
-    private final IBlockDefinition smoothSkyStoneSlab;
-    private final IBlockDefinition skyStoneBrickSlab;
-    private final IBlockDefinition skyStoneSmallBrickSlab;
-    private final IBlockDefinition fluixSlab;
-    private final IBlockDefinition quartzSlab;
-    private final IBlockDefinition chiseledQuartzSlab;
-    private final IBlockDefinition quartzPillarSlab;
-
-    private final IBlockDefinition itemGen;
-    private final IBlockDefinition chunkLoader;
-    private final IBlockDefinition phantomNode;
-    private final IBlockDefinition cubeGenerator;
-    private final IBlockDefinition energyGenerator;
-
-    private static final AbstractBlock.Settings QUARTZ_PROPERTIES = defaultProps(Material.STONE).strength(3, 5);
-
-    private static final AbstractBlock.Settings SKYSTONE_PROPERTIES = defaultProps(Material.STONE).strength(50,
-            150);
-
-    public ApiBlocks(FeatureFactory registry) {
-        this.quartzOre = registry.block("quartz_ore", () -> new QuartzOreBlock(QUARTZ_PROPERTIES))
-                .features(AEFeature.CERTUS_ORE).build();
-        this.quartzOreCharged = registry.block("charged_quartz_ore", () -> new ChargedQuartzOreBlock(QUARTZ_PROPERTIES))
-                .features(AEFeature.CERTUS_ORE, AEFeature.CHARGED_CERTUS_ORE).rendering(new BlockRenderingCustomizer() {
-                    @Override
-                    @Environment(EnvType.CLIENT)
-                    public void customize(IBlockRendering rendering, IItemRendering itemRendering) {
-                        rendering.renderType(RenderLayer.getCutout());
-                    }
-                }).build();
-        this.matrixFrame = registry.block("matrix_frame", MatrixFrameBlock::new).features(AEFeature.SPATIAL_IO).build();
-
-        FeatureFactory deco = registry.features(AEFeature.DECORATIVE_BLOCKS);
-        this.quartzBlock = deco.block("quartz_block", () -> new AEDecorativeBlock(QUARTZ_PROPERTIES)).build();
-        this.quartzPillar = deco.block("quartz_pillar", () -> new QuartzPillarBlock(QUARTZ_PROPERTIES)).build();
-        this.chiseledQuartzBlock = deco.block("chiseled_quartz_block", () -> new AEDecorativeBlock(QUARTZ_PROPERTIES))
-                .build();
-
-        this.quartzGlass = registry.features(AEFeature.QUARTZ_GLASS)
-                .block("quartz_glass", () -> new QuartzGlassBlock(defaultProps(Material.GLASS).notSolid()))
-                .rendering(new BlockRenderingCustomizer() {
-                    @Override
-                    @Environment(EnvType.CLIENT)
-                    public void customize(IBlockRendering rendering, IItemRendering itemRendering) {
-                        rendering.renderType(RenderLayer.getCutout());
-                    }
-                }).build();
-        this.quartzVibrantGlass = deco
-                .block("quartz_vibrant_glass",
-                        () -> new QuartzLampBlock(defaultProps(Material.GLASS).lightValue(15).notSolid()))
-                .addFeatures(AEFeature.DECORATIVE_LIGHTS, AEFeature.QUARTZ_GLASS)
-                .rendering(new BlockRenderingCustomizer() {
-                    @Override
-                    @Environment(EnvType.CLIENT)
-                    public void customize(IBlockRendering rendering, IItemRendering itemRendering) {
-                        rendering.renderType(RenderLayer.getCutout());
-                    }
-                }).build();
-
-        this.quartzFixture = registry.block("quartz_fixture", QuartzFixtureBlock::new)
-                .features(AEFeature.DECORATIVE_LIGHTS).rendering(new BlockRenderingCustomizer() {
-                    @Override
-                    @Environment(EnvType.CLIENT)
-                    public void customize(IBlockRendering rendering, IItemRendering itemRendering) {
-                        rendering.renderType(RenderLayer.getCutout());
-                    }
-                }).build();
-
-        this.fluixBlock = registry.features(AEFeature.FLUIX)
-                .block("fluix_block", () -> new AEDecorativeBlock(QUARTZ_PROPERTIES)).build();
-
-        this.skyStoneBlock = registry
-                .features(
-                        AEFeature.SKY_STONE)
-                .block("sky_stone_block", () -> new SkyStoneBlock(SkystoneType.STONE,
-                        defaultProps(Material.STONE).strength(50, 150).harvestLevel(3)))
-                .build();
-
-        this.smoothSkyStoneBlock = registry.features(AEFeature.SKY_STONE)
-                .block("smooth_sky_stone_block", () -> new SkyStoneBlock(SkystoneType.BLOCK, SKYSTONE_PROPERTIES))
-                .build();
-        this.skyStoneBrick = deco
-                .block("sky_stone_brick", () -> new SkyStoneBlock(SkystoneType.BRICK, SKYSTONE_PROPERTIES))
-                .addFeatures(AEFeature.SKY_STONE).build();
-        this.skyStoneSmallBrick = deco
-                .block("sky_stone_small_brick", () -> new SkyStoneBlock(SkystoneType.SMALL_BRICK, SKYSTONE_PROPERTIES))
-                .addFeatures(AEFeature.SKY_STONE).build();
-
-        AbstractBlock.Settings skyStoneChestProps = defaultProps(Material.STONE).strength(50, 150).notSolid();
-
-        TileEntityDefinition skyChestTile = registry
-                .tileEntity("sky_chest", SkyChestBlockEntity.class, SkyChestBlockEntity::new)
-                .rendering(new TileEntityRenderingCustomizer() {
-                    @Override
-                    @Environment(EnvType.CLIENT)
-                    public void customize(TileEntityRendering rendering) {
-                        rendering.tileEntityRenderer(SkyChestTESR::new);
-                    }
-                }).build();
-        this.skyStoneChest = registry
-                .block("sky_stone_chest", () -> new SkyChestBlock(SkyChestBlock.SkyChestType.STONE, skyStoneChestProps))
-                .features(AEFeature.SKY_STONE, AEFeature.SKY_STONE_CHESTS).tileEntity(skyChestTile).build();
-        this.smoothSkyStoneChest = registry
-                .block("smooth_sky_stone_chest",
-                        () -> new SkyChestBlock(SkyChestBlock.SkyChestType.BLOCK, skyStoneChestProps))
-                .features(AEFeature.SKY_STONE, AEFeature.SKY_STONE_CHESTS).tileEntity(skyChestTile).build();
-
-        this.skyCompass = registry.block("sky_compass", () -> new SkyCompassBlock(defaultProps(Material.SUPPORTED)))
-                .features(AEFeature.METEORITE_COMPASS)
-                .tileEntity(registry.tileEntity("sky_compass", SkyCompassBlockEntity.class, SkyCompassBlockEntity::new)
-                        .rendering(new SkyCompassRendering()).build())
-                .build();
-        this.grindstone = registry
-                .block("grindstone", () -> new GrinderBlock(defaultProps(Material.STONE).strength(3.2f)))
-                .features(AEFeature.GRIND_STONE)
-                .tileEntity(registry.tileEntity("grindstone", GrinderBlockEntity.class, GrinderBlockEntity::new).build())
-                .build();
-        this.crank = registry
-                .block("crank",
-                        () -> new CrankBlock(
-                                defaultProps(Material.WOOD).breakByTool(FabricToolTags.AXES, 0).notSolid()))
-                .features(AEFeature.GRIND_STONE)
-                .tileEntity(registry.tileEntity("crank", CrankBlockEntity.class, CrankBlockEntity::new)
-                        .rendering(new TileEntityRenderingCustomizer() {
-                            @Override
-                            @Environment(EnvType.CLIENT)
-                            public void customize(TileEntityRendering rendering) {
-                                rendering.tileEntityRenderer(CrankTESR::new);
-                            }
-                        }).build())
-                .build();
-        this.inscriber = registry.block("inscriber", () -> new InscriberBlock(defaultProps(Material.METAL).notSolid()))
-                .features(AEFeature.INSCRIBER)
-                .tileEntity(registry.tileEntity("inscriber", InscriberBlockEntity.class, InscriberBlockEntity::new)
-                        .rendering(new InscriberRendering()).build())
-                .build();
-        this.wirelessAccessPoint = registry.block("wireless_access_point", WirelessBlock::new)
-                .features(AEFeature.WIRELESS_ACCESS_TERMINAL)
-                .tileEntity(registry
-                        .tileEntity("wireless_access_point", WirelessBlockEntity.class, WirelessBlockEntity::new).build())
-                .rendering(new WirelessRendering()).build();
-        this.charger = registry.block("charger", ChargerBlock::new).features(AEFeature.CHARGER)
-                .tileEntity(registry.tileEntity("charger", ChargerBlockEntity.class, ChargerBlockEntity::new)
-                        .rendering(new TileEntityRenderingCustomizer() {
-                            @Override
-                            @Environment(EnvType.CLIENT)
-                            public void customize(TileEntityRendering rendering) {
-                                rendering.tileEntityRenderer(ChargerBlock.createTesr());
-                            }
-                        }).build())
-                .build();
-
-        TinyTNTPrimedEntity.TYPE = registry
-                .entity("tiny_tnt_primed", TinyTNTPrimedEntity::new, SpawnGroup.MISC)
-                .customize(p -> p.trackable(16, 4, true))
-                .build();
-
-        this.tinyTNT = registry
-                .block("tiny_tnt",
-                        () -> new TinyTNTBlock(
-                                defaultProps(Material.TNT).sounds(BlockSoundGroup.GROUND).strength(0).notSolid()))
-                .features(AEFeature.TINY_TNT).bootstrap((block, item) -> (IInitComponent) () -> DispenserBlock
-                        .registerBehavior(item, new TinyTNTDispenseItemBehavior()))
-                .build();
-        this.securityStation = registry.block("security_station", SecurityStationBlock::new)
-                .features(AEFeature.SECURITY)
-                .tileEntity(registry
-                        .tileEntity("security_station", SecurityStationBlockEntity.class, SecurityStationBlockEntity::new)
-                        .build())
-                .rendering(new SecurityStationRendering()).build();
-
-        TileEntityDefinition quantumRingTile = registry
-                .tileEntity("quantum_ring", QuantumBridgeBlockEntity.class, QuantumBridgeBlockEntity::new).build();
-        this.quantumRing = registry.block("quantum_ring", QuantumRingBlock::new)
-                .features(AEFeature.QUANTUM_NETWORK_BRIDGE).tileEntity(quantumRingTile)
-                .rendering(new QuantumBridgeRendering()).build();
-        this.quantumLink = registry.block("quantum_link", QuantumLinkChamberBlock::new)
-                .features(AEFeature.QUANTUM_NETWORK_BRIDGE).tileEntity(quantumRingTile)
-                .rendering(new QuantumBridgeRendering()).build();
-        this.spatialPylon = registry.block("spatial_pylon", SpatialPylonBlock::new).features(AEFeature.SPATIAL_IO)
-                .tileEntity(registry
-                        .tileEntity("spatial_pylon", SpatialPylonBlockEntity.class, SpatialPylonBlockEntity::new).build())
-                .rendering(new SpatialPylonRendering()).build();
-        this.spatialIOPort = registry.block("spatial_io_port", SpatialIOPortBlock::new).features(AEFeature.SPATIAL_IO)
-                .tileEntity(registry
-                        .tileEntity("spatial_io_port", SpatialIOPortBlockEntity.class, SpatialIOPortBlockEntity::new)
-                        .build())
-                .build();
-        this.controller = registry
-                .block("controller", ControllerBlock::new).features(AEFeature.CHANNELS).tileEntity(registry
-                        .tileEntity("controller", ControllerBlockEntity.class, ControllerBlockEntity::new).build())
-                .rendering(new ControllerRendering()).build();
-        this.drive = registry.block("drive", DriveBlock::new).features(AEFeature.STORAGE_CELLS, AEFeature.ME_DRIVE)
-                .tileEntity(registry.tileEntity("drive", DriveBlockEntity.class, DriveBlockEntity::new)
-                        .rendering(new TileEntityRenderingCustomizer() {
-                            @Override
-                            @Environment(EnvType.CLIENT)
-                            public void customize(TileEntityRendering rendering) {
-                                rendering.tileEntityRenderer(DriveLedTileEntityRenderer::new);
-                            }
-                        }).build())
-                .rendering(new DriveRendering()).build();
-        this.chest = registry.block("chest", ChestBlock::new).features(AEFeature.STORAGE_CELLS, AEFeature.ME_CHEST)
-                .tileEntity(registry.tileEntity("chest", ChestBlockEntity.class, ChestBlockEntity::new).build())
-                .rendering(new ChestRendering()).build();
-        this.iface = registry.block("interface", InterfaceBlock::new).features(AEFeature.INTERFACE)
-                .tileEntity(
-                        registry.tileEntity("interface", InterfaceBlockEntity.class, InterfaceBlockEntity::new).build())
-                .build();
-        this.fluidIface = registry.block("fluid_interface", FluidInterfaceBlock::new)
-                .features(AEFeature.FLUID_INTERFACE)
-                .tileEntity(registry
-                        .tileEntity("fluid_interface", FluidInterfaceBlockEntity.class, FluidInterfaceBlockEntity::new)
-                        .build())
-                .build();
-        this.cellWorkbench = registry.block("cell_workbench", CellWorkbenchBlock::new).features(AEFeature.STORAGE_CELLS)
-                .tileEntity(registry
-                        .tileEntity("cell_workbench", CellWorkbenchBlockEntity.class, CellWorkbenchBlockEntity::new)
-                        .build())
-                .build();
-        this.iOPort = registry.block("io_port", IOPortBlock::new).features(AEFeature.STORAGE_CELLS, AEFeature.IO_PORT)
-                .tileEntity(registry.tileEntity("io_port", IOPortBlockEntity.class, IOPortBlockEntity::new).build())
-                .build();
-        this.condenser = registry.block("condenser", CondenserBlock::new).features(AEFeature.CONDENSER)
-                .tileEntity(
-                        registry.tileEntity("condenser", CondenserBlockEntity.class, CondenserBlockEntity::new).build())
-                .build();
-        this.energyAcceptor = registry.block("energy_acceptor", EnergyAcceptorBlock::new)
-                .features(AEFeature.ENERGY_ACCEPTOR)
-                .tileEntity(registry
-                        .tileEntity("energy_acceptor", EnergyAcceptorBlockEntity.class, EnergyAcceptorBlockEntity::new)
-                        .build())
-                .build();
-        this.vibrationChamber = registry.block("vibration_chamber", VibrationChamberBlock::new)
-                .features(AEFeature.POWER_GEN).tileEntity(registry.tileEntity("vibration_chamber",
-                        VibrationChamberBlockEntity.class, VibrationChamberBlockEntity::new).build())
-                .build();
-        this.quartzGrowthAccelerator = registry.block("quartz_growth_accelerator", QuartzGrowthAcceleratorBlock::new)
-                .tileEntity(registry.tileEntity("quartz_growth_accelerator", QuartzGrowthAcceleratorBlockEntity.class,
-                        QuartzGrowthAcceleratorBlockEntity::new).build())
-                .features(AEFeature.CRYSTAL_GROWTH_ACCELERATOR).build();
-        this.energyCell = registry.block("energy_cell", EnergyCellBlock::new).features(AEFeature.ENERGY_CELLS)
-                .item(AEBaseBlockItemChargeable::new).tileEntity(registry
-                        .tileEntity("energy_cell", EnergyCellBlockEntity.class, EnergyCellBlockEntity::new).build())
-                .build();
-        this.energyCellDense = registry.block("dense_energy_cell", DenseEnergyCellBlock::new)
-                .features(AEFeature.ENERGY_CELLS, AEFeature.DENSE_ENERGY_CELLS).item(AEBaseBlockItemChargeable::new)
-                .tileEntity(registry.tileEntity("dense_energy_cell", DenseEnergyCellBlockEntity.class,
-                        DenseEnergyCellBlockEntity::new).build())
-                .build();
-        this.energyCellCreative = registry.block("creative_energy_cell", CreativeEnergyCellBlock::new)
-                .features(AEFeature.CREATIVE).tileEntity(registry.tileEntity("creative_energy_cell",
-                        CreativeEnergyCellBlockEntity.class, CreativeEnergyCellBlockEntity::new).build())
-                .build();
-
-        TileEntityDefinition craftingUnit = registry
-                .tileEntity("crafting_unit", CraftingBlockEntity.class, CraftingBlockEntity::new).build();
-
-        FeatureFactory crafting = registry.features(AEFeature.CRAFTING_CPU);
-        AbstractBlock.Settings craftingBlockProps = defaultProps(Material.METAL);
-        this.craftingUnit = crafting
-                .block("crafting_unit", () -> new CraftingUnitBlock(craftingBlockProps, CraftingUnitType.UNIT))
-                .rendering(new CraftingCubeRendering()).tileEntity(craftingUnit).build();
-        this.craftingAccelerator = crafting
-                .block("crafting_accelerator",
-                        () -> new CraftingUnitBlock(craftingBlockProps, CraftingUnitType.ACCELERATOR))
-                .rendering(new CraftingCubeRendering()).tileEntity(craftingUnit).build();
-
-        TileEntityDefinition craftingStorage = registry
-                .tileEntity("crafting_storage", CraftingStorageBlockEntity.class, CraftingStorageBlockEntity::new)
-                .build();
-        this.craftingStorage1k = crafting
-                .block("1k_crafting_storage",
-                        () -> new CraftingStorageBlock(craftingBlockProps, CraftingUnitType.STORAGE_1K))
-                .item(CraftingStorageItem::new).tileEntity(craftingStorage).rendering(new CraftingCubeRendering())
-                .build();
-        this.craftingStorage4k = crafting
-                .block("4k_crafting_storage",
-                        () -> new CraftingStorageBlock(craftingBlockProps, CraftingUnitType.STORAGE_4K))
-                .item(CraftingStorageItem::new).tileEntity(craftingStorage).rendering(new CraftingCubeRendering())
-                .build();
-        this.craftingStorage16k = crafting
-                .block("16k_crafting_storage",
-                        () -> new CraftingStorageBlock(craftingBlockProps, CraftingUnitType.STORAGE_16K))
-                .item(CraftingStorageItem::new).tileEntity(craftingStorage).rendering(new CraftingCubeRendering())
-                .build();
-        this.craftingStorage64k = crafting
-                .block("64k_crafting_storage",
-                        () -> new CraftingStorageBlock(craftingBlockProps, CraftingUnitType.STORAGE_64K))
-                .item(CraftingStorageItem::new).tileEntity(craftingStorage).rendering(new CraftingCubeRendering())
-                .build();
-        this.craftingMonitor = crafting.block("crafting_monitor", () -> new CraftingMonitorBlock(craftingBlockProps))
-                .tileEntity(registry
-                        .tileEntity("crafting_monitor", CraftingMonitorBlockEntity.class, CraftingMonitorBlockEntity::new)
-                        .rendering(new TileEntityRenderingCustomizer() {
-                            @Environment(EnvType.CLIENT)
-                            @Override
-                            public void customize(TileEntityRendering rendering) {
-                                rendering.tileEntityRenderer(CraftingMonitorTESR::new);
-                            }
-                        }).build())
-                .rendering(new BlockRenderingCustomizer() {
-                    @Override
-                    @Environment(EnvType.CLIENT)
-                    public void customize(IBlockRendering rendering, IItemRendering itemRendering) {
-                        rendering.renderType(RenderLayer.getCutout());
-                        rendering.modelCustomizer((path, model) -> {
-                            // The formed model handles rotations itself, the unformed one does not
-                            if (model instanceof MonitorBakedModel) {
-                                return model;
-                            }
-                            return new AutoRotatingBakedModel(model);
-                        });
-                    }
-                }).build();
-
-        this.molecularAssembler = registry
-                .block("molecular_assembler", () -> new MolecularAssemblerBlock(defaultProps(Material.METAL).notSolid()))
-                .features(AEFeature.MOLECULAR_ASSEMBLER).rendering(new BlockRenderingCustomizer() {
-                    @Environment(EnvType.CLIENT)
-                    @Override
-                    public void customize(IBlockRendering rendering, IItemRendering itemRendering) {
-                        rendering.renderType(RenderLayer.getCutout());
-                    }
-                })
-                .tileEntity(registry
-                        .tileEntity("molecular_assembler", MolecularAssemblerBlockEntity.class,
-                                MolecularAssemblerBlockEntity::new)
-                        .rendering(new TileEntityRenderingCustomizer() {
-                            @Override
-                            @Environment(EnvType.CLIENT)
-                            public void customize(TileEntityRendering rendering) {
-                                rendering.tileEntityRenderer(MolecularAssemblerRenderer::new);
-                            }
-                        }).build())
-                .build();
-
-        this.lightDetector = registry.block("light_detector", LightDetectorBlock::new)
-                .features(AEFeature.LIGHT_DETECTOR)
-                .tileEntity(registry
-                        .tileEntity("light_detector", LightDetectorBlockEntity.class, LightDetectorBlockEntity::new)
-                        .build())
-                .rendering(new BlockRenderingCustomizer() {
-                    @Override
-                    @Environment(EnvType.CLIENT)
-                    public void customize(IBlockRendering rendering, IItemRendering itemRendering) {
-                        rendering.renderType(RenderLayer.getCutout());
-                    }
-                }).build();
-        this.paint = registry
-                .block("paint", PaintSplotchesBlock::new).features(AEFeature.PAINT_BALLS).tileEntity(registry
-                        .tileEntity("paint", PaintSplotchesBlockEntity.class, PaintSplotchesBlockEntity::new).build())
-                .rendering(new PaintSplotchesRendering()).build();
-
-        this.skyStoneStairs = deco
-                .block("sky_stone_stairs",
-                        () -> new StairsBlock(this.skyStoneBlock().block()::getDefaultState, SKYSTONE_PROPERTIES))
-                .addFeatures(AEFeature.SKY_STONE).build();
-        this.smoothSkyStoneStairs = deco
-                .block("smooth_sky_stone_stairs",
-                        () -> new StairsBlock(this.smoothSkyStoneBlock().block()::getDefaultState, SKYSTONE_PROPERTIES))
-                .addFeatures(AEFeature.SKY_STONE).build();
-        this.skyStoneBrickStairs = deco
-                .block("sky_stone_brick_stairs",
-                        () -> new StairsBlock(this.skyStoneBrick().block()::getDefaultState, SKYSTONE_PROPERTIES))
-                .addFeatures(AEFeature.SKY_STONE).build();
-        this.skyStoneSmallBrickStairs = deco
-                .block("sky_stone_small_brick_stairs",
-                        () -> new StairsBlock(this.skyStoneSmallBrick().block()::getDefaultState, SKYSTONE_PROPERTIES))
-                .addFeatures(AEFeature.SKY_STONE).build();
-
-        this.fluixStairs = deco
-                .block("fluix_stairs",
-                        () -> new StairsBlock(this.fluixBlock().block()::getDefaultState, QUARTZ_PROPERTIES))
-                .addFeatures(AEFeature.FLUIX).build();
-        this.quartzStairs = deco
-                .block("quartz_stairs",
-                        () -> new StairsBlock(this.quartzBlock().block()::getDefaultState, QUARTZ_PROPERTIES))
-                .addFeatures(AEFeature.CERTUS).build();
-        this.chiseledQuartzStairs = deco
-                .block("chiseled_quartz_stairs",
-                        () -> new StairsBlock(this.chiseledQuartzBlock().block()::getDefaultState, QUARTZ_PROPERTIES))
-                .addFeatures(AEFeature.CERTUS).build();
-        this.quartzPillarStairs = deco
-                .block("quartz_pillar_stairs",
-                        () -> new StairsBlock(this.quartzPillar().block()::getDefaultState, QUARTZ_PROPERTIES))
-                .addFeatures(AEFeature.CERTUS).build();
-
-        this.multiPart = registry.block("cable_bus", CableBusBlock::new).rendering(new CableBusRendering())
-                .tileEntity(registry.tileEntity("cable_bus", CableBusBlockEntity.class, CableBusBlockEntity::new)
-                        .rendering(new TileEntityRenderingCustomizer() {
-                            @Override
-                            @Environment(EnvType.CLIENT)
-                            public void customize(TileEntityRendering rendering) {
-                                rendering.tileEntityRenderer(CableBusTESR::new);
-                            }
-                        }).build())
-                .build();
-
-        this.skyStoneSlab = deco.block("sky_stone_slab", () -> new SlabBlock(SKYSTONE_PROPERTIES))
-                .addFeatures(AEFeature.SKY_STONE).build();
-        this.smoothSkyStoneSlab = deco.block("smooth_sky_stone_slab", () -> new SlabBlock(SKYSTONE_PROPERTIES))
-                .addFeatures(AEFeature.SKY_STONE).build();
-        this.skyStoneBrickSlab = deco.block("sky_stone_brick_slab", () -> new SlabBlock(SKYSTONE_PROPERTIES))
-                .addFeatures(AEFeature.SKY_STONE).build();
-        this.skyStoneSmallBrickSlab = deco.block("sky_stone_small_brick_slab", () -> new SlabBlock(SKYSTONE_PROPERTIES))
-                .addFeatures(AEFeature.SKY_STONE).build();
-
-        this.fluixSlab = deco.block("fluix_slab", () -> new SlabBlock(QUARTZ_PROPERTIES)).addFeatures(AEFeature.FLUIX)
-                .build();
-        this.quartzSlab = deco.block("quartz_slab", () -> new SlabBlock(QUARTZ_PROPERTIES))
-                .addFeatures(AEFeature.CERTUS).build();
-        this.chiseledQuartzSlab = deco.block("chiseled_quartz_slab", () -> new SlabBlock(QUARTZ_PROPERTIES))
-                .addFeatures(AEFeature.CERTUS).build();
-        this.quartzPillarSlab = deco.block("quartz_pillar_slab", () -> new SlabBlock(QUARTZ_PROPERTIES))
-                .addFeatures(AEFeature.CERTUS).build();
-
-        this.itemGen = registry.block("debug_item_gen", ItemGenBlock::new)
-                .features(AEFeature.UNSUPPORTED_DEVELOPER_TOOLS, AEFeature.CREATIVE)
-                .tileEntity(
-                        registry.tileEntity("debug_item_gen", ItemGenBlockEntity.class, ItemGenBlockEntity::new).build())
-                .build();
-        this.chunkLoader = registry.block("debug_chunk_loader", ChunkLoaderBlock::new)
-                .features(AEFeature.UNSUPPORTED_DEVELOPER_TOOLS, AEFeature.CREATIVE)
-                .tileEntity(registry
-                        .tileEntity("debug_chunk_loader", ChunkLoaderBlockEntity.class, ChunkLoaderBlockEntity::new)
-                        .build())
-                .build();
-        this.phantomNode = registry.block("debug_phantom_node", PhantomNodeBlock::new)
-                .features(AEFeature.UNSUPPORTED_DEVELOPER_TOOLS, AEFeature.CREATIVE)
-                .tileEntity(registry
-                        .tileEntity("debug_phantom_node", PhantomNodeBlockEntity.class, PhantomNodeBlockEntity::new)
-                        .build())
-                .build();
-        this.cubeGenerator = registry.block("debug_cube_gen", CubeGeneratorBlock::new)
-                .features(AEFeature.UNSUPPORTED_DEVELOPER_TOOLS, AEFeature.CREATIVE)
-                .tileEntity(registry
-                        .tileEntity("debug_cube_gen", CubeGeneratorBlockEntity.class, CubeGeneratorBlockEntity::new)
-                        .build())
-                .build();
-        this.energyGenerator = registry.block("debug_energy_gen", EnergyGeneratorBlock::new)
-                .features(AEFeature.UNSUPPORTED_DEVELOPER_TOOLS, AEFeature.CREATIVE)
-                .tileEntity(registry
-                        .tileEntity("debug_energy_gen", EnergyGeneratorBlockEntity.class, EnergyGeneratorBlockEntity::new)
-                        .build())
-                .build();
-    }
-
-    @Override
-    public IBlockDefinition quartzOre() {
-        return this.quartzOre;
-    }
-
-    @Override
-    public IBlockDefinition quartzOreCharged() {
-        return this.quartzOreCharged;
-    }
-
-    @Override
-    public IBlockDefinition matrixFrame() {
-        return this.matrixFrame;
-    }
-
-    @Override
-    public IBlockDefinition quartzBlock() {
-        return this.quartzBlock;
-    }
-
-    @Override
-    public IBlockDefinition quartzPillar() {
-        return this.quartzPillar;
-    }
-
-    @Override
-    public IBlockDefinition chiseledQuartzBlock() {
-        return this.chiseledQuartzBlock;
-    }
-
-    @Override
-    public IBlockDefinition quartzGlass() {
-        return this.quartzGlass;
-    }
-
-    @Override
-    public IBlockDefinition quartzVibrantGlass() {
-        return this.quartzVibrantGlass;
-    }
-
-    @Override
-    public IBlockDefinition quartzFixture() {
-        return this.quartzFixture;
-    }
-
-    @Override
-    public IBlockDefinition fluixBlock() {
-        return this.fluixBlock;
-    }
-
-    @Override
-    public IBlockDefinition skyStoneBlock() {
-        return this.skyStoneBlock;
-    }
-
-    @Override
-    public IBlockDefinition smoothSkyStoneBlock() {
-        return this.smoothSkyStoneBlock;
-    }
-
-    @Override
-    public IBlockDefinition skyStoneBrick() {
-        return this.skyStoneBrick;
-    }
-
-    @Override
-    public IBlockDefinition skyStoneSmallBrick() {
-        return this.skyStoneSmallBrick;
-    }
-
-    @Override
-    public IBlockDefinition skyStoneChest() {
-        return this.skyStoneChest;
-    }
-
-    @Override
-    public IBlockDefinition smoothSkyStoneChest() {
-        return this.smoothSkyStoneChest;
-    }
-
-    @Override
-    public IBlockDefinition skyCompass() {
-        return this.skyCompass;
-    }
-
-    @Override
-    public IBlockDefinition skyStoneStairs() {
-        return this.skyStoneStairs;
-    }
-
-    @Override
-    public IBlockDefinition smoothSkyStoneStairs() {
-        return this.smoothSkyStoneStairs;
-    }
-
-    @Override
-    public IBlockDefinition skyStoneBrickStairs() {
-        return this.skyStoneBrickStairs;
-    }
-
-    @Override
-    public IBlockDefinition skyStoneSmallBrickStairs() {
-        return this.skyStoneSmallBrickStairs;
-    }
-
-    @Override
-    public IBlockDefinition fluixStairs() {
-        return this.fluixStairs;
-    }
-
-    @Override
-    public IBlockDefinition quartzStairs() {
-        return this.quartzStairs;
-    }
-
-    @Override
-    public IBlockDefinition chiseledQuartzStairs() {
-        return this.chiseledQuartzStairs;
-    }
-
-    @Override
-    public IBlockDefinition quartzPillarStairs() {
-        return this.quartzPillarStairs;
-    }
-
-    @Override
-    public IBlockDefinition skyStoneSlab() {
-        return this.skyStoneSlab;
-    }
-
-    @Override
-    public IBlockDefinition smoothSkyStoneSlab() {
-        return this.smoothSkyStoneSlab;
-    }
-
-    @Override
-    public IBlockDefinition skyStoneBrickSlab() {
-        return this.skyStoneBrickSlab;
-    }
-
-    @Override
-    public IBlockDefinition skyStoneSmallBrickSlab() {
-        return this.skyStoneSmallBrickSlab;
-    }
-
-    @Override
-    public IBlockDefinition fluixSlab() {
-        return this.fluixSlab;
-    }
-
-    @Override
-    public IBlockDefinition quartzSlab() {
-        return this.quartzSlab;
-    }
-
-    @Override
-    public IBlockDefinition chiseledQuartzSlab() {
-        return this.chiseledQuartzSlab;
-    }
-
-    @Override
-    public IBlockDefinition quartzPillarSlab() {
-        return this.quartzPillarSlab;
-    }
-
-    @Override
-    public ITileDefinition grindstone() {
-        return this.grindstone;
-    }
-
-    @Override
-    public ITileDefinition crank() {
-        return this.crank;
-    }
-
-    @Override
-    public ITileDefinition inscriber() {
-        return this.inscriber;
-    }
-
-    @Override
-    public ITileDefinition wirelessAccessPoint() {
-        return this.wirelessAccessPoint;
-    }
-
-    @Override
-    public ITileDefinition charger() {
-        return this.charger;
-    }
-
-    @Override
-    public IBlockDefinition tinyTNT() {
-        return this.tinyTNT;
-    }
-
-    @Override
-    public ITileDefinition securityStation() {
-        return this.securityStation;
-    }
-
-    @Override
-    public ITileDefinition quantumRing() {
-        return this.quantumRing;
-    }
-
-    @Override
-    public ITileDefinition quantumLink() {
-        return this.quantumLink;
-    }
-
-    @Override
-    public ITileDefinition spatialPylon() {
-        return this.spatialPylon;
-    }
-
-    @Override
-    public ITileDefinition spatialIOPort() {
-        return this.spatialIOPort;
-    }
-
-    @Override
-    public ITileDefinition multiPart() {
-        return this.multiPart;
-    }
-
-    @Override
-    public ITileDefinition controller() {
-        return this.controller;
-    }
-
-    @Override
-    public ITileDefinition drive() {
-        return this.drive;
-    }
-
-    @Override
-    public ITileDefinition chest() {
-        return this.chest;
-    }
-
-    @Override
-    public ITileDefinition iface() {
-        return this.iface;
-    }
-
-    @Override
-    public ITileDefinition fluidIface() {
-        return this.fluidIface;
-    }
-
-    @Override
-    public ITileDefinition cellWorkbench() {
-        return this.cellWorkbench;
-    }
-
-    @Override
-    public ITileDefinition iOPort() {
-        return this.iOPort;
-    }
-
-    @Override
-    public ITileDefinition condenser() {
-        return this.condenser;
-    }
-
-    @Override
-    public ITileDefinition energyAcceptor() {
-        return this.energyAcceptor;
-    }
-
-    @Override
-    public ITileDefinition vibrationChamber() {
-        return this.vibrationChamber;
-    }
-
-    @Override
-    public ITileDefinition quartzGrowthAccelerator() {
-        return this.quartzGrowthAccelerator;
-    }
-
-    @Override
-    public ITileDefinition energyCell() {
-        return this.energyCell;
-    }
-
-    @Override
-    public ITileDefinition energyCellDense() {
-        return this.energyCellDense;
-    }
-
-    @Override
-    public ITileDefinition energyCellCreative() {
-        return this.energyCellCreative;
-    }
-
-    @Override
-    public ITileDefinition craftingUnit() {
-        return this.craftingUnit;
-    }
-
-    @Override
-    public ITileDefinition craftingAccelerator() {
-        return this.craftingAccelerator;
-    }
-
-    @Override
-    public ITileDefinition craftingStorage1k() {
-        return this.craftingStorage1k;
-    }
-
-    @Override
-    public ITileDefinition craftingStorage4k() {
-        return this.craftingStorage4k;
-    }
-
-    @Override
-    public ITileDefinition craftingStorage16k() {
-        return this.craftingStorage16k;
-    }
-
-    @Override
-    public ITileDefinition craftingStorage64k() {
-        return this.craftingStorage64k;
-    }
-
-    @Override
-    public ITileDefinition craftingMonitor() {
-        return this.craftingMonitor;
-    }
-
-    @Override
-    public ITileDefinition molecularAssembler() {
-        return this.molecularAssembler;
-    }
-
-    @Override
-    public ITileDefinition lightDetector() {
-        return this.lightDetector;
-    }
-
-    @Override
-    public ITileDefinition paint() {
-        return this.paint;
-    }
-
-    public IBlockDefinition chunkLoader() {
-        return this.chunkLoader;
-    }
-
-    public IBlockDefinition itemGen() {
-        return this.itemGen;
-    }
-
-    public IBlockDefinition phantomNode() {
-        return this.phantomNode;
-    }
-
-    public IBlockDefinition cubeGenerator() {
-        return this.cubeGenerator;
-    }
-
-    public IBlockDefinition energyGenerator() {
-        return this.energyGenerator;
-    }
-}
diff --git a/src/main/java/appeng/core/api/definitions/ApiItems.java b/src/main/java/appeng/core/api/definitions/ApiItems.java
deleted file mode 100644
index 5ddfb27c9..000000000
--- a/src/main/java/appeng/core/api/definitions/ApiItems.java
+++ /dev/null
@@ -1,559 +0,0 @@
-/*
- * This file is part of Applied Energistics 2.
- * Copyright (c) 2013 - 2015, AlgorithmX2, All rights reserved.
- *
- * Applied Energistics 2 is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * Applied Energistics 2 is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with Applied Energistics 2.  If not, see .
- */
-
-package appeng.core.api.definitions;
-
-import java.util.function.Consumer;
-
-import net.fabricmc.fabric.api.tool.attribute.v1.FabricToolTags;
-import net.minecraft.entity.SpawnGroup;
-import net.minecraft.item.Item;
-import net.minecraft.item.ItemGroup;
-
-import appeng.api.definitions.IItemDefinition;
-import appeng.api.definitions.IItems;
-import appeng.api.features.AEFeature;
-import appeng.api.util.AEColor;
-import appeng.api.util.AEColoredItemDefinition;
-import appeng.bootstrap.FeatureFactory;
-import appeng.core.features.ActivityState;
-import appeng.core.features.ColoredItemDefinition;
-import appeng.core.features.ItemStackSrc;
-import appeng.debug.DebugCardItem;
-import appeng.debug.DebugPartPlacerItem;
-import appeng.debug.EraserItem;
-import appeng.debug.MeteoritePlacerItem;
-import appeng.debug.ReplicatorCardItem;
-import appeng.entity.GrowingCrystalEntity;
-import appeng.fluids.items.BasicFluidStorageCell;
-import appeng.fluids.items.FluidDummyItem;
-import appeng.fluids.items.FluidDummyItemRendering;
-import appeng.hooks.BlockToolDispenseItemBehavior;
-import appeng.hooks.MatterCannonDispenseItemBehavior;
-import appeng.items.materials.MaterialType;
-import appeng.items.misc.CrystalSeedItem;
-import appeng.items.misc.EncodedPatternItem;
-import appeng.items.misc.PaintBallItem;
-import appeng.items.misc.PaintBallItemRendering;
-import appeng.items.parts.FacadeItem;
-import appeng.items.storage.BasicStorageCellItem;
-import appeng.items.storage.CreativeStorageCellItem;
-import appeng.items.storage.SpatialStorageCellItem;
-import appeng.items.storage.ViewCellItem;
-import appeng.items.tools.BiometricCardItem;
-import appeng.items.tools.MemoryCardItem;
-import appeng.items.tools.NetworkToolItem;
-import appeng.items.tools.powered.ChargedStaffItem;
-import appeng.items.tools.powered.ColorApplicatorItem;
-import appeng.items.tools.powered.ColorApplicatorItemRendering;
-import appeng.items.tools.powered.EntropyManipulatorItem;
-import appeng.items.tools.powered.MatterCannonItem;
-import appeng.items.tools.powered.PortableCellItem;
-import appeng.items.tools.powered.WirelessTerminalItem;
-import appeng.items.tools.quartz.QuartzAxeItem;
-import appeng.items.tools.quartz.QuartzCuttingKnifeItem;
-import appeng.items.tools.quartz.QuartzHoeItem;
-import appeng.items.tools.quartz.QuartzPickaxeItem;
-import appeng.items.tools.quartz.QuartzSpadeItem;
-import appeng.items.tools.quartz.QuartzSwordItem;
-import appeng.items.tools.quartz.QuartzWrenchItem;
-
-/**
- * Internal implementation for the API items
- */
-public final class ApiItems implements IItems {
-    private final IItemDefinition certusQuartzAxe;
-    private final IItemDefinition certusQuartzHoe;
-    private final IItemDefinition certusQuartzShovel;
-    private final IItemDefinition certusQuartzPick;
-    private final IItemDefinition certusQuartzSword;
-    private final IItemDefinition certusQuartzWrench;
-    private final IItemDefinition certusQuartzKnife;
-
-    private final IItemDefinition netherQuartzAxe;
-    private final IItemDefinition netherQuartzHoe;
-    private final IItemDefinition netherQuartzShovel;
-    private final IItemDefinition netherQuartzPick;
-    private final IItemDefinition netherQuartzSword;
-    private final IItemDefinition netherQuartzWrench;
-    private final IItemDefinition netherQuartzKnife;
-
-    private final IItemDefinition entropyManipulator;
-    private final IItemDefinition wirelessTerminal;
-    private final IItemDefinition biometricCard;
-    private final IItemDefinition chargedStaff;
-    private final IItemDefinition massCannon;
-    private final IItemDefinition memoryCard;
-    private final IItemDefinition networkTool;
-    private final IItemDefinition portableCell;
-
-    private final IItemDefinition cellCreative;
-    private final IItemDefinition viewCell;
-
-    private final IItemDefinition cell1k;
-    private final IItemDefinition cell4k;
-    private final IItemDefinition cell16k;
-    private final IItemDefinition cell64k;
-
-    private final IItemDefinition fluidCell1k;
-    private final IItemDefinition fluidCell4k;
-    private final IItemDefinition fluidCell16k;
-    private final IItemDefinition fluidCell64k;
-
-    private final IItemDefinition spatialCell2;
-    private final IItemDefinition spatialCell16;
-    private final IItemDefinition spatialCell128;
-
-    private final IItemDefinition facade;
-    private final IItemDefinition certusCrystalSeed;
-    private final IItemDefinition fluixCrystalSeed;
-    private final IItemDefinition netherQuartzSeed;
-
-    // rv1
-    private final IItemDefinition encodedPattern;
-    private final IItemDefinition colorApplicator;
-
-    private final AEColoredItemDefinition coloredPaintBall;
-    private final AEColoredItemDefinition coloredLumenPaintBall;
-
-    // unsupported dev tools
-    private final IItemDefinition toolEraser;
-    private final IItemDefinition toolMeteoritePlacer;
-    private final IItemDefinition toolDebugCard;
-    private final IItemDefinition toolReplicatorCard;
-
-    private final IItemDefinition dummyFluidItem;
-
-    public ApiItems(FeatureFactory registry, ApiMaterials materials) {
-        FeatureFactory certusTools = registry.features(AEFeature.CERTUS_QUARTZ_TOOLS);
-        this.certusQuartzAxe = certusTools
-                .item("certus_quartz_axe", props -> new QuartzAxeItem(props, AEFeature.CERTUS_QUARTZ_TOOLS))
-                .itemGroup(ItemGroup.TOOLS).addFeatures(AEFeature.QUARTZ_AXE).build();
-        this.certusQuartzHoe = certusTools
-                .item("certus_quartz_hoe", props -> new QuartzHoeItem(props, AEFeature.CERTUS_QUARTZ_TOOLS))
-                .itemGroup(ItemGroup.TOOLS).addFeatures(AEFeature.QUARTZ_HOE).build();
-        this.certusQuartzShovel = certusTools
-                .item("certus_quartz_shovel", props -> new QuartzSpadeItem(props, AEFeature.CERTUS_QUARTZ_TOOLS))
-                .itemGroup(ItemGroup.TOOLS).addFeatures(AEFeature.QUARTZ_SPADE).build();
-        this.certusQuartzPick = certusTools
-                .item("certus_quartz_pickaxe", props -> new QuartzPickaxeItem(props, AEFeature.CERTUS_QUARTZ_TOOLS))
-                .itemGroup(ItemGroup.TOOLS).addFeatures(AEFeature.QUARTZ_PICKAXE).build();
-        this.certusQuartzSword = certusTools
-                .item("certus_quartz_sword", props -> new QuartzSwordItem(props, AEFeature.CERTUS_QUARTZ_TOOLS))
-                .itemGroup(ItemGroup.COMBAT).addFeatures(AEFeature.QUARTZ_SWORD).build();
-        this.certusQuartzWrench = certusTools.item("certus_quartz_wrench", QuartzWrenchItem::new)
-                .itemGroup(ItemGroup.TOOLS).props(props -> props.maxStackSize(1)).addFeatures(AEFeature.QUARTZ_WRENCH)
-                .build();
-        this.certusQuartzKnife = certusTools
-                .item("certus_quartz_cutting_knife",
-                        props -> new QuartzCuttingKnifeItem(props, AEFeature.CERTUS_QUARTZ_TOOLS))
-                .itemGroup(ItemGroup.TOOLS).props(props -> props.maxStackSize(1).maxDamage(50).setNoRepair())
-                .addFeatures(AEFeature.QUARTZ_KNIFE).build();
-
-        FeatureFactory netherTools = registry.features(AEFeature.NETHER_QUARTZ_TOOLS);
-        this.netherQuartzAxe = netherTools
-                .item("nether_quartz_axe", props -> new QuartzAxeItem(props, AEFeature.NETHER_QUARTZ_TOOLS))
-                .itemGroup(ItemGroup.TOOLS).addFeatures(AEFeature.QUARTZ_AXE).build();
-        this.netherQuartzHoe = netherTools
-                .item("nether_quartz_hoe", props -> new QuartzHoeItem(props, AEFeature.NETHER_QUARTZ_TOOLS))
-                .itemGroup(ItemGroup.TOOLS).addFeatures(AEFeature.QUARTZ_HOE).build();
-        this.netherQuartzShovel = netherTools
-                .item("nether_quartz_shovel", props -> new QuartzSpadeItem(props, AEFeature.NETHER_QUARTZ_TOOLS))
-                .itemGroup(ItemGroup.TOOLS).addFeatures(AEFeature.QUARTZ_SPADE).build();
-        this.netherQuartzPick = netherTools
-                .item("nether_quartz_pickaxe", props -> new QuartzPickaxeItem(props, AEFeature.NETHER_QUARTZ_TOOLS))
-                .itemGroup(ItemGroup.TOOLS).addFeatures(AEFeature.QUARTZ_PICKAXE).build();
-        this.netherQuartzSword = netherTools
-                .item("nether_quartz_sword", props -> new QuartzSwordItem(props, AEFeature.NETHER_QUARTZ_TOOLS))
-                .itemGroup(ItemGroup.COMBAT).addFeatures(AEFeature.QUARTZ_SWORD).build();
-        this.netherQuartzWrench = netherTools.item("nether_quartz_wrench", QuartzWrenchItem::new)
-                .itemGroup(ItemGroup.TOOLS).props(props -> props.maxStackSize(1)).addFeatures(AEFeature.QUARTZ_WRENCH)
-                .build();
-        this.netherQuartzKnife = netherTools
-                .item("nether_quartz_cutting_knife",
-                        props -> new QuartzCuttingKnifeItem(props, AEFeature.NETHER_QUARTZ_TOOLS))
-                .itemGroup(ItemGroup.TOOLS).props(props -> props.maxStackSize(1).maxDamage(50).setNoRepair())
-                .addFeatures(AEFeature.QUARTZ_KNIFE).build();
-
-        Consumer chargedDefaults = props -> props.maxStackSize(1).maxDamage(32).setNoRepair();
-
-        FeatureFactory powerTools = registry.features(AEFeature.POWERED_TOOLS);
-        this.entropyManipulator = powerTools.item("entropy_manipulator", EntropyManipulatorItem::new)
-                .props(chargedDefaults).addFeatures(AEFeature.ENTROPY_MANIPULATOR)
-                .dispenserBehavior(BlockToolDispenseItemBehavior::new).build();
-        this.wirelessTerminal = powerTools.item("wireless_terminal", WirelessTerminalItem::new).props(chargedDefaults)
-                .addFeatures(AEFeature.WIRELESS_ACCESS_TERMINAL).build();
-        this.chargedStaff = powerTools.item("charged_staff", ChargedStaffItem::new).props(chargedDefaults)
-                .addFeatures(AEFeature.CHARGED_STAFF).build();
-        this.massCannon = powerTools.item("matter_cannon", MatterCannonItem::new).props(chargedDefaults)
-                .addFeatures(AEFeature.MATTER_CANNON).dispenserBehavior(MatterCannonDispenseItemBehavior::new).build();
-        this.portableCell = powerTools.item("portable_cell", PortableCellItem::new).props(chargedDefaults)
-                .addFeatures(AEFeature.PORTABLE_CELL, AEFeature.STORAGE_CELLS).build();
-        this.colorApplicator = powerTools.item("color_applicator", ColorApplicatorItem::new).props(chargedDefaults)
-                .addFeatures(AEFeature.COLOR_APPLICATOR).dispenserBehavior(BlockToolDispenseItemBehavior::new)
-                .rendering(new ColorApplicatorItemRendering()).build();
-
-        this.biometricCard = registry.item("biometric_card", BiometricCardItem::new)
-                .props(props -> props.maxStackSize(1)).features(AEFeature.SECURITY).build();
-        this.memoryCard = registry.item("memory_card", MemoryCardItem::new).props(props -> props.maxStackSize(1))
-                .features(AEFeature.MEMORY_CARD).build();
-        this.networkTool = registry.item("network_tool", NetworkToolItem::new)
-                .props(props -> props.maxStackSize(1).addToolType(FabricToolTags.get("wrench"), 0))
-                .features(AEFeature.NETWORK_TOOL).build();
-
-        this.cellCreative = registry.item("creative_storage_cell", CreativeStorageCellItem::new)
-                .props(props -> props.maxStackSize(1)).features(AEFeature.STORAGE_CELLS, AEFeature.CREATIVE).build();
-        this.viewCell = registry.item("view_cell", ViewCellItem::new).props(props -> props.maxStackSize(1))
-                .features(AEFeature.VIEW_CELL).build();
-
-        Consumer storageCellProps = p -> p.maxStackSize(1);
-
-        FeatureFactory storageCells = registry.features(AEFeature.STORAGE_CELLS);
-        this.cell1k = storageCells
-                .item("1k_storage_cell",
-                        props -> new BasicStorageCellItem(props, MaterialType.ITEM_1K_CELL_COMPONENT, 1))
-                .props(storageCellProps).build();
-        this.cell4k = storageCells
-                .item("4k_storage_cell",
-                        props -> new BasicStorageCellItem(props, MaterialType.ITEM_4K_CELL_COMPONENT, 4))
-                .props(storageCellProps).build();
-        this.cell16k = storageCells
-                .item("16k_storage_cell",
-                        props -> new BasicStorageCellItem(props, MaterialType.ITEM_16K_CELL_COMPONENT, 16))
-                .props(storageCellProps).build();
-        this.cell64k = storageCells
-                .item("64k_storage_cell",
-                        props -> new BasicStorageCellItem(props, MaterialType.ITEM_64K_CELL_COMPONENT, 64))
-                .props(storageCellProps).build();
-
-        this.fluidCell1k = storageCells
-                .item("1k_fluid_storage_cell",
-                        props -> new BasicFluidStorageCell(props, MaterialType.FLUID_1K_CELL_COMPONENT, 1))
-                .props(storageCellProps).build();
-        this.fluidCell4k = storageCells
-                .item("4k_fluid_storage_cell",
-                        props -> new BasicFluidStorageCell(props, MaterialType.FLUID_4K_CELL_COMPONENT, 4))
-                .props(storageCellProps).build();
-        this.fluidCell16k = storageCells
-                .item("16k_fluid_storage_cell",
-                        props -> new BasicFluidStorageCell(props, MaterialType.FLUID_16K_CELL_COMPONENT, 16))
-                .props(storageCellProps).build();
-        this.fluidCell64k = storageCells
-                .item("64k_fluid_storage_cell",
-                        props -> new BasicFluidStorageCell(props, MaterialType.FLUID_64K_CELL_COMPONENT, 64))
-                .props(storageCellProps).build();
-
-        FeatureFactory spatialCells = registry.features(AEFeature.SPATIAL_IO);
-        this.spatialCell2 = spatialCells
-                .item("2_cubed_spatial_storage_cell", props -> new SpatialStorageCellItem(props, 2))
-                .props(storageCellProps).build();
-        this.spatialCell16 = spatialCells
-                .item("16_cubed_spatial_storage_cell", props -> new SpatialStorageCellItem(props, 16))
-                .props(storageCellProps).build();
-        this.spatialCell128 = spatialCells
-                .item("128_cubed_spatial_storage_cell", props -> new SpatialStorageCellItem(props, 128))
-                .props(storageCellProps).build();
-
-        this.facade = registry.item("facade", FacadeItem::new).features(AEFeature.FACADES).build();
-
-        this.certusCrystalSeed = registry
-                .item("certus_crystal_seed",
-                        props -> new CrystalSeedItem(props, materials.purifiedCertusQuartzCrystal().item()))
-                .features(AEFeature.CRYSTAL_SEEDS).build();
-        this.fluixCrystalSeed = registry
-                .item("fluix_crystal_seed",
-                        props -> new CrystalSeedItem(props, materials.purifiedFluixCrystal().item()))
-                .features(AEFeature.CRYSTAL_SEEDS).build();
-        this.netherQuartzSeed = registry
-                .item("nether_quartz_seed",
-                        props -> new CrystalSeedItem(props, materials.purifiedNetherQuartzCrystal().item()))
-                .features(AEFeature.CRYSTAL_SEEDS).build();
-
-        GrowingCrystalEntity.TYPE = registry
-                .entity("growing_crystal", GrowingCrystalEntity::new, SpawnGroup.MISC)
-                .customize(builder -> builder.size(0.25F, 0.25F)).build();
-
-        // rv1
-        this.encodedPattern = registry.item("encoded_pattern", EncodedPatternItem::new)
-                .props(props -> props.maxStackSize(1)).features(AEFeature.PATTERNS).build();
-
-        this.coloredPaintBall = createPaintBalls(registry, "_paint_ball", false);
-        this.coloredLumenPaintBall = createPaintBalls(registry, "_lumen_paint_ball", true);
-
-        FeatureFactory debugTools = registry.features(AEFeature.UNSUPPORTED_DEVELOPER_TOOLS, AEFeature.CREATIVE);
-        this.toolEraser = debugTools.item("debug_eraser", EraserItem::new).build();
-        this.toolMeteoritePlacer = debugTools.item("debug_meteorite_placer", MeteoritePlacerItem::new).build();
-        this.toolDebugCard = debugTools.item("debug_card", DebugCardItem::new).build();
-        this.toolReplicatorCard = debugTools.item("debug_replicator_card", ReplicatorCardItem::new).build();
-        debugTools.item("debug_part_placer", DebugPartPlacerItem::new).build();
-
-        this.dummyFluidItem = registry.item("dummy_fluid_item", FluidDummyItem::new)
-                .rendering(new FluidDummyItemRendering()).build();
-    }
-
-    private static AEColoredItemDefinition createPaintBalls(FeatureFactory registry, String idSuffix, boolean lumen) {
-        ColoredItemDefinition colors = new ColoredItemDefinition();
-        for (AEColor color : AEColor.values()) {
-            if (color == AEColor.TRANSPARENT) {
-                continue; // Fluix paintballs don't exist
-            }
-
-            String id = color.registryPrefix + idSuffix;
-            IItemDefinition paintBall = registry.item(id, props -> new PaintBallItem(props, color, lumen))
-                    .features(AEFeature.PAINT_BALLS).rendering(new PaintBallItemRendering(color, lumen)).build();
-            colors.add(color, new ItemStackSrc(paintBall.item(), ActivityState.Enabled));
-        }
-        return colors;
-    }
-
-    @Override
-    public IItemDefinition certusQuartzAxe() {
-        return this.certusQuartzAxe;
-    }
-
-    @Override
-    public IItemDefinition certusQuartzHoe() {
-        return this.certusQuartzHoe;
-    }
-
-    @Override
-    public IItemDefinition certusQuartzShovel() {
-        return this.certusQuartzShovel;
-    }
-
-    @Override
-    public IItemDefinition certusQuartzPick() {
-        return this.certusQuartzPick;
-    }
-
-    @Override
-    public IItemDefinition certusQuartzSword() {
-        return this.certusQuartzSword;
-    }
-
-    @Override
-    public IItemDefinition certusQuartzWrench() {
-        return this.certusQuartzWrench;
-    }
-
-    @Override
-    public IItemDefinition certusQuartzKnife() {
-        return this.certusQuartzKnife;
-    }
-
-    @Override
-    public IItemDefinition netherQuartzAxe() {
-        return this.netherQuartzAxe;
-    }
-
-    @Override
-    public IItemDefinition netherQuartzHoe() {
-        return this.netherQuartzHoe;
-    }
-
-    @Override
-    public IItemDefinition netherQuartzShovel() {
-        return this.netherQuartzShovel;
-    }
-
-    @Override
-    public IItemDefinition netherQuartzPick() {
-        return this.netherQuartzPick;
-    }
-
-    @Override
-    public IItemDefinition netherQuartzSword() {
-        return this.netherQuartzSword;
-    }
-
-    @Override
-    public IItemDefinition netherQuartzWrench() {
-        return this.netherQuartzWrench;
-    }
-
-    @Override
-    public IItemDefinition netherQuartzKnife() {
-        return this.netherQuartzKnife;
-    }
-
-    @Override
-    public IItemDefinition entropyManipulator() {
-        return this.entropyManipulator;
-    }
-
-    @Override
-    public IItemDefinition wirelessTerminal() {
-        return this.wirelessTerminal;
-    }
-
-    @Override
-    public IItemDefinition biometricCard() {
-        return this.biometricCard;
-    }
-
-    @Override
-    public IItemDefinition chargedStaff() {
-        return this.chargedStaff;
-    }
-
-    @Override
-    public IItemDefinition massCannon() {
-        return this.massCannon;
-    }
-
-    @Override
-    public IItemDefinition memoryCard() {
-        return this.memoryCard;
-    }
-
-    @Override
-    public IItemDefinition networkTool() {
-        return this.networkTool;
-    }
-
-    @Override
-    public IItemDefinition portableCell() {
-        return this.portableCell;
-    }
-
-    @Override
-    public IItemDefinition cellCreative() {
-        return this.cellCreative;
-    }
-
-    @Override
-    public IItemDefinition viewCell() {
-        return this.viewCell;
-    }
-
-    @Override
-    public IItemDefinition cell1k() {
-        return this.cell1k;
-    }
-
-    @Override
-    public IItemDefinition cell4k() {
-        return this.cell4k;
-    }
-
-    @Override
-    public IItemDefinition cell16k() {
-        return this.cell16k;
-    }
-
-    @Override
-    public IItemDefinition cell64k() {
-        return this.cell64k;
-    }
-
-    @Override
-    public IItemDefinition fluidCell1k() {
-        return this.fluidCell1k;
-    }
-
-    @Override
-    public IItemDefinition fluidCell4k() {
-        return this.fluidCell4k;
-    }
-
-    @Override
-    public IItemDefinition fluidCell16k() {
-        return this.fluidCell16k;
-    }
-
-    @Override
-    public IItemDefinition fluidCell64k() {
-        return this.fluidCell64k;
-    }
-
-    @Override
-    public IItemDefinition spatialCell2() {
-        return this.spatialCell2;
-    }
-
-    @Override
-    public IItemDefinition spatialCell16() {
-        return this.spatialCell16;
-    }
-
-    @Override
-    public IItemDefinition spatialCell128() {
-        return this.spatialCell128;
-    }
-
-    @Override
-    public IItemDefinition facade() {
-        return this.facade;
-    }
-
-    @Override
-    public IItemDefinition certusCrystalSeed() {
-        return certusCrystalSeed;
-    }
-
-    @Override
-    public IItemDefinition fluixCrystalSeed() {
-        return fluixCrystalSeed;
-    }
-
-    @Override
-    public IItemDefinition netherQuartzSeed() {
-        return netherQuartzSeed;
-    }
-
-    @Override
-    public IItemDefinition encodedPattern() {
-        return this.encodedPattern;
-    }
-
-    @Override
-    public IItemDefinition colorApplicator() {
-        return this.colorApplicator;
-    }
-
-    @Override
-    public AEColoredItemDefinition coloredPaintBall() {
-        return this.coloredPaintBall;
-    }
-
-    @Override
-    public AEColoredItemDefinition coloredLumenPaintBall() {
-        return this.coloredLumenPaintBall;
-    }
-
-    public IItemDefinition toolEraser() {
-        return this.toolEraser;
-    }
-
-    public IItemDefinition toolMeteoritePlacer() {
-        return this.toolMeteoritePlacer;
-    }
-
-    public IItemDefinition toolDebugCard() {
-        return this.toolDebugCard;
-    }
-
-    public IItemDefinition toolReplicatorCard() {
-        return this.toolReplicatorCard;
-    }
-
-    @Override
-    public IItemDefinition dummyFluidItem() {
-        return this.dummyFluidItem;
-    }
-}
diff --git a/src/main/java/appeng/core/api/definitions/ApiParts.java b/src/main/java/appeng/core/api/definitions/ApiParts.java
deleted file mode 100644
index f2d568478..000000000
--- a/src/main/java/appeng/core/api/definitions/ApiParts.java
+++ /dev/null
@@ -1,441 +0,0 @@
-/*
- * This file is part of Applied Energistics 2.
- * Copyright (c) 2013 - 2015, AlgorithmX2, All rights reserved.
- *
- * Applied Energistics 2 is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * Applied Energistics 2 is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with Applied Energistics 2.  If not, see .
- */
-
-package appeng.core.api.definitions;
-
-import java.util.function.Function;
-
-import net.minecraft.item.ItemStack;
-import net.minecraft.util.Identifier;
-
-import appeng.api.definitions.IItemDefinition;
-import appeng.api.definitions.IParts;
-import appeng.api.parts.IPart;
-import appeng.api.util.AEColor;
-import appeng.api.util.AEColoredItemDefinition;
-import appeng.bootstrap.FeatureFactory;
-import appeng.core.AppEng;
-import appeng.core.CreativeTab;
-import appeng.core.features.ActivityState;
-import appeng.core.features.ColoredItemDefinition;
-import appeng.core.features.ItemStackSrc;
-import appeng.core.features.registries.PartModels;
-import appeng.fluids.parts.FluidAnnihilationPlanePart;
-import appeng.fluids.parts.FluidExportBusPart;
-import appeng.fluids.parts.FluidFormationPlanePart;
-import appeng.fluids.parts.FluidImportBusPart;
-import appeng.fluids.parts.FluidInterfacePart;
-import appeng.fluids.parts.FluidLevelEmitterPart;
-import appeng.fluids.parts.FluidStorageBusPart;
-import appeng.fluids.parts.FluidTerminalPart;
-import appeng.items.parts.ColoredPartItem;
-import appeng.items.parts.PartItem;
-import appeng.items.parts.PartItemRendering;
-import appeng.items.parts.PartType;
-import appeng.parts.automation.AnnihilationPlanePart;
-import appeng.parts.automation.ExportBusPart;
-import appeng.parts.automation.FormationPlanePart;
-import appeng.parts.automation.IdentityAnnihilationPlanePart;
-import appeng.parts.automation.ImportBusPart;
-import appeng.parts.automation.LevelEmitterPart;
-import appeng.parts.misc.CableAnchorPart;
-import appeng.parts.misc.InterfacePart;
-import appeng.parts.misc.InvertedToggleBusPart;
-import appeng.parts.misc.StorageBusPart;
-import appeng.parts.misc.ToggleBusPart;
-import appeng.parts.networking.CoveredCablePart;
-import appeng.parts.networking.CoveredDenseCablePart;
-import appeng.parts.networking.GlassCablePart;
-import appeng.parts.networking.QuartzFiberPart;
-import appeng.parts.networking.SmartCablePart;
-import appeng.parts.networking.SmartDenseCablePart;
-import appeng.parts.p2p.FEP2PTunnelPart;
-import appeng.parts.p2p.FluidP2PTunnelPart;
-import appeng.parts.p2p.ItemP2PTunnelPart;
-import appeng.parts.p2p.LightP2PTunnelPart;
-import appeng.parts.p2p.MEP2PTunnelPart;
-import appeng.parts.p2p.RedstoneP2PTunnelPart;
-import appeng.parts.reporting.ConversionMonitorPart;
-import appeng.parts.reporting.CraftingTerminalPart;
-import appeng.parts.reporting.DarkPanelPart;
-import appeng.parts.reporting.InterfaceTerminalPart;
-import appeng.parts.reporting.PanelPart;
-import appeng.parts.reporting.PatternTerminalPart;
-import appeng.parts.reporting.SemiDarkPanelPart;
-import appeng.parts.reporting.StorageMonitorPart;
-import appeng.parts.reporting.TerminalPart;
-
-/**
- * Internal implementation for the API parts
- */
-public final class ApiParts implements IParts {
-    private final AEColoredItemDefinition cableSmart;
-    private final AEColoredItemDefinition cableCovered;
-    private final AEColoredItemDefinition cableGlass;
-    private final AEColoredItemDefinition cableDenseCovered;
-    private final AEColoredItemDefinition cableDenseSmart;
-    private final IItemDefinition quartzFiber;
-    private final IItemDefinition toggleBus;
-    private final IItemDefinition invertedToggleBus;
-    private final IItemDefinition storageBus;
-    private final IItemDefinition importBus;
-    private final IItemDefinition exportBus;
-    private final IItemDefinition iface;
-    private final IItemDefinition fluidIface;
-    private final IItemDefinition levelEmitter;
-    private final IItemDefinition fluidLevelEmitter;
-    private final IItemDefinition annihilationPlane;
-    private final IItemDefinition identityAnnihilationPlane;
-    private final IItemDefinition fluidAnnihilationPlane;
-    private final IItemDefinition formationPlane;
-    private final IItemDefinition fluidFormationPlane;
-    private final IItemDefinition p2PTunnelME;
-    private final IItemDefinition p2PTunnelRedstone;
-    private final IItemDefinition p2PTunnelItems;
-    private final IItemDefinition p2PTunnelFluids;
-    private final IItemDefinition p2PTunnelEU;
-    private final IItemDefinition p2PTunnelFE;
-    private final IItemDefinition p2PTunnelLight;
-    private final IItemDefinition cableAnchor;
-    private final IItemDefinition monitor;
-    private final IItemDefinition semiDarkMonitor;
-    private final IItemDefinition darkMonitor;
-    private final IItemDefinition interfaceTerminal;
-    private final IItemDefinition patternTerminal;
-    private final IItemDefinition craftingTerminal;
-    private final IItemDefinition terminal;
-    private final IItemDefinition storageMonitor;
-    private final IItemDefinition conversionMonitor;
-    private final IItemDefinition fluidImportBus;
-    private final IItemDefinition fluidExportBus;
-    private final IItemDefinition fluidTerminal;
-    private final IItemDefinition fluidStorageBus;
-
-    public ApiParts(FeatureFactory registry, PartModels partModels) {
-        registerPartModels(partModels);
-
-        this.cableSmart = constructColoredDefinition(registry, "smart_cable", PartType.CABLE_SMART,
-                SmartCablePart::new);
-        this.cableCovered = constructColoredDefinition(registry, "covered_cable", PartType.CABLE_COVERED,
-                CoveredCablePart::new);
-        this.cableGlass = constructColoredDefinition(registry, "glass_cable", PartType.CABLE_GLASS,
-                GlassCablePart::new);
-        this.cableDenseCovered = constructColoredDefinition(registry, "covered_dense_cable",
-                PartType.CABLE_DENSE_COVERED, CoveredDenseCablePart::new);
-        this.cableDenseSmart = constructColoredDefinition(registry, "smart_dense_cable", PartType.CABLE_DENSE_SMART,
-                SmartDenseCablePart::new);
-        this.quartzFiber = createPart(registry, "quartz_fiber", PartType.QUARTZ_FIBER, QuartzFiberPart::new);
-        this.toggleBus = createPart(registry, "toggle_bus", PartType.TOGGLE_BUS, ToggleBusPart::new);
-        this.invertedToggleBus = createPart(registry, "inverted_toggle_bus", PartType.INVERTED_TOGGLE_BUS,
-                InvertedToggleBusPart::new);
-        this.cableAnchor = createPart(registry, "cable_anchor", PartType.CABLE_ANCHOR, CableAnchorPart::new);
-        this.monitor = createPart(registry, "monitor", PartType.MONITOR, PanelPart::new);
-        this.semiDarkMonitor = createPart(registry, "semi_dark_monitor", PartType.SEMI_DARK_MONITOR,
-                SemiDarkPanelPart::new);
-        this.darkMonitor = createPart(registry, "dark_monitor", PartType.DARK_MONITOR, DarkPanelPart::new);
-        this.storageBus = createPart(registry, "storage_bus", PartType.STORAGE_BUS, StorageBusPart::new);
-        this.fluidStorageBus = createPart(registry, "fluid_storage_bus", PartType.FLUID_STORAGE_BUS,
-                FluidStorageBusPart::new);
-        this.importBus = createPart(registry, "import_bus", PartType.IMPORT_BUS, ImportBusPart::new);
-        this.fluidImportBus = createPart(registry, "fluid_import_bus", PartType.FLUID_IMPORT_BUS,
-                FluidImportBusPart::new);
-        this.exportBus = createPart(registry, "export_bus", PartType.EXPORT_BUS, ExportBusPart::new);
-        this.fluidExportBus = createPart(registry, "fluid_export_bus", PartType.FLUID_EXPORT_BUS,
-                FluidExportBusPart::new);
-        this.levelEmitter = createPart(registry, "level_emitter", PartType.LEVEL_EMITTER, LevelEmitterPart::new);
-        this.fluidLevelEmitter = createPart(registry, "fluid_level_emitter", PartType.FLUID_LEVEL_EMITTER,
-                FluidLevelEmitterPart::new);
-        this.annihilationPlane = createPart(registry, "annihilation_plane", PartType.ANNIHILATION_PLANE,
-                AnnihilationPlanePart::new);
-        this.identityAnnihilationPlane = createPart(registry, "identity_annihilation_plane",
-                PartType.IDENTITY_ANNIHILATION_PLANE, IdentityAnnihilationPlanePart::new);
-        this.fluidAnnihilationPlane = createPart(registry, "fluid_annihilation_plane",
-                PartType.FLUID_ANNIHILATION_PLANE, FluidAnnihilationPlanePart::new);
-        this.formationPlane = createPart(registry, "formation_plane", PartType.FORMATION_PLANE,
-                FormationPlanePart::new);
-        this.fluidFormationPlane = createPart(registry, "fluid_formation_plane", PartType.FLUID_FORMATION_PLANE,
-                FluidFormationPlanePart::new);
-        this.patternTerminal = createPart(registry, "pattern_terminal", PartType.PATTERN_TERMINAL,
-                PatternTerminalPart::new);
-        this.craftingTerminal = createPart(registry, "crafting_terminal", PartType.CRAFTING_TERMINAL,
-                CraftingTerminalPart::new);
-        this.terminal = createPart(registry, "terminal", PartType.TERMINAL, TerminalPart::new);
-        this.storageMonitor = createPart(registry, "storage_monitor", PartType.STORAGE_MONITOR,
-                StorageMonitorPart::new);
-        this.conversionMonitor = createPart(registry, "conversion_monitor", PartType.CONVERSION_MONITOR,
-                ConversionMonitorPart::new);
-        this.iface = createPart(registry, "cable_interface", PartType.INTERFACE, InterfacePart::new);
-        this.fluidIface = createPart(registry, "cable_fluid_interface", PartType.FLUID_INTERFACE,
-                FluidInterfacePart::new);
-        this.p2PTunnelME = createPart(registry, "me_p2p_tunnel", PartType.P2P_TUNNEL_ME, MEP2PTunnelPart::new);
-        this.p2PTunnelRedstone = createPart(registry, "redstone_p2p_tunnel", PartType.P2P_TUNNEL_REDSTONE,
-                RedstoneP2PTunnelPart::new);
-        this.p2PTunnelItems = createPart(registry, "item_p2p_tunnel", PartType.P2P_TUNNEL_ITEM, ItemP2PTunnelPart::new);
-        this.p2PTunnelFluids = createPart(registry, "fluid_p2p_tunnel", PartType.P2P_TUNNEL_FLUID,
-                FluidP2PTunnelPart::new);
-        this.p2PTunnelEU = null; // FIXME createPart( "ic2_p2p_tunnel", PartType.P2P_TUNNEL_IC2,
-                                 // PartP2PIC2Power::new);
-        this.p2PTunnelFE = createPart(registry, "fe_p2p_tunnel", PartType.P2P_TUNNEL_FE, FEP2PTunnelPart::new);
-        this.p2PTunnelLight = createPart(registry, "light_p2p_tunnel", PartType.P2P_TUNNEL_LIGHT,
-                LightP2PTunnelPart::new);
-        this.interfaceTerminal = createPart(registry, "interface_terminal", PartType.INTERFACE_TERMINAL,
-                InterfaceTerminalPart::new);
-        this.fluidTerminal = createPart(registry, "fluid_terminal", PartType.FLUID_TERMINAL, FluidTerminalPart::new);
-    }
-
-    private void registerPartModels(PartModels partModels) {
-
-        // Register the built-in models for annihilation planes
-        Identifier fluidFormationPlaneTexture = new Identifier(AppEng.MOD_ID,
-                "item/part/fluid_formation_plane");
-        Identifier fluidFormationPlaneOnTexture = new Identifier(AppEng.MOD_ID,
-                "parts/fluid_formation_plane_on");
-
-        // Register all part models
-        for (PartType partType : PartType.values()) {
-            partModels.registerModels(partType.getModels());
-        }
-    }
-
-    private  IItemDefinition createPart(FeatureFactory registry, String id, PartType type,
-            Function factory) {
-        return registry.item(id, props -> new PartItem<>(props, type, factory)).itemGroup(CreativeTab.INSTANCE)
-                .rendering(new PartItemRendering()).build();
-    }
-
-    private  AEColoredItemDefinition constructColoredDefinition(FeatureFactory registry,
-            String idSuffix, PartType type, Function factory) {
-        final ColoredItemDefinition definition = new ColoredItemDefinition();
-
-        for (final AEColor color : AEColor.values()) {
-            String id = color.registryPrefix + '_' + idSuffix;
-
-            IItemDefinition itemDef = registry.item(id, props -> new ColoredPartItem<>(props, type, factory, color))
-                    .itemGroup(CreativeTab.INSTANCE).rendering(new PartItemRendering(color)).build();
-
-            definition.add(color, new ItemStackSrc(itemDef.item(), ActivityState.Enabled));
-        }
-
-        return definition;
-    }
-
-    @Override
-    public AEColoredItemDefinition cableSmart() {
-        return this.cableSmart;
-    }
-
-    @Override
-    public AEColoredItemDefinition cableCovered() {
-        return this.cableCovered;
-    }
-
-    @Override
-    public AEColoredItemDefinition cableGlass() {
-        return this.cableGlass;
-    }
-
-    @Override
-    public AEColoredItemDefinition cableDenseCovered() {
-        return this.cableDenseCovered;
-    }
-
-    @Override
-    public AEColoredItemDefinition cableDenseSmart() {
-        return this.cableDenseSmart;
-    }
-
-    @Override
-    public IItemDefinition quartzFiber() {
-        return this.quartzFiber;
-    }
-
-    @Override
-    public IItemDefinition toggleBus() {
-        return this.toggleBus;
-    }
-
-    @Override
-    public IItemDefinition invertedToggleBus() {
-        return this.invertedToggleBus;
-    }
-
-    @Override
-    public IItemDefinition storageBus() {
-        return this.storageBus;
-    }
-
-    @Override
-    public IItemDefinition importBus() {
-        return this.importBus;
-    }
-
-    @Override
-    public IItemDefinition exportBus() {
-        return this.exportBus;
-    }
-
-    @Override
-    public IItemDefinition iface() {
-        return this.iface;
-    }
-
-    @Override
-    public IItemDefinition fluidIface() {
-        return this.fluidIface;
-    }
-
-    @Override
-    public IItemDefinition levelEmitter() {
-        return this.levelEmitter;
-    }
-
-    @Override
-    public IItemDefinition annihilationPlane() {
-        return this.annihilationPlane;
-    }
-
-    @Override
-    public IItemDefinition identityAnnihilationPlane() {
-        return this.identityAnnihilationPlane;
-    }
-
-    @Override
-    public IItemDefinition formationPlane() {
-        return this.formationPlane;
-    }
-
-    @Override
-    public IItemDefinition p2PTunnelME() {
-        return this.p2PTunnelME;
-    }
-
-    @Override
-    public IItemDefinition p2PTunnelRedstone() {
-        return this.p2PTunnelRedstone;
-    }
-
-    @Override
-    public IItemDefinition p2PTunnelItems() {
-        return this.p2PTunnelItems;
-    }
-
-    @Override
-    public IItemDefinition p2PTunnelFluids() {
-        return this.p2PTunnelFluids;
-    }
-
-    @Override
-    public IItemDefinition p2PTunnelEU() {
-        return this.p2PTunnelEU;
-    }
-
-    @Override
-    public IItemDefinition p2PTunnelFE() {
-        return this.p2PTunnelFE;
-    }
-
-    @Override
-    public IItemDefinition p2PTunnelLight() {
-        return this.p2PTunnelLight;
-    }
-
-    @Override
-    public IItemDefinition cableAnchor() {
-        return this.cableAnchor;
-    }
-
-    @Override
-    public IItemDefinition monitor() {
-        return this.monitor;
-    }
-
-    @Override
-    public IItemDefinition semiDarkMonitor() {
-        return this.semiDarkMonitor;
-    }
-
-    @Override
-    public IItemDefinition darkMonitor() {
-        return this.darkMonitor;
-    }
-
-    @Override
-    public IItemDefinition interfaceTerminal() {
-        return this.interfaceTerminal;
-    }
-
-    @Override
-    public IItemDefinition patternTerminal() {
-        return this.patternTerminal;
-    }
-
-    @Override
-    public IItemDefinition craftingTerminal() {
-        return this.craftingTerminal;
-    }
-
-    @Override
-    public IItemDefinition terminal() {
-        return this.terminal;
-    }
-
-    @Override
-    public IItemDefinition storageMonitor() {
-        return this.storageMonitor;
-    }
-
-    @Override
-    public IItemDefinition conversionMonitor() {
-        return this.conversionMonitor;
-    }
-
-    @Override
-    public IItemDefinition fluidTerminal() {
-        return this.fluidTerminal;
-    }
-
-    @Override
-    public IItemDefinition fluidImportBus() {
-        return this.fluidImportBus;
-    }
-
-    @Override
-    public IItemDefinition fluidExportBus() {
-        return this.fluidExportBus;
-    }
-
-    @Override
-    public IItemDefinition fluidStorageBus() {
-        return this.fluidStorageBus;
-    }
-
-    @Override
-    public IItemDefinition fluidLevelEmitter() {
-        return this.fluidLevelEmitter;
-    }
-
-    @Override
-    public IItemDefinition fluidAnnihilationPlane() {
-        return this.fluidAnnihilationPlane;
-    }
-
-    @Override
-    public IItemDefinition fluidFormationnPlane() {
-        return this.fluidFormationPlane;
-    }
-}
diff --git a/src/main/java/appeng/debug/DebugPartPlacerItem.java b/src/main/java/appeng/debug/DebugPartPlacerItem.java
index f569681ba..a4bce78a7 100644
--- a/src/main/java/appeng/debug/DebugPartPlacerItem.java
+++ b/src/main/java/appeng/debug/DebugPartPlacerItem.java
@@ -66,7 +66,7 @@ public class DebugPartPlacerItem extends AEBaseItem {
         }
 
         Direction face = context.getSide();
-        Vec3i offset = face.getDirectionVec();
+        Vec3i offset = face.getVector();
         Direction[] perpendicularFaces = Arrays.stream(Direction.values()).filter(d -> d.getAxis() != face.getAxis())
                 .toArray(Direction[]::new);
 
diff --git a/src/main/java/appeng/hooks/BlockToolDispenseItemBehavior.java b/src/main/java/appeng/hooks/BlockToolDispenseItemBehavior.java
index 89d9645ac..f106108d4 100644
--- a/src/main/java/appeng/hooks/BlockToolDispenseItemBehavior.java
+++ b/src/main/java/appeng/hooks/BlockToolDispenseItemBehavior.java
@@ -19,8 +19,8 @@
 package appeng.hooks;
 
 import net.minecraft.block.DispenserBlock;
-import net.minecraft.dispenser.DefaultDispenseItemBehavior;
-import net.minecraft.dispenser.IBlockSource;
+import net.minecraft.block.dispenser.ItemDispenserBehavior;
+import net.minecraft.util.math.BlockPointer;
 import net.minecraft.item.DirectionalPlaceContext;
 import net.minecraft.item.Item;
 import net.minecraft.item.ItemStack;
@@ -29,10 +29,10 @@ import net.minecraft.util.math.Direction;
 import net.minecraft.world.World;
 import net.minecraft.server.world.ServerWorld;
 
-public final class BlockToolDispenseItemBehavior extends DefaultDispenseItemBehavior {
+public final class BlockToolDispenseItemBehavior extends ItemDispenserBehavior {
 
     @Override
-    protected ItemStack dispenseStack(final IBlockSource dispenser, final ItemStack dispensedItem) {
+    protected ItemStack dispenseSilently(final BlockPointer dispenser, final ItemStack dispensedItem) {
         final Item i = dispensedItem.getItem();
         if (i instanceof IBlockTool) {
             final Direction direction = dispenser.getBlockState().get(DispenserBlock.FACING);
diff --git a/src/main/java/appeng/hooks/MatterCannonDispenseItemBehavior.java b/src/main/java/appeng/hooks/MatterCannonDispenseItemBehavior.java
index de2e7bbaa..b206499fd 100644
--- a/src/main/java/appeng/hooks/MatterCannonDispenseItemBehavior.java
+++ b/src/main/java/appeng/hooks/MatterCannonDispenseItemBehavior.java
@@ -20,8 +20,8 @@ package appeng.hooks;
 
 import appeng.util.FakePlayer;
 import net.minecraft.block.DispenserBlock;
-import net.minecraft.dispenser.DefaultDispenseItemBehavior;
-import net.minecraft.dispenser.IBlockSource;
+import net.minecraft.block.dispenser.ItemDispenserBehavior;
+import net.minecraft.util.math.BlockPointer;
 import net.minecraft.entity.player.PlayerEntity;
 import net.minecraft.item.Item;
 import net.minecraft.item.ItemStack;
@@ -33,10 +33,10 @@ import appeng.api.util.AEPartLocation;
 import appeng.items.tools.powered.MatterCannonItem;
 import appeng.util.Platform;
 
-public final class MatterCannonDispenseItemBehavior extends DefaultDispenseItemBehavior {
+public final class MatterCannonDispenseItemBehavior extends ItemDispenserBehavior {
 
     @Override
-    protected ItemStack dispenseStack(final IBlockSource dispenser, ItemStack dispensedItem) {
+    protected ItemStack dispenseSilently(final BlockPointer dispenser, ItemStack dispensedItem) {
         final Item i = dispensedItem.getItem();
         if (i instanceof MatterCannonItem) {
             final Direction Direction = dispenser.getBlockState().get(DispenserBlock.FACING);
diff --git a/src/main/java/appeng/integration/modules/theoneprobe/part/PartAccessor.java b/src/main/java/appeng/integration/modules/theoneprobe/part/PartAccessor.java
index 4c358dc58..25b32cb37 100644
--- a/src/main/java/appeng/integration/modules/theoneprobe/part/PartAccessor.java
+++ b/src/main/java/appeng/integration/modules/theoneprobe/part/PartAccessor.java
@@ -35,7 +35,7 @@ public final class PartAccessor {
     public Optional getMaybePart(final BlockEntity te, final IProbeHitData data) {
         if (te instanceof IPartHost) {
             BlockPos pos = data.getPos();
-            final Vec3d position = data.getHitVec().add(-pos.getX(), -pos.getY(), -pos.getZ());
+            final Vec3d position = data.getHitPos().add(-pos.getX(), -pos.getY(), -pos.getZ());
             final IPartHost host = (IPartHost) te;
             final SelectedPart sp = host.selectPart(position);
 
diff --git a/src/main/java/appeng/items/contents/CellUpgrades.java b/src/main/java/appeng/items/contents/CellUpgrades.java
index 0b135215f..2a1004456 100644
--- a/src/main/java/appeng/items/contents/CellUpgrades.java
+++ b/src/main/java/appeng/items/contents/CellUpgrades.java
@@ -18,6 +18,7 @@
 
 package appeng.items.contents;
 
+import alexiil.mc.lib.attributes.item.FixedItemInvView;
 import net.minecraft.item.ItemStack;
 
 import appeng.parts.automation.StackUpgradeInventory;
@@ -32,7 +33,7 @@ public final class CellUpgrades extends StackUpgradeInventory {
     }
 
     @Override
-    protected void onContentsChanged(int slot) {
+    protected void onContentsChanged(FixedItemInvView inv, int slot, ItemStack previous, ItemStack current) {
         this.writeToNBT(this.is.getOrCreateTag(), "upgrades");
     }
 }
\ No newline at end of file
diff --git a/src/main/java/appeng/items/tools/NetworkToolItem.java b/src/main/java/appeng/items/tools/NetworkToolItem.java
index 255993107..f7d132df0 100644
--- a/src/main/java/appeng/items/tools/NetworkToolItem.java
+++ b/src/main/java/appeng/items/tools/NetworkToolItem.java
@@ -86,7 +86,7 @@ public class NetworkToolItem extends AEBaseItem implements IGuiItem, IAEWrench {
 
     @Override
     public ActionResult onItemUseFirst(ItemStack stack, ItemUsageContext context) {
-        final BlockHitResult mop = new BlockHitResult(context.getHitVec(), context.getSide(),
+        final BlockHitResult mop = new BlockHitResult(context.getHitPos(), context.getSide(),
                 context.getBlockPos(), context.isInside());
         final BlockEntity te = context.getWorld().getBlockEntity(context.getBlockPos());
 
@@ -155,7 +155,7 @@ public class NetworkToolItem extends AEBaseItem implements IGuiItem, IAEWrench {
 
             return true;
         } else {
-            BlockHitResult rtr = new BlockHitResult(useContext.getHitVec(), side, pos, false);
+            BlockHitResult rtr = new BlockHitResult(useContext.getHitPos(), side, pos, false);
             bs.onUse(w, p, hand, rtr);
         }
 
diff --git a/src/main/java/appeng/parts/PartPlacement.java b/src/main/java/appeng/parts/PartPlacement.java
index 1185ccfbe..e5e068907 100644
--- a/src/main/java/appeng/parts/PartPlacement.java
+++ b/src/main/java/appeng/parts/PartPlacement.java
@@ -313,7 +313,7 @@ public class PartPlacement {
                 if (!player.isCreative()) {
                     held.increment(-1);
                     if (held.getCount() == 0) {
-                        player.setHeldItem(hand, ItemStack.EMPTY);
+                        player.setStackInHand(hand, ItemStack.EMPTY);
                         MinecraftForge.EVENT_BUS.post(new PlayerDestroyItemEvent(player, held, hand));
                     }
                 }
diff --git a/src/main/java/appeng/parts/automation/FormationPlanePart.java b/src/main/java/appeng/parts/automation/FormationPlanePart.java
index c1e21c05c..cfaad7109 100644
--- a/src/main/java/appeng/parts/automation/FormationPlanePart.java
+++ b/src/main/java/appeng/parts/automation/FormationPlanePart.java
@@ -228,7 +228,7 @@ public class FormationPlanePart extends AbstractFormationPlanePart
                 final PlayerEntity player = FakePlayer.getOrCreate((ServerWorld) w);
                 Platform.configurePlayer(player, side, this.getTile());
                 Hand hand = player.getActiveHand();
-                player.setHeldItem(hand, is);
+                player.setStackInHand(hand, is);
 
                 maxStorage = is.getCount();
                 worked = true;
@@ -276,7 +276,7 @@ public class FormationPlanePart extends AbstractFormationPlanePart
                 }
 
                 // Safe keeping
-                player.setHeldItem(hand, ItemStack.EMPTY);
+                player.setStackInHand(hand, ItemStack.EMPTY);
             } else {
                 worked = true;
 
diff --git a/src/main/java/appeng/parts/automation/PlaneModel.java b/src/main/java/appeng/parts/automation/PlaneModel.java
index 1a123affd..ba27cb879 100644
--- a/src/main/java/appeng/parts/automation/PlaneModel.java
+++ b/src/main/java/appeng/parts/automation/PlaneModel.java
@@ -29,7 +29,7 @@ import net.minecraft.client.render.model.BakedModel;
 import net.minecraft.client.render.model.IModelTransform;
 import net.minecraft.client.render.model.IUnbakedModel;
 import net.minecraft.client.render.model.json.ModelOverrideList;
-import net.minecraft.client.render.model.Material;
+import net.minecraft.client.util.SpriteIdentifier;
 import net.minecraft.client.render.model.ModelLoader;
 import net.minecraft.client.texture.SpriteAtlasTexture;
 import net.minecraft.client.texture.Sprite;
@@ -42,19 +42,19 @@ import net.minecraftforge.client.model.geometry.IModelGeometry;
  */
 public class PlaneModel implements IModelGeometry {
 
-    private final Material frontTexture;
-    private final Material sidesTexture;
-    private final Material backTexture;
+    private final SpriteIdentifier frontTexture;
+    private final SpriteIdentifier sidesTexture;
+    private final SpriteIdentifier backTexture;
 
     public PlaneModel(Identifier frontTexture, Identifier sidesTexture, Identifier backTexture) {
-        this.frontTexture = new Material(SpriteAtlasTexture.BLOCK_ATLAS_TEX, frontTexture);
-        this.sidesTexture = new Material(SpriteAtlasTexture.BLOCK_ATLAS_TEX, sidesTexture);
-        this.backTexture = new Material(SpriteAtlasTexture.BLOCK_ATLAS_TEX, backTexture);
+        this.frontTexture = new SpriteIdentifier(SpriteAtlasTexture.BLOCK_ATLAS_TEX, frontTexture);
+        this.sidesTexture = new SpriteIdentifier(SpriteAtlasTexture.BLOCK_ATLAS_TEX, sidesTexture);
+        this.backTexture = new SpriteIdentifier(SpriteAtlasTexture.BLOCK_ATLAS_TEX, backTexture);
     }
 
     @Override
     public BakedModel bake(IModelConfiguration owner, ModelLoader bakery,
-                           Function spriteGetter, IModelTransform modelTransform,
+                           Function spriteGetter, IModelTransform modelTransform,
                            ModelOverrideList overrides, Identifier modelLocation) {
         Sprite frontSprite = spriteGetter.apply(this.frontTexture);
         Sprite sidesSprite = spriteGetter.apply(this.sidesTexture);
@@ -64,8 +64,8 @@ public class PlaneModel implements IModelGeometry {
     }
 
     @Override
-    public Collection getTextures(IModelConfiguration owner,
-                                            Function modelGetter, Set> missingTextureErrors) {
+    public Collection getTextures(IModelConfiguration owner,
+                                                    Function modelGetter, Set> missingTextureErrors) {
         return Arrays.asList(frontTexture, sidesTexture, backTexture);
     }
 
diff --git a/src/main/java/appeng/parts/reporting/ConversionMonitorPart.java b/src/main/java/appeng/parts/reporting/ConversionMonitorPart.java
index 3dcd596a4..3f8c1ec15 100644
--- a/src/main/java/appeng/parts/reporting/ConversionMonitorPart.java
+++ b/src/main/java/appeng/parts/reporting/ConversionMonitorPart.java
@@ -177,7 +177,7 @@ public class ConversionMonitorPart extends AbstractMonitorPart {
                 final IAEItemStack input = AEItemStack.fromItemStack(player.getStackInHand(hand));
                 final IAEItemStack failedToInsert = Platform.poweredInsert(energy, cell, input,
                         new PlayerSource(player, this));
-                player.setHeldItem(hand, failedToInsert == null ? ItemStack.EMPTY : failedToInsert.createItemStack());
+                player.setStackInHand(hand, failedToInsert == null ? ItemStack.EMPTY : failedToInsert.createItemStack());
             }
         } catch (final GridAccessException e) {
             // :P
diff --git a/src/main/java/appeng/server/subcommands/TestMeteoritesCommand.java b/src/main/java/appeng/server/subcommands/TestMeteoritesCommand.java
index 1cb9a2c5f..d43a82c71 100644
--- a/src/main/java/appeng/server/subcommands/TestMeteoritesCommand.java
+++ b/src/main/java/appeng/server/subcommands/TestMeteoritesCommand.java
@@ -33,6 +33,7 @@ import com.mojang.brigadier.exceptions.CommandSyntaxException;
 import net.minecraft.server.command.ServerCommandSource;
 import net.minecraft.server.network.ServerPlayerEntity;
 import net.minecraft.server.MinecraftServer;
+import net.minecraft.text.ClickEvent;
 import net.minecraft.util.Formatting;
 import net.minecraft.util.math.BlockPos;
 import net.minecraft.util.math.ChunkPos;
@@ -190,8 +191,9 @@ public class TestMeteoritesCommand implements ISubCommand {
         String displayText = String.format(Locale.ROOT, "pos=%d,%d,%d", tpPos.getX(), tpPos.getY(), tpPos.getZ());
         String tpCommand = String.format(Locale.ROOT, "/tp @s %d %d %d", tpPos.getX(), tpPos.getY(), tpPos.getZ());
 
-        return new LiteralText(displayText).formatted(Formatting.UNDERLINE)
-                .formatted(style -> style.setClickEvent(new ClickEvent(ClickEvent.Action.RUN_COMMAND, tpCommand)));
+        return new LiteralText(displayText)
+                .formatted(Formatting.UNDERLINE)
+                .styled(style -> style.withClickEvent(new ClickEvent(ClickEvent.Action.RUN_COMMAND, tpCommand)));
     }
 
     private static MeteoriteStructurePiece getMeteoritePieceFromChunk(Chunk chunk) {
diff --git a/src/main/java/appeng/spatial/CachedPlane.java b/src/main/java/appeng/spatial/CachedPlane.java
index c640697ec..02446f5d5 100644
--- a/src/main/java/appeng/spatial/CachedPlane.java
+++ b/src/main/java/appeng/spatial/CachedPlane.java
@@ -284,7 +284,7 @@ public class CachedPlane {
                     final BlockPos pos = new BlockPos(x, y, z);
 
                     // attempt recovery...
-                    c.c.addTileEntity(te);
+                    c.c.addBlockEntity(te);
 
                     this.world.updateListeners(pos, this.world.getBlockState(pos), this.world.getBlockState(pos), z);
                 }
diff --git a/src/main/java/appeng/thirdparty/codechicken/lib/model/Quad.java b/src/main/java/appeng/thirdparty/codechicken/lib/model/Quad.java
index 446656074..aa6baa15a 100644
--- a/src/main/java/appeng/thirdparty/codechicken/lib/model/Quad.java
+++ b/src/main/java/appeng/thirdparty/codechicken/lib/model/Quad.java
@@ -201,7 +201,7 @@ public class Quad implements IVertexProducer, ISmartVertexConsumer {
                 vertex.normal[3] = 0;
             }
         }
-        this.orientation = Direction.getFacingFromVector(this.normal.getX(), this.normal.getY(), this.normal.getZ());
+        this.orientation = Direction.getFacing(this.normal.getX(), this.normal.getY(), this.normal.getZ());
     }
 
     /**
diff --git a/src/main/java/appeng/thirdparty/codechicken/lib/model/pipeline/transformers/QuadCornerKicker.java b/src/main/java/appeng/thirdparty/codechicken/lib/model/pipeline/transformers/QuadCornerKicker.java
index b86cb11b4..088b5ecc6 100644
--- a/src/main/java/appeng/thirdparty/codechicken/lib/model/pipeline/transformers/QuadCornerKicker.java
+++ b/src/main/java/appeng/thirdparty/codechicken/lib/model/pipeline/transformers/QuadCornerKicker.java
@@ -121,7 +121,7 @@ public class QuadCornerKicker extends QuadTransformer {
                             float z = vertex.vec[2];
                             if (epsComp(x, corner.pX(this.box)) && epsComp(y, corner.pY(this.box))
                                     && epsComp(z, corner.pZ(this.box))) {
-                                Vec3i vec = Direction.values()[hoz].getDirectionVec();
+                                Vec3i vec = Direction.values()[hoz].getVector();
                                 x -= vec.getX() * this.thickness;
                                 y -= vec.getY() * this.thickness;
                                 z -= vec.getZ() * this.thickness;
diff --git a/src/main/java/appeng/thirdparty/codechicken/lib/model/pipeline/transformers/QuadMatrixTransformer.java b/src/main/java/appeng/thirdparty/codechicken/lib/model/pipeline/transformers/QuadMatrixTransformer.java
index af8377379..82de7da64 100644
--- a/src/main/java/appeng/thirdparty/codechicken/lib/model/pipeline/transformers/QuadMatrixTransformer.java
+++ b/src/main/java/appeng/thirdparty/codechicken/lib/model/pipeline/transformers/QuadMatrixTransformer.java
@@ -18,8 +18,8 @@
 
 package appeng.thirdparty.codechicken.lib.model.pipeline.transformers;
 
+import net.minecraft.client.util.math.Vector4f;
 import net.minecraft.util.math.Matrix4f;
-import net.minecraft.client.renderer.Vector4f;
 import net.minecraft.util.math.Direction;
 import net.minecraftforge.client.model.pipeline.IVertexConsumer;
 
@@ -36,7 +36,7 @@ public class QuadMatrixTransformer extends QuadTransformer {
 
     static {
         identity = new Matrix4f();
-        identity.setIdentity();
+        identity.loadIdentity();
     }
 
     private final Vector4f storage = new Vector4f();
@@ -78,7 +78,7 @@ public class QuadMatrixTransformer extends QuadTransformer {
             vertex.normal[2] = storage.getZ();
         }
         Quad.Vertex v0 = quad.vertices[0];
-        quad.orientation = Direction.getFacingFromVector(v0.normal[0], v0.normal[1], v0.normal[2]);
+        quad.orientation = Direction.getFacing(v0.normal[0], v0.normal[1], v0.normal[2]);
         return true;
     }
 }
diff --git a/src/main/java/appeng/tile/crafting/CraftingBlockEntity.java b/src/main/java/appeng/tile/crafting/CraftingBlockEntity.java
index 1403f693e..2d0f9d43d 100644
--- a/src/main/java/appeng/tile/crafting/CraftingBlockEntity.java
+++ b/src/main/java/appeng/tile/crafting/CraftingBlockEntity.java
@@ -35,8 +35,6 @@ import net.minecraft.util.math.Direction;
 import net.minecraft.util.math.BlockPos;
 import net.minecraft.world.BlockView;
 
-import net.minecraftforge.common.util.Constants;
-
 import appeng.api.AEApi;
 import appeng.api.config.Actionable;
 import appeng.api.implementations.IPowerChannelState;
diff --git a/src/main/java/appeng/tile/crafting/MolecularAssemblerRenderer.java b/src/main/java/appeng/tile/crafting/MolecularAssemblerRenderer.java
index 1a8e6e5f8..3f9ff3dc1 100644
--- a/src/main/java/appeng/tile/crafting/MolecularAssemblerRenderer.java
+++ b/src/main/java/appeng/tile/crafting/MolecularAssemblerRenderer.java
@@ -101,7 +101,7 @@ public class MolecularAssemblerRenderer extends BlockEntityRenderer