diff --git a/.architectury-transformer/debug.log b/.architectury-transformer/debug.log
new file mode 100644
index 0000000..b81c285
--- /dev/null
+++ b/.architectury-transformer/debug.log
@@ -0,0 +1 @@
+[Architectury Transformer DEBUG] Closing File Systems for D:\Git\Matrix\common\build\libs\matrix-1.0.0.jar
diff --git a/.vscode/launch.json b/.vscode/launch.json
new file mode 100644
index 0000000..8a29359
--- /dev/null
+++ b/.vscode/launch.json
@@ -0,0 +1,63 @@
+{
+  "version": "0.2.0",
+  "configurations": [
+    {
+      "type": "java",
+      "name": "Minecraft Client (:fabric)",
+      "request": "launch",
+      "cwd": "${workspaceFolder}/fabric/run",
+      "console": "internalConsole",
+      "stopOnEntry": false,
+      "mainClass": "dev.architectury.transformer.TransformerRuntime",
+      "vmArgs": "\"-Dfabric.dli.config\u003dD:\\Git\\Matrix\\fabric\\.gradle\\loom-cache\\launch.cfg\" \"-Dfabric.dli.env\u003dclient\" \"-Dfabric.dli.main\u003dnet.fabricmc.loader.impl.launch.knot.KnotClient\" \"-Darchitectury.main.class\u003dD:\\Git\\Matrix\\fabric\\.gradle\\architectury\\.main_class\" \"-Darchitectury.runtime.transformer\u003dD:\\Git\\Matrix\\fabric\\.gradle\\architectury\\.transforms\" \"-Darchitectury.properties\u003dD:\\Git\\Matrix\\fabric\\.gradle\\architectury\\.properties\" \"-Djdk.attach.allowAttachSelf\u003dtrue\" \"-javaagent:D:\\Git\\Matrix\\.gradle\\architectury\\architectury-transformer-agent.jar\"",
+      "args": "",
+      "env": {},
+      "projectName": "fabric"
+    },
+    {
+      "type": "java",
+      "name": "Minecraft Server (:fabric)",
+      "request": "launch",
+      "cwd": "${workspaceFolder}/fabric/run",
+      "console": "internalConsole",
+      "stopOnEntry": false,
+      "mainClass": "dev.architectury.transformer.TransformerRuntime",
+      "vmArgs": "\"-Dfabric.dli.config\u003dD:\\Git\\Matrix\\fabric\\.gradle\\loom-cache\\launch.cfg\" \"-Dfabric.dli.env\u003dserver\" \"-Dfabric.dli.main\u003dnet.fabricmc.loader.impl.launch.knot.KnotServer\" \"-Darchitectury.main.class\u003dD:\\Git\\Matrix\\fabric\\.gradle\\architectury\\.main_class\" \"-Darchitectury.runtime.transformer\u003dD:\\Git\\Matrix\\fabric\\.gradle\\architectury\\.transforms\" \"-Darchitectury.properties\u003dD:\\Git\\Matrix\\fabric\\.gradle\\architectury\\.properties\" \"-Djdk.attach.allowAttachSelf\u003dtrue\" \"-javaagent:D:\\Git\\Matrix\\.gradle\\architectury\\architectury-transformer-agent.jar\"",
+      "args": "\"nogui\"",
+      "env": {},
+      "projectName": "fabric"
+    },
+    {
+      "type": "java",
+      "name": "Minecraft Client (:forge)",
+      "request": "launch",
+      "cwd": "${workspaceFolder}/forge/run",
+      "console": "internalConsole",
+      "stopOnEntry": false,
+      "mainClass": "dev.architectury.transformer.TransformerRuntime",
+      "vmArgs": "\"-Dfabric.dli.config\u003dD:\\Git\\Matrix\\forge\\.gradle\\loom-cache\\launch.cfg\" \"-Dfabric.dli.env\u003dclient\" \"-p\" \"C:\\Users\\water\\.gradle\\caches\\modules-2\\files-2.1\\cpw.mods\\securejarhandler\\0.9.54\\24b670f2c026ec9777e64a2c2126ebc8635dbe8d\\securejarhandler-0.9.54.jar;C:\\Users\\water\\.gradle\\caches\\modules-2\\files-2.1\\org.ow2.asm\\asm-commons\\9.1\\8b971b182eb5cf100b9e8d4119152d83e00e0fdd\\asm-commons-9.1.jar;C:\\Users\\water\\.gradle\\caches\\modules-2\\files-2.1\\org.ow2.asm\\asm-util\\9.1\\36464a45d871779f3383a8a9aba2b26562a86729\\asm-util-9.1.jar;C:\\Users\\water\\.gradle\\caches\\modules-2\\files-2.1\\org.ow2.asm\\asm-analysis\\9.1\\4f61b83b81d8b659958f4bcc48907e93ecea55a0\\asm-analysis-9.1.jar;C:\\Users\\water\\.gradle\\caches\\modules-2\\files-2.1\\org.ow2.asm\\asm-tree\\9.1\\c333f2a855069cb8eb17a40a3eb8b1b67755d0eb\\asm-tree-9.1.jar;C:\\Users\\water\\.gradle\\caches\\modules-2\\files-2.1\\org.ow2.asm\\asm\\9.1\\a99500cf6eea30535eeac6be73899d048f8d12a8\\asm-9.1.jar\" \"--add-modules\" \"ALL-MODULE-PATH\" \"--add-opens\" \"java.base/java.util.jar\u003dcpw.mods.securejarhandler\" \"--add-exports\" \"java.base/sun.security.util\u003dcpw.mods.securejarhandler\" \"--add-exports\" \"jdk.naming.dns/com.sun.jndi.dns\u003djava.naming\" \"-Dfabric.dli.main\u003dcpw.mods.bootstraplauncher.BootstrapLauncher\" \"-Darchitectury.main.class\u003dD:\\Git\\Matrix\\forge\\.gradle\\architectury\\.main_class\" \"-Darchitectury.runtime.transformer\u003dD:\\Git\\Matrix\\forge\\.gradle\\architectury\\.transforms\" \"-Darchitectury.properties\u003dD:\\Git\\Matrix\\forge\\.gradle\\architectury\\.properties\" \"-Djdk.attach.allowAttachSelf\u003dtrue\" \"-javaagent:D:\\Git\\Matrix\\.gradle\\architectury\\architectury-transformer-agent.jar\"",
+      "args": "",
+      "env": {
+        "MOD_CLASSES": "main%%D:\\Git\\Matrix\\forge\\build\\resources\\main;main%%D:\\Git\\Matrix\\forge\\build\\classes\\java\\main",
+        "MCP_MAPPINGS": "loom.stub"
+      },
+      "projectName": "forge"
+    },
+    {
+      "type": "java",
+      "name": "Minecraft Server (:forge)",
+      "request": "launch",
+      "cwd": "${workspaceFolder}/forge/run",
+      "console": "internalConsole",
+      "stopOnEntry": false,
+      "mainClass": "dev.architectury.transformer.TransformerRuntime",
+      "vmArgs": "\"-Dfabric.dli.config\u003dD:\\Git\\Matrix\\forge\\.gradle\\loom-cache\\launch.cfg\" \"-Dfabric.dli.env\u003dserver\" \"-p\" \"C:\\Users\\water\\.gradle\\caches\\modules-2\\files-2.1\\cpw.mods\\securejarhandler\\0.9.54\\24b670f2c026ec9777e64a2c2126ebc8635dbe8d\\securejarhandler-0.9.54.jar;C:\\Users\\water\\.gradle\\caches\\modules-2\\files-2.1\\org.ow2.asm\\asm-commons\\9.1\\8b971b182eb5cf100b9e8d4119152d83e00e0fdd\\asm-commons-9.1.jar;C:\\Users\\water\\.gradle\\caches\\modules-2\\files-2.1\\org.ow2.asm\\asm-util\\9.1\\36464a45d871779f3383a8a9aba2b26562a86729\\asm-util-9.1.jar;C:\\Users\\water\\.gradle\\caches\\modules-2\\files-2.1\\org.ow2.asm\\asm-analysis\\9.1\\4f61b83b81d8b659958f4bcc48907e93ecea55a0\\asm-analysis-9.1.jar;C:\\Users\\water\\.gradle\\caches\\modules-2\\files-2.1\\org.ow2.asm\\asm-tree\\9.1\\c333f2a855069cb8eb17a40a3eb8b1b67755d0eb\\asm-tree-9.1.jar;C:\\Users\\water\\.gradle\\caches\\modules-2\\files-2.1\\org.ow2.asm\\asm\\9.1\\a99500cf6eea30535eeac6be73899d048f8d12a8\\asm-9.1.jar\" \"--add-modules\" \"ALL-MODULE-PATH\" \"--add-opens\" \"java.base/java.util.jar\u003dcpw.mods.securejarhandler\" \"--add-exports\" \"java.base/sun.security.util\u003dcpw.mods.securejarhandler\" \"--add-exports\" \"jdk.naming.dns/com.sun.jndi.dns\u003djava.naming\" \"-Dfabric.dli.main\u003dcpw.mods.bootstraplauncher.BootstrapLauncher\" \"-Darchitectury.main.class\u003dD:\\Git\\Matrix\\forge\\.gradle\\architectury\\.main_class\" \"-Darchitectury.runtime.transformer\u003dD:\\Git\\Matrix\\forge\\.gradle\\architectury\\.transforms\" \"-Darchitectury.properties\u003dD:\\Git\\Matrix\\forge\\.gradle\\architectury\\.properties\" \"-Djdk.attach.allowAttachSelf\u003dtrue\" \"-javaagent:D:\\Git\\Matrix\\.gradle\\architectury\\architectury-transformer-agent.jar\"",
+      "args": "\"nogui\"",
+      "env": {
+        "MOD_CLASSES": "main%%D:\\Git\\Matrix\\forge\\build\\resources\\main;main%%D:\\Git\\Matrix\\forge\\build\\classes\\java\\main",
+        "MCP_MAPPINGS": "loom.stub"
+      },
+      "projectName": "forge"
+    }
+  ]
+}
\ No newline at end of file
diff --git a/build.gradle b/build.gradle
index 271dd9b..9098770 100644
--- a/build.gradle
+++ b/build.gradle
@@ -1,63 +1,51 @@
-plugins {
-	id "fabric-loom" version "0.6-SNAPSHOT"
-	id "org.cadixdev.licenser" version "0.5.0"
-}
-
-apply plugin: "java"
-
-sourceCompatibility = 1.8
-targetCompatibility = 1.8
-
-sourceSets {
-	testmod
-}
-
-dependencies {
-	minecraft "com.mojang:minecraft:21w08b"
-	mappings "net.fabricmc:yarn:21w08b+build.8:v2"
-	modImplementation "net.fabricmc:fabric-loader:0.11.1"
-	testmodImplementation sourceSets.main.output
-	testmodCompileOnly sourceSets.main.compileClasspath
-	testmodRuntimeOnly sourceSets.main.runtimeClasspath
-	modRuntime("net.fabricmc.fabric-api:fabric-api:0.31.2+1.17") {
-		exclude module: "fabric-loader"
-	}
-}
-
-version = "1.0.0"
-archivesBaseName = "Matrix"
-group = "org.dimdev"
-
-license {
-	include '**/*.java'
-}
-
-processResources {
-	filesMatching("fabric.mod.json") {
-		expand "version": project.version
-	}
-
-	inputs.property "version", project.version
-}
-
-tasks.withType(JavaCompile).configureEach {
-	it.options.encoding = "UTF-8"
-	def targetVersion = 8
-	if (JavaVersion.current().isJava9Compatible()) {
-		it.options.release.set(targetVersion)
-	}
-}
-
-java {
-	withSourcesJar()
-}
-
-jar {
-	from("LICENSE") {
-		rename { "${it}_${project.archivesBaseName}"}
-	}
-}
-
-artifacts {
-	archives jar
-}
+plugins {
+	id "architectury-plugin" version "3.4-SNAPSHOT"
+	id "dev.architectury.loom" version "0.10.0-SNAPSHOT" apply false
+}
+
+architectury {
+	minecraft = rootProject.minecraft_version
+}
+
+subprojects {
+	apply plugin: "dev.architectury.loom"
+
+	loom {
+		silentMojangMappingsLicense()
+	}
+
+	dependencies {
+		minecraft "com.mojang:minecraft:${rootProject.minecraft_version}"
+		// The following line declares the mojmap mappings, you may use other mappings as well
+		mappings loom.officialMojangMappings()
+		// The following line declares the yarn mappings you may select this one as well.
+		// mappings "net.fabricmc:yarn:1.18+build.1:v2"
+	}
+}
+
+allprojects {
+	apply plugin: "java"
+	apply plugin: "architectury-plugin"
+	apply plugin: "maven-publish"
+
+	archivesBaseName = rootProject.archives_base_name
+	version = rootProject.version
+	group = rootProject.group
+
+	repositories {
+		// Add repositories to retrieve artifacts from in here.
+		// You should only use this when depending on other mods because
+		// Loom adds the essential maven repositories to download Minecraft and libraries from automatically.
+		// See https://docs.gradle.org/current/userguide/declaring_repositories.html
+		// for more information about repositories.
+	}
+
+	tasks.withType(JavaCompile) {
+		options.encoding = "UTF-8"
+		options.release = 17
+	}
+
+	java {
+		withSourcesJar()
+	}
+}
diff --git a/common/build.gradle b/common/build.gradle
new file mode 100644
index 0000000..c253f86
--- /dev/null
+++ b/common/build.gradle
@@ -0,0 +1,25 @@
+dependencies {
+    // We depend on fabric loader here to use the fabric @Environment annotations and get the mixin dependencies
+    // Do NOT use other classes from fabric loader
+    modImplementation "net.fabricmc:fabric-loader:${rootProject.fabric_loader_version}"
+    // Remove the next line if you don't want to depend on the API
+    modApi "dev.architectury:architectury:${rootProject.architectury_version}"
+}
+
+architectury {
+    common()
+}
+
+publishing {
+    publications {
+        mavenCommon(MavenPublication) {
+            artifactId = rootProject.archives_base_name
+            from components.java
+        }
+    }
+
+    // See https://docs.gradle.org/current/userguide/publishing_maven.html for information on how to set up publishing.
+    repositories {
+        // Add repositories to publish to here.
+    }
+}
diff --git a/src/main/java/org/dimdev/matrix/Matrix.java b/common/src/main/java/org/dimdev/matrix/Matrix.java
similarity index 60%
rename from src/main/java/org/dimdev/matrix/Matrix.java
rename to common/src/main/java/org/dimdev/matrix/Matrix.java
index 74ad732..87823b7 100644
--- a/src/main/java/org/dimdev/matrix/Matrix.java
+++ b/common/src/main/java/org/dimdev/matrix/Matrix.java
@@ -1,59 +1,68 @@
-package org.dimdev.matrix;
-
-import java.lang.reflect.Modifier;
-import java.util.Arrays;
-
-import net.minecraft.item.BlockItem;
-import net.minecraft.item.Item;
-import net.minecraft.util.Identifier;
-import net.minecraft.util.registry.Registry;
-
-/**
- * An Annotation Based Registration Library.
- *
- * <p>Matrix allows registering items, blocks, etc. without
- * calling {@code Registry.register(...)} a bunch of times or
- * registering at static init. Registering at static init
- * is not safe as you might just register the entries much
- * before vanilla registers its entries.</p>
- *
- * <p>Using Annotations is simple and easy to migrate to.
- * You no longer have to worry about skipping a call to
- * {@code Registry.register(...)}.</p>
- */
-public class Matrix {
-	/**
-	 *
-	 * @param clazz The class that should be scanned for registry entries.
-	 * @param registry The registry that entries should be registered to.
-	 */
-	@SuppressWarnings({"unchecked", "rawtypes"})
-	public static void register(Class<?> clazz, Registry<?> registry) {
-		Registrar registrar = clazz.getAnnotation(Registrar.class);
-		if (registrar == null) {
-			return;
-		}
-
-		String modid = registrar.modid();
-		Class<?> element = registrar.element();
-
-		Arrays.stream(clazz.getFields())
-				.filter(field -> field.isAnnotationPresent(RegistryEntry.class)
-						&& Modifier.isPublic(field.getModifiers())
-						&& Modifier.isStatic(field.getModifiers())
-						&& Modifier.isFinal(field.getModifiers())
-						&& element.isAssignableFrom(field.getType())
-				)
-				.forEach(field -> {
-					try {
-						Object value = field.get(null);
-						Registry.register((Registry) registry, new Identifier(modid, field.getAnnotation(RegistryEntry.class).value()), element.cast(value));
-						if (value instanceof BlockItem) {
-							Item.BLOCK_ITEMS.put(((BlockItem) value).getBlock(), (Item) value);
-						}
-					} catch (IllegalAccessException e) {
-						throw new AssertionError(e);
-					}
-				});
-	}
-}
+package org.dimdev.matrix;
+
+import dev.architectury.registry.registries.DeferredRegister;
+import net.minecraft.core.Registry;
+import net.minecraft.resources.ResourceKey;
+import net.minecraft.resources.ResourceLocation;
+import net.minecraft.world.item.BlockItem;
+import net.minecraft.world.item.Item;
+
+import java.lang.reflect.Modifier;
+import java.util.Arrays;
+
+/**
+ * An Annotation Based Registration Library.
+ *
+ * <p>Matrix allows registering items, blocks, etc. without
+ * calling {@code Registry.register(...)} a bunch of times or
+ * registering at static init. Registering at static init
+ * is not safe as you might just register the entries much
+ * before vanilla registers its entries.</p>
+ *
+ * <p>Using Annotations is simple and easy to migrate to.
+ * You no longer have to worry about skipping a call to
+ * {@code Registry.register(...)}.</p>
+ */
+public class Matrix {
+	/**
+	 *
+	 * @param clazz The class that should be scanned for registry entries.
+	 * @param registryKey The resource key for the registry being registered to.
+	 */
+	@SuppressWarnings({"unchecked", "rawtypes"})
+	public static <T, S> void register(Class<T> clazz, ResourceKey<Registry<S>> registryKey) {
+		Registrar registrar = clazz.getAnnotation(Registrar.class);
+		if (registrar == null) {
+			return;
+		}
+
+		String modid = registrar.modid();
+
+		Class<?> element = registrar.element();
+
+		DeferredRegister<S> deferredRegister = DeferredRegister.create(modid, registryKey);
+
+		Arrays.stream(clazz.getFields())
+				.filter(field -> field.isAnnotationPresent(RegistryEntry.class)
+						&& Modifier.isPublic(field.getModifiers())
+						&& Modifier.isStatic(field.getModifiers())
+						&& Modifier.isFinal(field.getModifiers())
+						&& element.isAssignableFrom(field.getType())
+				)
+				.forEach(field -> {
+					try {
+						Object value = field.get(null);
+
+						deferredRegister.register(new ResourceLocation(modid, field.getAnnotation(RegistryEntry.class).value()), () -> (S) value);
+						if (value instanceof BlockItem) {
+							Item.BY_BLOCK.put(((BlockItem) value).getBlock(), (Item) value);
+						}
+					} catch (IllegalAccessException e) {
+						throw new AssertionError(e);
+					} catch (ClassCastException e) {
+						//TODO: Make this print more concise details than a stacktrace
+						e.printStackTrace();
+					}
+				});
+	}
+}
diff --git a/src/main/java/org/dimdev/matrix/Registrar.java b/common/src/main/java/org/dimdev/matrix/Registrar.java
similarity index 96%
rename from src/main/java/org/dimdev/matrix/Registrar.java
rename to common/src/main/java/org/dimdev/matrix/Registrar.java
index 26afcc4..e5a0af8 100644
--- a/src/main/java/org/dimdev/matrix/Registrar.java
+++ b/common/src/main/java/org/dimdev/matrix/Registrar.java
@@ -1,20 +1,20 @@
-package org.dimdev.matrix;
-
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
-
-/**
- * Specifies the namespace for registry entries.
- *
- * <p>This must be annotated on the class you wish
- * to keep all your registry entries (as fields).</p>
- */
-@Retention(RetentionPolicy.RUNTIME)
-@Target(ElementType.TYPE)
-public @interface Registrar {
-	Class<?> element();
-
-	String modid();
-}
+package org.dimdev.matrix;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Specifies the namespace for registry entries.
+ *
+ * <p>This must be annotated on the class you wish
+ * to keep all your registry entries (as fields).</p>
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.TYPE)
+public @interface Registrar {
+	Class<?> element();
+
+	String modid();
+}
diff --git a/src/main/java/org/dimdev/matrix/RegistryEntry.java b/common/src/main/java/org/dimdev/matrix/RegistryEntry.java
similarity index 95%
rename from src/main/java/org/dimdev/matrix/RegistryEntry.java
rename to common/src/main/java/org/dimdev/matrix/RegistryEntry.java
index 379821d..172564e 100644
--- a/src/main/java/org/dimdev/matrix/RegistryEntry.java
+++ b/common/src/main/java/org/dimdev/matrix/RegistryEntry.java
@@ -1,18 +1,18 @@
-package org.dimdev.matrix;
-
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
-
-/**
- * Specifies that the annotated field should be registered.
- */
-@Retention(RetentionPolicy.RUNTIME)
-@Target(ElementType.FIELD)
-public @interface RegistryEntry {
-	/**
-	 * The id of the registry entry.
-	 */
-	String value();
-}
+package org.dimdev.matrix;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Specifies that the annotated field should be registered.
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.FIELD)
+public @interface RegistryEntry {
+	/**
+	 * The id of the registry entry.
+	 */
+	String value();
+}
diff --git a/fabric/build.gradle b/fabric/build.gradle
new file mode 100644
index 0000000..9fbb272
--- /dev/null
+++ b/fabric/build.gradle
@@ -0,0 +1,75 @@
+plugins {
+    id "com.github.johnrengelman.shadow" version "7.1.2"
+}
+
+architectury {
+    platformSetupLoomIde()
+    fabric()
+}
+
+configurations {
+    common
+    shadowCommon // Don't use shadow from the shadow plugin because we don't want IDEA to index this.
+    compileClasspath.extendsFrom common
+    runtimeClasspath.extendsFrom common
+    developmentFabric.extendsFrom common
+}
+
+dependencies {
+    modImplementation "net.fabricmc:fabric-loader:${rootProject.fabric_loader_version}"
+    modApi "net.fabricmc.fabric-api:fabric-api:${rootProject.fabric_api_version}"
+    // Remove the next line if you don't want to depend on the API
+    modApi "dev.architectury:architectury-fabric:${rootProject.architectury_version}"
+
+    common(project(path: ":common", configuration: "namedElements")) { transitive false }
+    shadowCommon(project(path: ":common", configuration: "transformProductionFabric")) { transitive false }
+}
+
+processResources {
+    inputs.property "version", project.version
+
+    filesMatching("fabric.mod.json") {
+        expand "version": project.version
+    }
+}
+
+shadowJar {
+    configurations = [project.configurations.shadowCommon]
+    classifier "dev-shadow"
+}
+
+remapJar {
+    input.set shadowJar.archiveFile
+    dependsOn shadowJar
+    classifier null
+}
+
+jar {
+    classifier "dev"
+}
+
+sourcesJar {
+    def commonSources = project(":common").sourcesJar
+    dependsOn commonSources
+    from commonSources.archiveFile.map { zipTree(it) }
+}
+
+components.java {
+    withVariantsFromConfiguration(project.configurations.shadowRuntimeElements) {
+        skip()
+    }
+}
+
+publishing {
+    publications {
+        mavenFabric(MavenPublication) {
+            artifactId = rootProject.archives_base_name + "-" + project.name
+            from components.java
+        }
+    }
+
+    // See https://docs.gradle.org/current/userguide/publishing_maven.html for information on how to set up publishing.
+    repositories {
+        // Add repositories to publish to here.
+    }
+}
diff --git a/fabric/src/main/resources/fabric.mod.json b/fabric/src/main/resources/fabric.mod.json
new file mode 100644
index 0000000..20573a8
--- /dev/null
+++ b/fabric/src/main/resources/fabric.mod.json
@@ -0,0 +1,23 @@
+{
+  "schemaVersion": 1,
+  "id": "matrix",
+  "version": "${version}",
+  "name": "Matrix",
+  "description": "Annotation based registration library",
+  "authors": [
+    "Me!"
+  ],
+  "contact": {
+    "homepage": "https://fabricmc.net/",
+    "sources": "https://github.com/FabricMC/fabric-example-mod"
+  },
+  "license": "MIT",
+  "icon": "assets/examplemod/icon.png",
+  "depends": {
+    "minecraft": ">=1.18",
+    "architectury": ">=3.6.15"
+  },
+  "suggests": {
+    "flamingo": "*"
+  }
+}
\ No newline at end of file
diff --git a/forge/build.gradle b/forge/build.gradle
new file mode 100644
index 0000000..8b93a12
--- /dev/null
+++ b/forge/build.gradle
@@ -0,0 +1,76 @@
+plugins {
+    id "com.github.johnrengelman.shadow" version "7.1.2"
+}
+
+architectury {
+    platformSetupLoomIde()
+    forge()
+}
+
+configurations {
+    common
+    shadowCommon // Don't use shadow from the shadow plugin because we don't want IDEA to index this.
+    compileClasspath.extendsFrom common
+    runtimeClasspath.extendsFrom common
+    developmentForge.extendsFrom common
+}
+
+dependencies {
+    forge "net.minecraftforge:forge:${rootProject.forge_version}"
+    // Remove the next line if you don't want to depend on the API
+    modApi "dev.architectury:architectury-forge:${rootProject.architectury_version}"
+
+    common(project(path: ":common", configuration: "namedElements")) { transitive false }
+    shadowCommon(project(path: ":common", configuration: "transformProductionForge")) { transitive = false }
+}
+
+processResources {
+    inputs.property "version", project.version
+
+    filesMatching("META-INF/mods.toml") {
+        expand "version": project.version
+    }
+}
+
+shadowJar {
+    exclude "fabric.mod.json"
+
+    configurations = [project.configurations.shadowCommon]
+    classifier "dev-shadow"
+}
+
+remapJar {
+    input.set shadowJar.archiveFile
+    dependsOn shadowJar
+    classifier null
+}
+
+jar {
+    classifier "dev"
+}
+
+sourcesJar {
+    def commonSources = project(":common").sourcesJar
+    dependsOn commonSources
+    from commonSources.archiveFile.map { zipTree(it) }
+}
+
+components.java {
+    withVariantsFromConfiguration(project.configurations.shadowRuntimeElements) {
+        skip()
+    }
+}
+
+publishing {
+    publications {
+        mavenForge(MavenPublication) {
+            artifactId = rootProject.archives_base_name + "-" + project.name
+            from components.java
+        }
+    }
+
+    // See https://docs.gradle.org/current/userguide/publishing_maven.html for information on how to set up publishing.
+    repositories {
+        // Add repositories to publish to here.
+    }
+}
diff --git a/forge/gradle.properties b/forge/gradle.properties
new file mode 100644
index 0000000..32f842a
--- /dev/null
+++ b/forge/gradle.properties
@@ -0,0 +1 @@
+loom.platform=forge
\ No newline at end of file
diff --git a/forge/src/main/resources/META-INF/mods.toml b/forge/src/main/resources/META-INF/mods.toml
new file mode 100644
index 0000000..7b7459f
--- /dev/null
+++ b/forge/src/main/resources/META-INF/mods.toml
@@ -0,0 +1,28 @@
+modLoader = "javafml"
+loaderVersion = "[38,)"
+#issueTrackerURL = ""
+license = "MIT"
+
+[[mods]]
+modId = "matrix"
+version = "${version}"
+displayName = "Matrix"
+authors = "Me!"
+description = '''
+Annotation based registration library
+'''
+#logoFile = ""
+
+[[dependencies.examplemod]]
+modId = "minecraft"
+mandatory = true
+versionRange = "[1.18,)"
+ordering = "NONE"
+side = "BOTH"
+
+[[dependencies.examplemod]]
+modId = "architectury"
+mandatory = true
+versionRange = "[3.6.15,)"
+ordering = "AFTER"
+side = "BOTH"
\ No newline at end of file
diff --git a/forge/src/main/resources/pack.mcmeta b/forge/src/main/resources/pack.mcmeta
new file mode 100644
index 0000000..9252d3d
--- /dev/null
+++ b/forge/src/main/resources/pack.mcmeta
@@ -0,0 +1,6 @@
+{
+  "pack": {
+    "description": "Example Mod",
+    "pack_format": 8
+  }
+}
diff --git a/gradle.properties b/gradle.properties
new file mode 100644
index 0000000..067f866
--- /dev/null
+++ b/gradle.properties
@@ -0,0 +1,14 @@
+org.gradle.jvmargs=-Xmx2048M
+
+minecraft_version=1.18
+
+version = 1.0.0
+archives_base_name = matrix
+group = "org.dimdev"
+
+architectury_version=3.6.15
+
+fabric_loader_version=0.13.0
+fabric_api_version=0.46.4+1.18
+
+forge_version=1.18-38.0.17
diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties
index 4d9ca16..af01817 100644
--- a/gradle/wrapper/gradle-wrapper.properties
+++ b/gradle/wrapper/gradle-wrapper.properties
@@ -1,5 +1,5 @@
-distributionBase=GRADLE_USER_HOME
-distributionPath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-6.7.1-bin.zip
-zipStoreBase=GRADLE_USER_HOME
-zipStorePath=wrapper/dists
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+distributionUrl=https\://services.gradle.org/distributions/gradle-7.3.3-bin.zip
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
diff --git a/settings.gradle b/settings.gradle
index c0075e8..00793a7 100644
--- a/settings.gradle
+++ b/settings.gradle
@@ -1,13 +1,13 @@
-pluginManagement {
-    repositories {
-        jcenter()
-        maven {
-            name = 'Fabric'
-            url = 'https://maven.fabricmc.net/'
-        }
-        gradlePluginPortal()
-        mavenCentral()
-    }
-}
-
+pluginManagement {
+    repositories {
+        maven { url "https://maven.fabricmc.net/" }
+        maven { url "https://maven.architectury.dev/" }
+        maven { url "https://maven.minecraftforge.net/" }
+        gradlePluginPortal()
+    }
+}
+
+include("common")
+include("fabric")
+include("forge")
 rootProject.name = 'Matrix'
\ No newline at end of file