diff --git a/build.gradle b/build.gradle
index 27fea88..d61f6f1 100644
--- a/build.gradle
+++ b/build.gradle
@@ -6,7 +6,7 @@ plugins {
 
 import org.gradle.internal.os.OperatingSystem
 
-project.ext.lwjglVersion = "3.3.1"
+project.ext.lwjglVersion = "3.3.4"
 
 switch (OperatingSystem.current()) {
 	case OperatingSystem.LINUX:
@@ -43,6 +43,18 @@ repositories {
 		name = 'signalumMaven'
 		url = 'https://maven.thesignalumproject.net/infrastructure'
 	}
+	maven {
+		name = 'signalumMaven'
+		url = 'https://maven.thesignalumproject.net/releases'
+	}
+	ivy {
+		url = "https://github.com/Better-than-Adventure"
+		patternLayout {
+			artifact "[organisation]/releases/download/v[revision]/[module].jar"
+			m2compatible = true
+		}
+		metadataSources { artifact() }
+	}
 	ivy {
 		url = "https://downloads.betterthanadventure.net/bta-client/${project.bta_channel}/"
 		patternLayout {
@@ -67,6 +79,7 @@ repositories {
 		}
 		metadataSources { artifact() }
 	}
+
 }
 
 dependencies {
@@ -74,16 +87,13 @@ dependencies {
 	mappings loom.layered() {}
 
 	modRuntimeOnly "objects:client:43db9b498cb67058d2e12d394e6507722e71bb45" // https://piston-data.mojang.com/v1/objects/43db9b498cb67058d2e12d394e6507722e71bb45/client.jar
-	modImplementation "babric:fabric-loader:${project.loader_version}"
-
-	// Nightly builds are highly unstable, it is very likely that even these base mods might not work!
-	// Uncomment at your own risk.
+	modImplementation "net.fabricmc:fabric-loader:${project.loader_version}"
 
 	// Helper library
 	// If you do not need Halplibe you can comment this line out or delete this line
-	//modImplementation "com.github.Turnip-Labs:bta-halplibe:${project.halplibe_version}"
+	//implementation("turniplabs:halplibe:${project.halplibe_version}")
 
-	//modImplementation "ModMenu:ModMenu:2.0.6"
+	modImplementation("turniplabs:modmenu-bta:${project.mod_menu_version}")
 
 	implementation "org.slf4j:slf4j-api:1.8.0-beta4"
 	implementation "org.apache.logging.log4j:log4j-slf4j18-impl:2.16.0"
@@ -97,7 +107,7 @@ dependencies {
 
 	include(implementation("org.apache.commons:commons-lang3:3.12.0"))
 
-	modImplementation("com.github.zarzelcow:legacy-lwjgl3:1.0.1")
+	modImplementation("com.github.zarzelcow:legacy-lwjgl3:1.0.4")
 	implementation platform("org.lwjgl:lwjgl-bom:$lwjglVersion")
 
 	runtimeOnly "org.lwjgl:lwjgl::$lwjglNatives"
@@ -106,12 +116,12 @@ dependencies {
 	runtimeOnly "org.lwjgl:lwjgl-openal::$lwjglNatives"
 	runtimeOnly "org.lwjgl:lwjgl-opengl::$lwjglNatives"
 	runtimeOnly "org.lwjgl:lwjgl-stb::$lwjglNatives"
-	implementation "org.lwjgl:lwjgl::$lwjglNatives"
-	implementation "org.lwjgl:lwjgl-assimp::$lwjglNatives"
-	implementation "org.lwjgl:lwjgl-glfw::$lwjglNatives"
-	implementation "org.lwjgl:lwjgl-openal::$lwjglNatives"
-	implementation "org.lwjgl:lwjgl-opengl::$lwjglNatives"
-	implementation "org.lwjgl:lwjgl-stb::$lwjglNatives"
+	implementation "org.lwjgl:lwjgl:$lwjglVersion"
+	implementation "org.lwjgl:lwjgl-assimp:$lwjglVersion"
+	implementation "org.lwjgl:lwjgl-glfw:$lwjglVersion"
+	implementation "org.lwjgl:lwjgl-openal:$lwjglVersion"
+	implementation "org.lwjgl:lwjgl-opengl:$lwjglVersion"
+	implementation "org.lwjgl:lwjgl-stb:$lwjglVersion"
 }
 
 java {
diff --git a/gradle.properties b/gradle.properties
index 9037c8f..66b6847 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -5,13 +5,13 @@ bta_version=7.3-pre1
 bta_channel=prerelease
 
 # Loader
-loader_version=0.15.6-babric.6-bta
+loader_version=0.15.6-bta.7
 
 # Nightly builds are highly unstable, it is very likely that even these base mods might not work!
 # Uncomment at your own risk.
 
 # Other Mods
-# mod_menu_version=2.0.5
+ mod_menu_version=3.0.0
 # halplibe_version=3.5.2
 
 # Mod
diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties
index 0d18421..db4c326 100644
--- a/gradle/wrapper/gradle-wrapper.properties
+++ b/gradle/wrapper/gradle-wrapper.properties
@@ -2,4 +2,4 @@ distributionBase=GRADLE_USER_HOME
 distributionPath=wrapper/dists
 distributionUrl=https\://services.gradle.org/distributions/gradle-8.8-bin.zip
 zipStoreBase=GRADLE_USER_HOME
-zipStorePath=wrapper/dists
+zipStorePath=wrapper/dists
\ No newline at end of file
diff --git a/settings.gradle b/settings.gradle
index 00837f5..bddaedd 100644
--- a/settings.gradle
+++ b/settings.gradle
@@ -1,6 +1,6 @@
 pluginManagement {
     repositories {
-		gradlePluginPortal()
+        gradlePluginPortal()
         maven {
             name = 'Fabric'
             url = 'https://maven.fabricmc.net/'
@@ -13,9 +13,9 @@ pluginManagement {
             name = 'Babric'
             url = 'https://maven.glass-launcher.net/babric'
         }
-		maven {
-			name = 'signalumMaven'
-			url = 'https://maven.thesignalumproject.net/infrastructure'
-		}
+        maven {
+            name = 'signalumMaven'
+            url = 'https://maven.thesignalumproject.net/infrastructure'
+        }
     }
-}
+}
\ No newline at end of file
diff --git a/src/main/java/turniplabs/halplibe/helper/BlockBuilder.java b/src/main/java/turniplabs/halplibe/helper/BlockBuilder.java
index 3cb078e..4c71da4 100644
--- a/src/main/java/turniplabs/halplibe/helper/BlockBuilder.java
+++ b/src/main/java/turniplabs/halplibe/helper/BlockBuilder.java
@@ -14,6 +14,7 @@
 import net.minecraft.core.block.BlockLogicFire;
 import net.minecraft.core.block.BlockLogicSupplier;
 import net.minecraft.core.block.Blocks;
+import net.minecraft.core.block.entity.TileEntity;
 import net.minecraft.core.block.tag.BlockTags;
 import net.minecraft.core.data.tag.Tag;
 import net.minecraft.core.item.Item;
@@ -24,6 +25,7 @@
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 import turniplabs.halplibe.HalpLibe;
+import turniplabs.halplibe.mixin.accessors.BlockAccessor;
 import turniplabs.halplibe.mixin.accessors.BlocksAccessor;
 import turniplabs.halplibe.util.registry.IdSupplier;
 import turniplabs.halplibe.util.registry.RunLengthConfig;
@@ -33,49 +35,35 @@
 import java.util.*;
 import java.util.function.Consumer;
 import java.util.function.Function;
+import java.util.function.Supplier;
 
 public final class BlockBuilder implements Cloneable {
 
-    private final String modId;
-    private final String key;
-    private final String namespaceId;
-    private final int id;
-    private Float hardness = null;
-    private Float resistance = null;
-    private Integer luminance = null;
-    private Integer lightOpacity = null;
-    private Float slipperiness = null;
+    private final @NotNull String modId;
+    private @Nullable Float hardness = null;
+    private @Nullable Float resistance = null;
+    private @Nullable Integer luminance = null;
+    private @Nullable Integer lightOpacity = null;
+    private @Nullable Float slipperiness = null;
     private boolean immovable = false;
     private boolean useInternalLight = false;
     private boolean visualUpdateOnMetadata = false;
-    private Boolean tickOnLoad = null;
+    private @Nullable Boolean tickOnLoad = null;
     private boolean infiniburn = false;
-    private int[] flammability = null;
-    private BlockSound blockSound = null;
-    private Function<Block<?>, BlockColor> blockColor = null;
-    @NotNull
-    private Function<Block<?>, BlockModel<?>> blockModelSupplier = BlockModelStandard::new;
-    @NotNull
-    private Function<ItemBlock<?>, ItemModel> customItemModelSupplier = ItemModelBlock::new;
-    private BlockLambda<ItemBlock<?>> customBlockItem = null;
-    private Tag<Block<?>>[] tags = null;
-    @NotNull
-    private String[] textures = new String[6];
-    @Nullable
-    private String itemIcon = null;
-
-    public BlockBuilder(String modId, String name, int id) {
+    private int @Nullable [] flammability = null;
+    private @Nullable BlockSound blockSound = null;
+    private @Nullable Function<Block<?>, BlockColor> blockColor = null;
+    private @NotNull Function<Block<?>, BlockModel<?>> blockModelSupplier = BlockModelStandard::new;
+    private @NotNull Function<ItemBlock<?>, ItemModel> customItemModelSupplier = ItemModelBlock::new;
+    private @Nullable BlockLambda<ItemBlock<?>> customBlockItem = null;
+    private @Nullable Tag<Block<?>>[] tags = null;
+    private String @NotNull [] textures = new String[6];
+    private @Nullable String itemIcon = null;
+    private @Nullable Supplier<TileEntity> entitySupplier = null;
+
+
+    public BlockBuilder(@NotNull String modId) {
         this.modId = modId;
-        this.key = String.format("tile.%s.%s", modId, name.replace("_", "."));
-        this.namespaceId = String.format("%s:block/%s", modId, name);
-        this.id = id;
-    }
-
-    public BlockBuilder(String modId, String translationKey, String namespacedId, int id) {
-        this.modId = modId;
-        this.key = translationKey;
-        this.namespaceId = namespacedId;
-        this.id = id;
     }
 
     @Override
@@ -234,6 +222,18 @@ public BlockBuilder setEastWestTextures(String texture){
         return builder;
     }
 
+    /**
+     * Sets the block to be a TileEntity Block which creates the provided tile entities on placement
+     * @param tileEntitySupplier supplier of TileEntity instances for the block to create when placed
+     * @return @return Copy of {@link ItemBuilder}
+     */
+    @SuppressWarnings("unused")
+    public BlockBuilder setTileEntity(@Nullable Supplier<TileEntity> tileEntitySupplier) {
+        BlockBuilder builder = clone();
+        builder.entitySupplier = tileEntitySupplier;
+        return builder;
+    }
+
     /**
      * Sets the icon for the {@link Item}'s {@link ItemModel}, only works if the ItemModel used extends {@link ItemModelStandard} and the {@link BlockModel} renders as 2D
      * @param iconKey texture key for the icon for the item to use. Example "minecraft:item/stick"
@@ -492,14 +492,28 @@ public final BlockBuilder addTags(Tag<Block<?>>... tags) {
     }
 
     /**
-     * Applies the builder configuration to the supplied block.
-     * @param blockLogicSupplier Input block object
-     * @return Returns the input block after builder settings are applied to it.
+     * Generates a block with the specified configuration
+     * @param name Underscore separated name (eg `waxed_lightly_weathered_cut_copper_stairs`)
+     * @param numericId Numeric id of the block must be in the range [0, 16383]
+     * @param blockLogicSupplier {@link BlockLogic} that will be assigned to the Block on creation
+     * @return Returns the {@link Block} after registration and configuration
      */
     @SuppressWarnings({"unused"})
-    public <T extends BlockLogic> Block<T> build(BlockLogicSupplier<T> blockLogicSupplier) {
-        // TODO add tile entity supplier build arg
-        Block<T> block = Blocks.register(key, namespaceId, id, blockLogicSupplier);
+    public <T extends BlockLogic> Block<T> build(String name, int numericId, BlockLogicSupplier<T> blockLogicSupplier) {
+        return build(name.replace("_", "."), name, numericId, blockLogicSupplier);
+    }
+
+    /**
+     * Generates a block with the specified configuration
+     * @param translationKey Dot separated identifier to use for translation (eg `cracked.polished.blackstone.bricks`)
+     * @param name Underscore separated name (eg `waxed_lightly_weathered_cut_copper_stairs`)
+     * @param numericId Numeric id of the block must be in the range [0, 16383]
+     * @param blockLogicSupplier {@link BlockLogic} that will be assigned to the Block on creation
+     * @return Returns the {@link Block} after registration and configuration
+     */
+    @SuppressWarnings({"unused"})
+    public <T extends BlockLogic> Block<T> build(String translationKey, String name, int numericId, BlockLogicSupplier<T> blockLogicSupplier) {
+        Block<T> block = Blocks.register(String.format("%s.%s", modId, translationKey), String.format("%s:block/%s", modId, name), numericId, blockLogicSupplier);
         if (hardness != null) {
             block.withHardness(hardness);
         }
@@ -546,29 +560,36 @@ public <T extends BlockLogic> Block<T> build(BlockLogicSupplier<T> blockLogicSup
             block.withSound(blockSound);
         }
 
-        Assignment.queueBlockColor(block, blockColor);
+        if (entitySupplier != null) {
+            block.withEntity(entitySupplier);
+        }
 
-        ItemBlock<?> BlockItem;
+        Assignment.queueBlockColor(block, blockColor);
 
         if (tags != null) {
             block.withTags(tags);
         }
 
+        if (customBlockItem != null) {
+            block.setBlockItem(() -> customBlockItem.run(block));
+        }
+
         if (BlocksAccessor.hasInit()) {
             block.init();
 
-            if (customBlockItem != null) {
-                Item.itemsList[block.id()] = BlockItem = customBlockItem.run(block);
-            } else {
-                Item.itemsList[block.id()] = BlockItem = new ItemBlock<>(block);
+            Item item = block.blockItemSupplier.get();
+            if (((BlockAccessor)(Object)block).getStatParent() != null) {
+                item.setStatParent(((BlockAccessor)(Object)block).getStatParent());
             }
+            Item.itemsList[item.id] = item;
+
 
             block.getLogic().initializeBlock();
             BlocksAccessor.cacheBlock(block);
         }
 
         Assignment.queueBlockModel(block, blockModelSupplier, textures);
-//        ItemBuilder.Assignment.queueItemModel(BlockItem, customItemModelSupplier, itemIcon); // TODO reimpl item model
+        ItemBuilder.Assignment.queueItemModel(block.id(), customItemModelSupplier, itemIcon); // TODO reimpl item model
 
         return block;
     }
@@ -644,7 +665,7 @@ public static class Assignment{
         /**
          *  Queues a BlockModel assignment until the game is ready to do so
          */
-        public static <T extends Block> void queueBlockModel(@NotNull T block, Function<T, BlockModel<?>> blockModelSupplier, @Nullable String[] textures){
+        public static <T extends Block<?>> void queueBlockModel(@NotNull T block, Function<T, BlockModel<?>> blockModelSupplier, @Nullable String[] textures){
             if (!HalpLibe.isClient) return;
             if (blockModelSupplier == null) return;
 
@@ -655,7 +676,7 @@ public static <T extends Block> void queueBlockModel(@NotNull T block, Function<
             queuedBlockModels.add(new BlockAssignmentEntry<>(block, blockModelSupplier, textures));
         }
 
-        public static class BlockAssignmentEntry<T extends Block>{
+        public static class BlockAssignmentEntry<T extends Block<?>>{
             public final T block;
             public final Function<T, BlockModel<?>> modelFunction;
             public final String[] textures;
diff --git a/src/main/java/turniplabs/halplibe/helper/EntityHelper.java b/src/main/java/turniplabs/halplibe/helper/EntityHelper.java
index 9cc1bda..a64de01 100644
--- a/src/main/java/turniplabs/halplibe/helper/EntityHelper.java
+++ b/src/main/java/turniplabs/halplibe/helper/EntityHelper.java
@@ -93,7 +93,7 @@ public static void queueEntityRenderer(@NotNull Class<? extends Entity> clazz, @
             }
             queuedEntityRenderer.put(clazz, rendererSupplier);
         }
-        public static boolean TileEntityRendererDispatcherInitialized = false;
+        public static boolean tileEntityRendererDispatcherInitialized = false;
         public static final Map<Class<? extends TileEntity> , Supplier<TileEntityRenderer<?>>> queuedTileEntityRenderer = new LinkedHashMap<>();
         /**
          *  Queues a TileEntityRenderer assignment until the game is ready to do so
@@ -102,7 +102,7 @@ public static void queueTileEntityRenderer(@NotNull Class<? extends TileEntity>
             if (!HalpLibe.isClient) return;
             Objects.requireNonNull(rendererSupplier, "Renderer Supplier must not be null!");
 
-            if (TileEntityRendererDispatcherInitialized){
+            if (tileEntityRendererDispatcherInitialized){
                 Map<Class<? extends TileEntity>, TileEntityRenderer<?>> specialRendererMap = ((TileEntityRendererAccessor) BlockEntityRenderDispatcher.instance).getSpecialRendererMap();
                 TileEntityRenderer<?> renderer = rendererSupplier.get();
                 specialRendererMap.put(clazz, renderer);
diff --git a/src/main/java/turniplabs/halplibe/helper/ItemBuilder.java b/src/main/java/turniplabs/halplibe/helper/ItemBuilder.java
index a8f94a7..9d8d74c 100644
--- a/src/main/java/turniplabs/halplibe/helper/ItemBuilder.java
+++ b/src/main/java/turniplabs/halplibe/helper/ItemBuilder.java
@@ -182,7 +182,7 @@ public <T extends Item> T build(T item){
         newTokens.add(modId);
         newTokens.addAll(tokens.subList(1, tokens.size()));
 
-        Assignment.queueItemModel(item, customItemModelSupplier, textureKey);
+        Assignment.queueItemModel(item.id, customItemModelSupplier, textureKey);
 
         item.setKey(StringUtils.join(newTokens, "."));
 
@@ -195,25 +195,26 @@ public static class Assignment{
         /**
          *  Queues a ItemModel assignment until the game is ready to do so
          */
-        public static <T extends Item> void queueItemModel(@NotNull T item, @NotNull Function<T, ItemModel> itemModelSupplier, @Nullable String iconTexture){
+        public static <T extends Item> void queueItemModel(int id, @NotNull Function<T, ItemModel> itemModelSupplier, @Nullable String iconTexture){
             if (!HalpLibe.isClient) return;
             if (itemDispatcherInitialized){
-                ItemModelDispatcher.getInstance().addDispatch(new ItemAssignmentEntry<>(item, itemModelSupplier, iconTexture).getModel());
+                ItemModelDispatcher.getInstance().addDispatch(new ItemAssignmentEntry<>(id, itemModelSupplier, iconTexture).getModel());
                 return;
             }
-            queuedItemModels.add(new ItemAssignmentEntry<>(item, itemModelSupplier, iconTexture));
+            queuedItemModels.add(new ItemAssignmentEntry<>(id, itemModelSupplier, iconTexture));
         }
         public static class ItemAssignmentEntry<T extends Item>{
-            public final T item;
+            public final int itemId;
             public final Function<T, ItemModel> modelFunction;
             public final String iconKey;
 
-            public ItemAssignmentEntry(T item, Function<T, ItemModel> modelFunction, String iconKey){
-                this.item = item;
+            public ItemAssignmentEntry(int id, Function<T, ItemModel> modelFunction, String iconKey){
+                this.itemId = id;
                 this.modelFunction = modelFunction;
                 this.iconKey = iconKey;
             }
             public ItemModel getModel(){
+                T item = (T) Item.itemsList[itemId];
                 ItemModel model = modelFunction.apply(item);
 
                 if (model instanceof ItemModelStandard && iconKey != null){
diff --git a/src/main/java/turniplabs/halplibe/mixin/accessors/BlockAccessor.java b/src/main/java/turniplabs/halplibe/mixin/accessors/BlockAccessor.java
new file mode 100644
index 0000000..977e3d7
--- /dev/null
+++ b/src/main/java/turniplabs/halplibe/mixin/accessors/BlockAccessor.java
@@ -0,0 +1,15 @@
+package turniplabs.halplibe.mixin.accessors;
+
+import net.minecraft.core.block.Block;
+import net.minecraft.core.item.IItemConvertible;
+import org.jetbrains.annotations.NotNull;
+import org.spongepowered.asm.mixin.Mixin;
+import org.spongepowered.asm.mixin.gen.Accessor;
+
+import java.util.function.Supplier;
+
+@Mixin(value = Block.class, remap = false)
+public interface BlockAccessor {
+    @Accessor("statParent")
+    Supplier<@NotNull IItemConvertible> getStatParent();
+}
diff --git a/src/main/java/turniplabs/halplibe/mixin/models/BlockColorDispatcherMixin.java b/src/main/java/turniplabs/halplibe/mixin/models/BlockColorDispatcherMixin.java
new file mode 100644
index 0000000..a6e7920
--- /dev/null
+++ b/src/main/java/turniplabs/halplibe/mixin/models/BlockColorDispatcherMixin.java
@@ -0,0 +1,32 @@
+package turniplabs.halplibe.mixin.models;
+
+import net.minecraft.client.render.block.color.BlockColor;
+import net.minecraft.client.render.block.color.BlockColorDispatcher;
+import net.minecraft.client.util.dispatch.Dispatcher;
+import net.minecraft.core.block.Block;
+import org.spongepowered.asm.mixin.Mixin;
+import org.spongepowered.asm.mixin.injection.At;
+import org.spongepowered.asm.mixin.injection.Inject;
+import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
+import turniplabs.halplibe.helper.BlockBuilder;
+
+import java.util.Map;
+import java.util.Set;
+import java.util.function.Function;
+
+@Mixin(value = BlockColorDispatcher.class, remap = false)
+public abstract class BlockColorDispatcherMixin extends Dispatcher<Block<?>, BlockColor> {
+
+    @Inject(method = "<init>()V", at = @At("TAIL"))
+    private void addQueuedModels(CallbackInfo ci){
+        Set<Map.Entry<Block<?>, Function<Block<?>, BlockColor>>> entries = BlockBuilder.Assignment.queuedBlockColors.entrySet();
+        for (Map.Entry<Block<?>, Function<Block<?>, BlockColor>> entry : entries){
+            try {
+                addDispatch(entry.getKey(),entry.getValue().apply(entry.getKey()));
+            } catch (Exception e){
+                throw new RuntimeException("Exception Occurred when applying " + entry.getKey().getKey(), e);
+            }
+        }
+        BlockBuilder.Assignment.blockColorDispatcherInitialized = true;
+    }
+}
diff --git a/src/main/java/turniplabs/halplibe/mixin/models/BlockModelDispatcherMixin.java b/src/main/java/turniplabs/halplibe/mixin/models/BlockModelDispatcherMixin.java
new file mode 100644
index 0000000..3326e18
--- /dev/null
+++ b/src/main/java/turniplabs/halplibe/mixin/models/BlockModelDispatcherMixin.java
@@ -0,0 +1,27 @@
+package turniplabs.halplibe.mixin.models;
+
+import net.minecraft.client.render.block.model.BlockModel;
+import net.minecraft.client.render.block.model.BlockModelDispatcher;
+import org.spongepowered.asm.mixin.Mixin;
+import org.spongepowered.asm.mixin.Shadow;
+import org.spongepowered.asm.mixin.injection.At;
+import org.spongepowered.asm.mixin.injection.Inject;
+import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
+import turniplabs.halplibe.helper.BlockBuilder;
+
+@Mixin(value = BlockModelDispatcher.class, remap = false)
+public abstract class BlockModelDispatcherMixin {
+    @Shadow public abstract void addDispatch(BlockModel<?> dispatchable);
+
+    @Inject(method = "<init>()V", at = @At("TAIL"))
+    private void addQueuedModels(CallbackInfo ci){
+        for (BlockBuilder.Assignment.BlockAssignmentEntry<?> entry : BlockBuilder.Assignment.queuedBlockModels){
+            try {
+                addDispatch(entry.getModel());
+            } catch (Exception e){
+                throw new RuntimeException("Exception Occurred when applying " + entry.block.getKey(), e);
+            }
+        }
+        BlockBuilder.Assignment.blockDispatcherInitialized = true;
+    }
+}
diff --git a/src/main/java/turniplabs/halplibe/mixin/models/EntityRenderDispatcherMixin.java b/src/main/java/turniplabs/halplibe/mixin/models/EntityRenderDispatcherMixin.java
new file mode 100644
index 0000000..b9bd8f0
--- /dev/null
+++ b/src/main/java/turniplabs/halplibe/mixin/models/EntityRenderDispatcherMixin.java
@@ -0,0 +1,36 @@
+package turniplabs.halplibe.mixin.models;
+
+import net.minecraft.client.render.EntityRenderDispatcher;
+import net.minecraft.client.render.entity.EntityRenderer;
+import net.minecraft.core.entity.Entity;
+import org.spongepowered.asm.mixin.Final;
+import org.spongepowered.asm.mixin.Mixin;
+import org.spongepowered.asm.mixin.Shadow;
+import org.spongepowered.asm.mixin.injection.At;
+import org.spongepowered.asm.mixin.injection.Inject;
+import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
+import turniplabs.halplibe.helper.EntityHelper;
+
+import java.util.Map;
+import java.util.Set;
+import java.util.function.Supplier;
+
+@Mixin(value = EntityRenderDispatcher.class, remap = false)
+public abstract class EntityRenderDispatcherMixin {
+    @Shadow @Final private Map<Class<?>, EntityRenderer<?>> renderers;
+
+    @Inject(method = "<init>()V", at = @At("TAIL"))
+    private void addQueuedModels(CallbackInfo ci){
+        Set<Map.Entry<Class<? extends Entity> , Supplier<EntityRenderer<?>>>> entries = EntityHelper.Assignment.queuedEntityRenderer.entrySet();
+        for (Map.Entry<Class<? extends Entity> , Supplier<EntityRenderer<?>>> entry : entries){
+            try {
+                EntityRenderer<?> renderer = entry.getValue().get();
+                renderers.put(entry.getKey(), renderer);
+                renderer.init((EntityRenderDispatcher) (Object)this);
+            } catch (Exception e){
+                throw new RuntimeException("Exception Occurred when applying " + entry.getKey().getSimpleName(), e);
+            }
+        }
+        EntityHelper.Assignment.entityRendererDispatcherInitialized = true;
+    }
+}
diff --git a/src/main/java/turniplabs/halplibe/mixin/models/ItemModelDispatcherMixin.java b/src/main/java/turniplabs/halplibe/mixin/models/ItemModelDispatcherMixin.java
new file mode 100644
index 0000000..9a544da
--- /dev/null
+++ b/src/main/java/turniplabs/halplibe/mixin/models/ItemModelDispatcherMixin.java
@@ -0,0 +1,28 @@
+package turniplabs.halplibe.mixin.models;
+
+import net.minecraft.client.render.item.model.ItemModel;
+import net.minecraft.client.render.item.model.ItemModelDispatcher;
+import net.minecraft.core.item.Item;
+import org.spongepowered.asm.mixin.Mixin;
+import org.spongepowered.asm.mixin.Shadow;
+import org.spongepowered.asm.mixin.injection.At;
+import org.spongepowered.asm.mixin.injection.Inject;
+import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
+import turniplabs.halplibe.helper.ItemBuilder;
+@Mixin(value = ItemModelDispatcher.class, remap = false)
+public abstract class ItemModelDispatcherMixin {
+    @Shadow public abstract void addDispatch(ItemModel dispatchable);
+
+    @Inject(method = "<init>()V", at = @At("TAIL"))
+    private void addQueuedModels(CallbackInfo ci){
+        for (ItemBuilder.Assignment.ItemAssignmentEntry<?> entry : ItemBuilder.Assignment.queuedItemModels){
+            try {
+                addDispatch(entry.getModel());
+            } catch (Exception e){
+                throw new RuntimeException("Exception Occurred when applying " + Item.getItem(entry.itemId).getKey(), e);
+            }
+        }
+        ItemBuilder.Assignment.queuedItemModels.clear();
+        ItemBuilder.Assignment.itemDispatcherInitialized = true;
+    }
+}
diff --git a/src/main/java/turniplabs/halplibe/mixin/models/TileEntityRendererDispatcherMixin.java b/src/main/java/turniplabs/halplibe/mixin/models/TileEntityRendererDispatcherMixin.java
new file mode 100644
index 0000000..afe2c76
--- /dev/null
+++ b/src/main/java/turniplabs/halplibe/mixin/models/TileEntityRendererDispatcherMixin.java
@@ -0,0 +1,36 @@
+package turniplabs.halplibe.mixin.models;
+
+import net.minecraft.client.render.BlockEntityRenderDispatcher;
+import net.minecraft.client.render.blockentity.TileEntityRenderer;
+import net.minecraft.core.block.entity.TileEntity;
+import org.spongepowered.asm.mixin.Final;
+import org.spongepowered.asm.mixin.Mixin;
+import org.spongepowered.asm.mixin.Shadow;
+import org.spongepowered.asm.mixin.injection.At;
+import org.spongepowered.asm.mixin.injection.Inject;
+import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
+import turniplabs.halplibe.helper.EntityHelper;
+
+import java.util.Map;
+import java.util.Set;
+import java.util.function.Supplier;
+
+@Mixin(value = BlockEntityRenderDispatcher.class, remap = false)
+public class TileEntityRendererDispatcherMixin {
+    @Shadow @Final private Map<Class<?>, TileEntityRenderer<?>> renderers;
+
+    @Inject(method = "<init>()V", at = @At("TAIL"))
+    private void addQueuedModels(CallbackInfo ci){
+        Set<Map.Entry<Class<? extends TileEntity> , Supplier<TileEntityRenderer<?>>>> entries = EntityHelper.Assignment.queuedTileEntityRenderer.entrySet();
+        for (Map.Entry<Class<? extends TileEntity> , Supplier<TileEntityRenderer<?>>> entry : entries){
+            try {
+                TileEntityRenderer<?> renderer = entry.getValue().get();
+                renderers.put(entry.getKey(), renderer);
+                renderer.setRenderDispatcher((BlockEntityRenderDispatcher) (Object)this);
+            } catch (Exception e){
+                throw new RuntimeException("Exception Occurred when applying " + entry.getKey().getSimpleName(), e);
+            }
+        }
+        EntityHelper.Assignment.tileEntityRendererDispatcherInitialized = true;
+    }
+}
diff --git a/src/main/resources/halplibe.mixins.json b/src/main/resources/halplibe.mixins.json
index 78f716c..07f642f 100644
--- a/src/main/resources/halplibe.mixins.json
+++ b/src/main/resources/halplibe.mixins.json
@@ -7,6 +7,7 @@
     "I18nMixin",
     "MinecraftMixin",
     "MinecraftServerMixin",
+    "accessors.BlockAccessor",
     "accessors.BlocksAccessor",
     "accessors.EntityFireflyFXAccessor",
     "accessors.EntityFXAccessor",
@@ -14,7 +15,12 @@
     "accessors.RenderManagerAccessor"
   ],
   "client": [
-    "accessors.TileEntityRendererAccessor"
+    "accessors.TileEntityRendererAccessor",
+    "models.BlockColorDispatcherMixin",
+    "models.BlockModelDispatcherMixin",
+    "models.EntityRenderDispatcherMixin",
+    "models.ItemModelDispatcherMixin",
+    "models.TileEntityRendererDispatcherMixin"
   ],
   "server": [
   ],