Selaa lähdekoodia

Convert to @ExpectPlatform

shedaniel 4 vuotta sitten
vanhempi
sitoutus
213da7a20e
73 muutettua tiedostoa jossa 792 lisäystä ja 1148 poistoa
  1. 1 1
      build.gradle
  2. 1 1
      common/src/main/java/me/shedaniel/architectury/Architectury.java
  3. 0 65
      common/src/main/java/me/shedaniel/architectury/ArchitecturyPopulator.java
  4. 3 3
      common/src/main/java/me/shedaniel/architectury/ExpectPlatform.java
  5. 35 0
      common/src/main/java/me/shedaniel/architectury/PlatformMethods.java
  6. 17 17
      common/src/main/java/me/shedaniel/architectury/event/EventHandler.java
  7. 3 14
      common/src/main/java/me/shedaniel/architectury/hooks/DyeColorHooks.java
  8. 3 14
      common/src/main/java/me/shedaniel/architectury/hooks/EntityHooks.java
  9. 9 23
      common/src/main/java/me/shedaniel/architectury/hooks/ExplosionHooks.java
  10. 15 32
      common/src/main/java/me/shedaniel/architectury/hooks/FluidStackHooks.java
  11. 3 14
      common/src/main/java/me/shedaniel/architectury/hooks/ItemEntityHooks.java
  12. 3 14
      common/src/main/java/me/shedaniel/architectury/hooks/PackRepositoryHooks.java
  13. 5 17
      common/src/main/java/me/shedaniel/architectury/hooks/PlayerHooks.java
  14. 7 20
      common/src/main/java/me/shedaniel/architectury/hooks/ScreenHooks.java
  15. 9 24
      common/src/main/java/me/shedaniel/architectury/networking/NetworkManager.java
  16. 18 38
      common/src/main/java/me/shedaniel/architectury/platform/Platform.java
  17. 3 14
      common/src/main/java/me/shedaniel/architectury/registry/BlockEntityRenderers.java
  18. 9 23
      common/src/main/java/me/shedaniel/architectury/registry/BlockProperties.java
  19. 5 17
      common/src/main/java/me/shedaniel/architectury/registry/ColorHandlers.java
  20. 3 14
      common/src/main/java/me/shedaniel/architectury/registry/CreativeTabs.java
  21. 3 14
      common/src/main/java/me/shedaniel/architectury/registry/KeyBindings.java
  22. 10 18
      common/src/main/java/me/shedaniel/architectury/registry/Registries.java
  23. 3 14
      common/src/main/java/me/shedaniel/architectury/registry/ReloadListeners.java
  24. 5 16
      common/src/main/java/me/shedaniel/architectury/registry/RenderTypes.java
  25. 9 17
      common/src/main/java/me/shedaniel/architectury/registry/ToolType.java
  26. 3 15
      common/src/main/java/me/shedaniel/architectury/utils/GameInstance.java
  27. 5 2
      fabric/build.gradle
  28. 4 8
      fabric/src/main/java/me/shedaniel/architectury/event/fabric/EventHandlerImpl.java
  29. 2 4
      fabric/src/main/java/me/shedaniel/architectury/hooks/fabric/DyeColorHooksImpl.java
  30. 2 4
      fabric/src/main/java/me/shedaniel/architectury/hooks/fabric/EntityHooksImpl.java
  31. 5 10
      fabric/src/main/java/me/shedaniel/architectury/hooks/fabric/ExplosionHooksImpl.java
  32. 2 4
      fabric/src/main/java/me/shedaniel/architectury/hooks/fabric/ItemEntityHooksImpl.java
  33. 2 4
      fabric/src/main/java/me/shedaniel/architectury/hooks/fabric/PackRepositoryHooksImpl.java
  34. 3 6
      fabric/src/main/java/me/shedaniel/architectury/hooks/fabric/PlayerHooksImpl.java
  35. 4 8
      fabric/src/main/java/me/shedaniel/architectury/hooks/fabric/ScreenHooksImpl.java
  36. 10 14
      fabric/src/main/java/me/shedaniel/architectury/networking/fabric/NetworkManagerImpl.java
  37. 13 23
      fabric/src/main/java/me/shedaniel/architectury/platform/fabric/PlatformImpl.java
  38. 2 4
      fabric/src/main/java/me/shedaniel/architectury/registry/fabric/BlockEntityRenderersImpl.java
  39. 6 10
      fabric/src/main/java/me/shedaniel/architectury/registry/fabric/BlockPropertiesImpl.java
  40. 3 6
      fabric/src/main/java/me/shedaniel/architectury/registry/fabric/ColorHandlersImpl.java
  41. 2 4
      fabric/src/main/java/me/shedaniel/architectury/registry/fabric/CreativeTabsImpl.java
  42. 2 4
      fabric/src/main/java/me/shedaniel/architectury/registry/fabric/KeyBindingsImpl.java
  43. 4 7
      fabric/src/main/java/me/shedaniel/architectury/registry/fabric/RegistriesImpl.java
  44. 4 6
      fabric/src/main/java/me/shedaniel/architectury/registry/fabric/ReloadListenersImpl.java
  45. 3 6
      fabric/src/main/java/me/shedaniel/architectury/registry/fabric/RenderTypesImpl.java
  46. 5 10
      fabric/src/main/java/me/shedaniel/architectury/registry/fabric/ToolTypeImpl.java
  47. 2 4
      fabric/src/main/java/me/shedaniel/architectury/utils/fabric/GameInstanceImpl.java
  48. 10 400
      forge/src/main/java/me/shedaniel/architectury/event/forge/EventHandlerImpl.java
  49. 136 0
      forge/src/main/java/me/shedaniel/architectury/event/forge/EventHandlerImplClient.java
  50. 274 0
      forge/src/main/java/me/shedaniel/architectury/event/forge/EventHandlerImplCommon.java
  51. 12 0
      forge/src/main/java/me/shedaniel/architectury/event/forge/EventHandlerImplServer.java
  52. 6 0
      forge/src/main/java/me/shedaniel/architectury/forge/ArchitecturyForge.java
  53. 2 4
      forge/src/main/java/me/shedaniel/architectury/hooks/forge/DyeColorHooksImpl.java
  54. 2 4
      forge/src/main/java/me/shedaniel/architectury/hooks/forge/EntityHooksImpl.java
  55. 5 10
      forge/src/main/java/me/shedaniel/architectury/hooks/forge/ExplosionHooksImpl.java
  56. 2 4
      forge/src/main/java/me/shedaniel/architectury/hooks/forge/ItemEntityHooksImpl.java
  57. 2 4
      forge/src/main/java/me/shedaniel/architectury/hooks/forge/PackRepositoryHooksImpl.java
  58. 3 6
      forge/src/main/java/me/shedaniel/architectury/hooks/forge/PlayerHooksImpl.java
  59. 4 8
      forge/src/main/java/me/shedaniel/architectury/hooks/forge/ScreenHooksImpl.java
  60. 2 3
      forge/src/main/java/me/shedaniel/architectury/networking/forge/ClientNetworkingManager.java
  61. 9 13
      forge/src/main/java/me/shedaniel/architectury/networking/forge/NetworkManagerImpl.java
  62. 13 23
      forge/src/main/java/me/shedaniel/architectury/platform/forge/PlatformImpl.java
  63. 2 4
      forge/src/main/java/me/shedaniel/architectury/registry/forge/BlockEntityRenderersImpl.java
  64. 5 9
      forge/src/main/java/me/shedaniel/architectury/registry/forge/BlockPropertiesImpl.java
  65. 4 7
      forge/src/main/java/me/shedaniel/architectury/registry/forge/ColorHandlersImpl.java
  66. 2 4
      forge/src/main/java/me/shedaniel/architectury/registry/forge/CreativeTabsImpl.java
  67. 2 4
      forge/src/main/java/me/shedaniel/architectury/registry/forge/KeyBindingsImpl.java
  68. 4 7
      forge/src/main/java/me/shedaniel/architectury/registry/forge/RegistriesImpl.java
  69. 5 7
      forge/src/main/java/me/shedaniel/architectury/registry/forge/ReloadListenersImpl.java
  70. 3 6
      forge/src/main/java/me/shedaniel/architectury/registry/forge/RenderTypesImpl.java
  71. 5 10
      forge/src/main/java/me/shedaniel/architectury/registry/forge/ToolTypeImpl.java
  72. 2 4
      forge/src/main/java/me/shedaniel/architectury/utils/forge/GameInstanceImpl.java
  73. 6 0
      forge/src/main/resources/pack.mcmeta

+ 1 - 1
build.gradle

@@ -1,5 +1,5 @@
 plugins {
-    id "architect-plugin" version "1.0.10"
+    id "architect-plugin" version "1.1.11"
     id "org.cadixdev.licenser" version "0.5.0"
     id "com.jfrog.bintray" version "1.8.4"
     id "maven"

+ 1 - 1
common/src/main/java/me/shedaniel/architectury/Architectury.java

@@ -37,7 +37,7 @@ public class Architectury {
         String loader = null;
         for (Map.Entry<String, String> entry : MOD_LOADERS.entrySet()) {
             try {
-                Class.forName(entry.getKey());
+                Class.forName(entry.getKey(), false, Architectury.class.getClassLoader());
                 loader = entry.getValue();
                 break;
             } catch (ClassNotFoundException ignored) {}

+ 0 - 65
common/src/main/java/me/shedaniel/architectury/ArchitecturyPopulator.java

@@ -1,65 +0,0 @@
-/*
- * Copyright 2020 shedaniel
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package me.shedaniel.architectury;
-
-import org.apache.commons.lang3.reflect.FieldUtils;
-
-import java.lang.reflect.Field;
-import java.lang.reflect.Modifier;
-
-public final class ArchitecturyPopulator {
-    private ArchitecturyPopulator() {}
-    
-    public static void populate() {
-        try {
-            populate(Class.forName(Thread.currentThread().getStackTrace()[2].getClassName()));
-        } catch (Throwable e) {
-            throw new RuntimeException(e);
-        }
-    }
-    
-    public static void populate(Object o) {
-        try {
-            if (o instanceof Class) {
-                Class<?> aClass = (Class<?>) o;
-                for (Field field : aClass.getDeclaredFields()) {
-                    if (!field.isAnnotationPresent(Populatable.class)) continue;
-                    if (Modifier.isStatic(field.getModifiers())) {
-                        FieldUtils.removeFinalModifier(field);
-                        field.setAccessible(true);
-                        String type = field.getType().getName().replace("$", "");
-                        Class<?> newClass = Class.forName(type.substring(0, type.lastIndexOf('.')) + "." + Architectury.getModLoader() + "." + type.substring(type.lastIndexOf('.') + 1));
-                        field.set(null, newClass.getConstructor().newInstance());
-                    }
-                }
-            } else {
-                for (Field field : o.getClass().getDeclaredFields()) {
-                    if (!field.isAnnotationPresent(Populatable.class)) continue;
-                    if (!Modifier.isStatic(field.getModifiers())) {
-                        FieldUtils.removeFinalModifier(field);
-                        field.setAccessible(true);
-                        String type = field.getType().getName().replace("$", "");
-                        Class<?> newClass = Class.forName(type.substring(0, type.lastIndexOf('.')) + "." + Architectury.getModLoader() + "." + type.substring(type.lastIndexOf('.') + 1));
-                        field.set(o, newClass.getConstructor().newInstance());
-                    }
-                }
-            }
-        } catch (Throwable e) {
-            throw new RuntimeException(e);
-        }
-    }
-}

+ 3 - 3
common/src/main/java/me/shedaniel/architectury/Populatable.java → common/src/main/java/me/shedaniel/architectury/ExpectPlatform.java

@@ -22,6 +22,6 @@ import java.lang.annotation.RetentionPolicy;
 import java.lang.annotation.Target;
 
 @Retention(RetentionPolicy.RUNTIME)
-@Target(ElementType.FIELD)
-public @interface Populatable {
-}
+@Target(ElementType.METHOD)
+public @interface ExpectPlatform {
+}

+ 35 - 0
common/src/main/java/me/shedaniel/architectury/PlatformMethods.java

@@ -0,0 +1,35 @@
+/*
+ * Copyright 2020 shedaniel
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package me.shedaniel.architectury;
+
+import org.jetbrains.annotations.ApiStatus;
+
+import java.lang.invoke.CallSite;
+import java.lang.invoke.ConstantCallSite;
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.MethodType;
+
+@ApiStatus.Internal
+public class PlatformMethods {
+    public static CallSite platform(MethodHandles.Lookup lookup, String name, MethodType type)
+            throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException {
+        Class<?> lookupClass = lookup.lookupClass();
+        String lookupType = lookupClass.getName().replace("$", "") + "Impl";
+        Class<?> newClass = Class.forName(lookupType.substring(0, lookupType.lastIndexOf('.')) + "." + Architectury.getModLoader() + "." + lookupType.substring(lookupType.lastIndexOf('.') + 1), false, lookupClass.getClassLoader());
+        return new ConstantCallSite(lookup.findStatic(newClass, name, type));
+    }
+}

+ 17 - 17
common/src/main/java/me/shedaniel/architectury/event/EventHandler.java

@@ -16,8 +16,7 @@
 
 package me.shedaniel.architectury.event;
 
-import me.shedaniel.architectury.ArchitecturyPopulator;
-import me.shedaniel.architectury.Populatable;
+import me.shedaniel.architectury.ExpectPlatform;
 import me.shedaniel.architectury.platform.Platform;
 import net.fabricmc.api.EnvType;
 import net.fabricmc.api.Environment;
@@ -25,31 +24,32 @@ import net.fabricmc.api.Environment;
 public final class EventHandler {
     private EventHandler() {}
     
-    @Populatable
-    private static final Impl IMPL = null;
     private static boolean initialized = false;
     
     public static void init() {
         if (initialized) return;
         initialized = true;
         if (Platform.getEnv() == EnvType.CLIENT)
-            IMPL.registerClient();
-        IMPL.registerCommon();
+            registerClient();
+        registerCommon();
         if (Platform.getEnv() == EnvType.SERVER)
-            IMPL.registerServer();
+            registerServer();
     }
     
-    public interface Impl {
-        @Environment(EnvType.CLIENT)
-        void registerClient();
-        
-        void registerCommon();
-        
-        @Environment(EnvType.SERVER)
-        void registerServer();
+    @ExpectPlatform
+    @Environment(EnvType.CLIENT)
+    private static void registerClient() {
+        throw new AssertionError();
     }
     
-    static {
-        ArchitecturyPopulator.populate(EventHandler.class);
+    @ExpectPlatform
+    private static void registerCommon() {
+        throw new AssertionError();
+    }
+    
+    @ExpectPlatform
+    @Environment(EnvType.SERVER)
+    private static void registerServer() {
+        throw new AssertionError();
     }
 }

+ 3 - 14
common/src/main/java/me/shedaniel/architectury/hooks/DyeColorHooks.java

@@ -16,25 +16,14 @@
 
 package me.shedaniel.architectury.hooks;
 
-import me.shedaniel.architectury.ArchitecturyPopulator;
-import me.shedaniel.architectury.Populatable;
+import me.shedaniel.architectury.ExpectPlatform;
 import net.minecraft.world.item.DyeColor;
 
 public class DyeColorHooks {
     private DyeColorHooks() {}
     
-    @Populatable
-    private static final Impl IMPL = null;
-    
+    @ExpectPlatform
     public static int getColorValue(DyeColor color) {
-        return IMPL.getColorValue(color);
-    }
-    
-    public interface Impl {
-        int getColorValue(DyeColor color);
-    }
-    
-    static {
-        ArchitecturyPopulator.populate();
+        throw new AssertionError();
     }
 }

+ 3 - 14
common/src/main/java/me/shedaniel/architectury/hooks/EntityHooks.java

@@ -16,8 +16,7 @@
 
 package me.shedaniel.architectury.hooks;
 
-import me.shedaniel.architectury.ArchitecturyPopulator;
-import me.shedaniel.architectury.Populatable;
+import me.shedaniel.architectury.ExpectPlatform;
 import net.fabricmc.api.EnvType;
 import net.fabricmc.api.Environment;
 import net.minecraft.world.entity.Entity;
@@ -26,18 +25,8 @@ import net.minecraft.world.entity.Entity;
 public final class EntityHooks {
     private EntityHooks() {}
     
-    @Populatable
-    private static final Impl IMPL = null;
-    
+    @ExpectPlatform
     public static String getEncodeId(Entity entity) {
-        return IMPL.getEncodeId(entity);
-    }
-    
-    public interface Impl {
-        String getEncodeId(Entity entity);
-    }
-    
-    static {
-        ArchitecturyPopulator.populate(ItemEntityHooks.class);
+        throw new AssertionError();
     }
 }

+ 9 - 23
common/src/main/java/me/shedaniel/architectury/hooks/ExplosionHooks.java

@@ -16,8 +16,7 @@
 
 package me.shedaniel.architectury.hooks;
 
-import me.shedaniel.architectury.ArchitecturyPopulator;
-import me.shedaniel.architectury.Populatable;
+import me.shedaniel.architectury.ExpectPlatform;
 import net.fabricmc.api.EnvType;
 import net.fabricmc.api.Environment;
 import net.minecraft.world.entity.Entity;
@@ -29,37 +28,24 @@ import org.jetbrains.annotations.Nullable;
 public final class ExplosionHooks {
     private ExplosionHooks() {}
     
-    @Populatable
-    private static final Impl IMPL = null;
-    
+    @ExpectPlatform
     public static Vec3 getPosition(Explosion explosion) {
-        return IMPL.getPosition(explosion);
+        throw new AssertionError();
     }
     
     @Nullable
+    @ExpectPlatform
     public static Entity getSource(Explosion explosion) {
-        return IMPL.getSource(explosion);
+        throw new AssertionError();
     }
     
+    @ExpectPlatform
     public static float getRadius(Explosion explosion) {
-        return IMPL.getRadius(explosion);
+        throw new AssertionError();
     }
     
+    @ExpectPlatform
     public static void setRadius(Explosion explosion, float radius) {
-        IMPL.setRadius(explosion, radius);
-    }
-    
-    public interface Impl {
-        Vec3 getPosition(Explosion explosion);
-        
-        Entity getSource(Explosion explosion);
-        
-        float getRadius(Explosion explosion);
-        
-        void setRadius(Explosion explosion, float radius);
-    }
-    
-    static {
-        ArchitecturyPopulator.populate(ExplosionHooks.class);
+        throw new AssertionError();
     }
 }

+ 15 - 32
common/src/main/java/me/shedaniel/architectury/hooks/FluidStackHooks.java

@@ -16,8 +16,7 @@
 
 package me.shedaniel.architectury.hooks;
 
-import me.shedaniel.architectury.ArchitecturyPopulator;
-import me.shedaniel.architectury.Populatable;
+import me.shedaniel.architectury.ExpectPlatform;
 import me.shedaniel.architectury.fluid.FluidStack;
 import me.shedaniel.architectury.utils.Fraction;
 import net.minecraft.nbt.CompoundTag;
@@ -27,43 +26,46 @@ import net.minecraft.network.chat.Component;
 public class FluidStackHooks {
     private FluidStackHooks() {}
     
-    @Populatable
-    private static final Impl IMPL = null;
-    
+    @ExpectPlatform
     public static Component getName(FluidStack stack) {
-        return IMPL.getName(stack);
+        throw new AssertionError();
     }
     
+    @ExpectPlatform
     public static String getTranslationKey(FluidStack stack) {
-        return IMPL.getTranslationKey(stack);
+        throw new AssertionError();
     }
     
     /**
      * Platform-specific FluidStack read.
      */
+    @ExpectPlatform
     public static FluidStack read(FriendlyByteBuf buf) {
-        return IMPL.read(buf);
+        throw new AssertionError();
     }
     
     /**
      * Platform-specific FluidStack write.
      */
+    @ExpectPlatform
     public static void write(FluidStack stack, FriendlyByteBuf buf) {
-        IMPL.write(stack, buf);
+        throw new AssertionError();
     }
     
     /**
      * Platform-specific FluidStack read.
      */
+    @ExpectPlatform
     public static FluidStack read(CompoundTag tag) {
-        return IMPL.read(tag);
+        throw new AssertionError();
     }
     
     /**
      * Platform-specific FluidStack write.
      */
+    @ExpectPlatform
     public static CompoundTag write(FluidStack stack, CompoundTag tag) {
-        return IMPL.write(stack, tag);
+        throw new AssertionError();
     }
     
     /**
@@ -71,27 +73,8 @@ public class FluidStackHooks {
      * Forge: 1000
      * Fabric: 1
      */
+    @ExpectPlatform
     public static Fraction bucketAmount() {
-        return IMPL.bucketAmount();
-    }
-    
-    public interface Impl {
-        Fraction bucketAmount();
-        
-        Component getName(FluidStack stack);
-        
-        String getTranslationKey(FluidStack stack);
-        
-        FluidStack read(FriendlyByteBuf buf);
-        
-        void write(FluidStack stack, FriendlyByteBuf buf);
-        
-        FluidStack read(CompoundTag tag);
-        
-        CompoundTag write(FluidStack stack, CompoundTag tag);
-    }
-    
-    static {
-        ArchitecturyPopulator.populate();
+        throw new AssertionError();
     }
 }

+ 3 - 14
common/src/main/java/me/shedaniel/architectury/hooks/ItemEntityHooks.java

@@ -16,8 +16,7 @@
 
 package me.shedaniel.architectury.hooks;
 
-import me.shedaniel.architectury.ArchitecturyPopulator;
-import me.shedaniel.architectury.Populatable;
+import me.shedaniel.architectury.ExpectPlatform;
 import me.shedaniel.architectury.utils.IntValue;
 import net.fabricmc.api.EnvType;
 import net.fabricmc.api.Environment;
@@ -27,23 +26,13 @@ import net.minecraft.world.entity.item.ItemEntity;
 public final class ItemEntityHooks {
     private ItemEntityHooks() {}
     
-    @Populatable
-    private static final Impl IMPL = null;
-    
     /**
      * The lifespan of an {@link ItemEntity}.
      * Fabric: Since it doesn't have this, the value will be a readable-only value of 6000.
      * Forge: Value of lifespan of the forge hook.
      */
+    @ExpectPlatform
     public static IntValue lifespan(ItemEntity entity) {
-        return IMPL.lifespan(entity);
-    }
-    
-    public interface Impl {
-        IntValue lifespan(ItemEntity entity);
-    }
-    
-    static {
-        ArchitecturyPopulator.populate(ItemEntityHooks.class);
+        throw new AssertionError();
     }
 }

+ 3 - 14
common/src/main/java/me/shedaniel/architectury/hooks/PackRepositoryHooks.java

@@ -16,26 +16,15 @@
 
 package me.shedaniel.architectury.hooks;
 
-import me.shedaniel.architectury.ArchitecturyPopulator;
-import me.shedaniel.architectury.Populatable;
+import me.shedaniel.architectury.ExpectPlatform;
 import net.minecraft.server.packs.repository.PackRepository;
 import net.minecraft.server.packs.repository.RepositorySource;
 
 public class PackRepositoryHooks {
     private PackRepositoryHooks() {}
     
-    @Populatable
-    private static final Impl IMPL = null;
-    
+    @ExpectPlatform
     public static void addSource(PackRepository repository, RepositorySource source) {
-        IMPL.addSource(repository, source);
-    }
-    
-    public interface Impl {
-        void addSource(PackRepository repository, RepositorySource source);
-    }
-    
-    static {
-        ArchitecturyPopulator.populate();
+        throw new AssertionError();
     }
 }

+ 5 - 17
common/src/main/java/me/shedaniel/architectury/hooks/PlayerHooks.java

@@ -16,8 +16,7 @@
 
 package me.shedaniel.architectury.hooks;
 
-import me.shedaniel.architectury.ArchitecturyPopulator;
-import me.shedaniel.architectury.Populatable;
+import me.shedaniel.architectury.ExpectPlatform;
 import net.fabricmc.api.EnvType;
 import net.fabricmc.api.Environment;
 import net.minecraft.world.entity.player.Player;
@@ -26,24 +25,13 @@ import net.minecraft.world.entity.player.Player;
 public final class PlayerHooks {
     private PlayerHooks() {}
     
-    @Populatable
-    private static final Impl IMPL = null;
-    
+    @ExpectPlatform
     public static boolean isFake(Player player) {
-        return IMPL.isFake(player);
+        throw new AssertionError();
     }
     
+    @ExpectPlatform
     public static void closeContainer(Player player) {
-        IMPL.closeContainer(player);
-    }
-    
-    public interface Impl {
-        boolean isFake(Player player);
-        
-        void closeContainer(Player player);
-    }
-    
-    static {
-        ArchitecturyPopulator.populate(PlayerHooks.class);
+        throw new AssertionError();
     }
 }

+ 7 - 20
common/src/main/java/me/shedaniel/architectury/hooks/ScreenHooks.java

@@ -16,8 +16,7 @@
 
 package me.shedaniel.architectury.hooks;
 
-import me.shedaniel.architectury.ArchitecturyPopulator;
-import me.shedaniel.architectury.Populatable;
+import me.shedaniel.architectury.ExpectPlatform;
 import net.fabricmc.api.EnvType;
 import net.fabricmc.api.Environment;
 import net.minecraft.client.gui.components.AbstractWidget;
@@ -30,30 +29,18 @@ import java.util.List;
 public final class ScreenHooks {
     private ScreenHooks() {}
     
-    @Populatable
-    private static final Impl IMPL = null;
-    
+    @ExpectPlatform
     public static List<AbstractWidget> getButtons(Screen screen) {
-        return IMPL.getButtons(screen);
+        throw new AssertionError();
     }
     
+    @ExpectPlatform
     public static <T extends AbstractWidget> T addButton(Screen screen, T widget) {
-        return IMPL.addButton(screen, widget);
+        throw new AssertionError();
     }
     
+    @ExpectPlatform
     public static <T extends GuiEventListener> T addChild(Screen screen, T listener) {
-        return IMPL.addChild(screen, listener);
-    }
-    
-    public interface Impl {
-        List<AbstractWidget> getButtons(Screen screen);
-        
-        <T extends AbstractWidget> T addButton(Screen screen, T widget);
-        
-        <T extends GuiEventListener> T addChild(Screen screen, T listener);
-    }
-    
-    static {
-        ArchitecturyPopulator.populate(ScreenHooks.class);
+        throw new AssertionError();
     }
 }

+ 9 - 24
common/src/main/java/me/shedaniel/architectury/networking/NetworkManager.java

@@ -16,8 +16,7 @@
 
 package me.shedaniel.architectury.networking;
 
-import me.shedaniel.architectury.ArchitecturyPopulator;
-import me.shedaniel.architectury.Populatable;
+import me.shedaniel.architectury.ExpectPlatform;
 import net.fabricmc.api.EnvType;
 import net.fabricmc.api.Environment;
 import net.minecraft.client.Minecraft;
@@ -28,15 +27,14 @@ import net.minecraft.server.level.ServerPlayer;
 import net.minecraft.world.entity.player.Player;
 
 public final class NetworkManager {
-    @Populatable
-    private static final Impl IMPL = null;
-    
+    @ExpectPlatform
     public static void registerReceiver(Side side, ResourceLocation id, NetworkReceiver receiver) {
-        IMPL.registerReceiver(side, id, receiver);
+        throw new AssertionError();
     }
     
+    @ExpectPlatform
     public static Packet<?> toPacket(Side side, ResourceLocation id, FriendlyByteBuf buf) {
-        return IMPL.toPacket(side, id, buf);
+        throw new AssertionError();
     }
     
     public static void sendToPlayer(ServerPlayer player, ResourceLocation id, FriendlyByteBuf buf) {
@@ -56,23 +54,14 @@ public final class NetworkManager {
     }
     
     @Environment(EnvType.CLIENT)
+    @ExpectPlatform
     public static boolean canServerReceive(ResourceLocation id) {
-        return IMPL.canServerReceive(id);
+        throw new AssertionError();
     }
     
+    @ExpectPlatform
     public static boolean canPlayerReceive(ServerPlayer player, ResourceLocation id) {
-        return IMPL.canPlayerReceive(player, id);
-    }
-    
-    public interface Impl {
-        void registerReceiver(Side side, ResourceLocation id, NetworkReceiver receiver);
-        
-        Packet<?> toPacket(Side side, ResourceLocation id, FriendlyByteBuf buf);
-        
-        @Environment(EnvType.CLIENT)
-        boolean canServerReceive(ResourceLocation id);
-        
-        boolean canPlayerReceive(ServerPlayer player, ResourceLocation id);
+        throw new AssertionError();
     }
     
     @FunctionalInterface
@@ -108,8 +97,4 @@ public final class NetworkManager {
         S2C,
         C2S
     }
-    
-    static {
-        ArchitecturyPopulator.populate(NetworkManager.class);
-    }
 }

+ 18 - 38
common/src/main/java/me/shedaniel/architectury/platform/Platform.java

@@ -17,8 +17,7 @@
 package me.shedaniel.architectury.platform;
 
 import me.shedaniel.architectury.Architectury;
-import me.shedaniel.architectury.ArchitecturyPopulator;
-import me.shedaniel.architectury.Populatable;
+import me.shedaniel.architectury.ExpectPlatform;
 import net.fabricmc.api.EnvType;
 import net.minecraft.SharedConstants;
 import org.jetbrains.annotations.NotNull;
@@ -30,9 +29,6 @@ import java.util.Optional;
 public final class Platform {
     private Platform() {}
     
-    @Populatable
-    private static final Impl IMPL = null;
-    
     /**
      * @return the current mod loader, either "fabric" or "forge"
      */
@@ -47,73 +43,57 @@ public final class Platform {
     }
     
     @NotNull
+    @ExpectPlatform
     public static Path getGameFolder() {
-        return IMPL.getGameFolder();
+        throw new AssertionError();
     }
     
     @NotNull
+    @ExpectPlatform
     public static Path getConfigFolder() {
-        return IMPL.getConfigFolder();
+        throw new AssertionError();
     }
     
     @NotNull
+    @ExpectPlatform
     public static EnvType getEnv() {
-        return IMPL.getEnv();
+        throw new AssertionError();
     }
     
+    @ExpectPlatform
     public static boolean isModLoaded(String id) {
-        return IMPL.isModLoaded(id);
+        throw new AssertionError();
     }
     
     @NotNull
+    @ExpectPlatform
     public static Mod getMod(String id) {
-        return IMPL.getMod(id);
+        throw new AssertionError();
     }
     
     @NotNull
     public static Optional<Mod> getOptionalMod(String id) {
         try {
-            return Optional.of(IMPL.getMod(id));
+            return Optional.of(getMod(id));
         } catch (NullPointerException e) {
             return Optional.empty();
         }
     }
     
     @NotNull
+    @ExpectPlatform
     public static Collection<Mod> getMods() {
-        return IMPL.getMods();
+        throw new AssertionError();
     }
     
     @NotNull
+    @ExpectPlatform
     public static Collection<String> getModIds() {
-        return IMPL.getModIds();
+        throw new AssertionError();
     }
     
+    @ExpectPlatform
     public static boolean isDevelopmentEnvironment() {
-        return IMPL.isDevelopmentEnvironment();
-    }
-    
-    public interface Impl {
-        Path getGameFolder();
-        
-        Path getConfigFolder();
-        
-        Path getModsFolder();
-        
-        EnvType getEnv();
-        
-        boolean isModLoaded(String id);
-        
-        Mod getMod(String id);
-        
-        Collection<Mod> getMods();
-        
-        Collection<String> getModIds();
-        
-        boolean isDevelopmentEnvironment();
-    }
-    
-    static {
-        ArchitecturyPopulator.populate(Platform.class);
+        throw new AssertionError();
     }
 }

+ 3 - 14
common/src/main/java/me/shedaniel/architectury/registry/BlockEntityRenderers.java

@@ -16,8 +16,7 @@
 
 package me.shedaniel.architectury.registry;
 
-import me.shedaniel.architectury.ArchitecturyPopulator;
-import me.shedaniel.architectury.Populatable;
+import me.shedaniel.architectury.ExpectPlatform;
 import net.fabricmc.api.EnvType;
 import net.fabricmc.api.Environment;
 import net.minecraft.client.renderer.blockentity.BlockEntityRenderDispatcher;
@@ -31,18 +30,8 @@ import java.util.function.Function;
 public final class BlockEntityRenderers {
     private BlockEntityRenderers() {}
     
-    @Populatable
-    private static final Impl IMPL = null;
-    
+    @ExpectPlatform
     public static <T extends BlockEntity> void registerRenderer(BlockEntityType<T> type, Function<BlockEntityRenderDispatcher, BlockEntityRenderer<T>> provider) {
-        IMPL.registerRenderer(type, provider);
-    }
-    
-    public interface Impl {
-        <T extends BlockEntity> void registerRenderer(BlockEntityType<T> type, Function<BlockEntityRenderDispatcher, BlockEntityRenderer<T>> provider);
-    }
-    
-    static {
-        ArchitecturyPopulator.populate(BlockEntityRenderers.class);
+        throw new AssertionError();
     }
 }

+ 9 - 23
common/src/main/java/me/shedaniel/architectury/registry/BlockProperties.java

@@ -16,8 +16,7 @@
 
 package me.shedaniel.architectury.registry;
 
-import me.shedaniel.architectury.ArchitecturyPopulator;
-import me.shedaniel.architectury.Populatable;
+import me.shedaniel.architectury.ExpectPlatform;
 import net.minecraft.world.item.DyeColor;
 import net.minecraft.world.level.block.state.BlockBehaviour;
 import net.minecraft.world.level.block.state.BlockState;
@@ -27,9 +26,6 @@ import net.minecraft.world.level.material.MaterialColor;
 import java.util.function.Function;
 
 public abstract class BlockProperties extends BlockBehaviour.Properties implements BlockPropertiesExtension {
-    @Populatable
-    private static final Impl IMPL = null;
-    
     public BlockProperties(Material material, Function<BlockState, MaterialColor> function) {
         super(material, function);
     }
@@ -42,33 +38,23 @@ public abstract class BlockProperties extends BlockBehaviour.Properties implemen
         return of(material, color.getMaterialColor());
     }
     
+    @ExpectPlatform
     public static BlockProperties of(Material material, MaterialColor color) {
-        return IMPL.of(material, color);
+        throw new AssertionError();
     }
     
+    @ExpectPlatform
     public static BlockProperties of(Material material, Function<BlockState, MaterialColor> color) {
-        return IMPL.of(material, color);
+        throw new AssertionError();
     }
     
+    @ExpectPlatform
     public static BlockProperties copy(BlockBehaviour block) {
-        return IMPL.copy(block);
+        throw new AssertionError();
     }
     
+    @ExpectPlatform
     public static BlockProperties copy(BlockBehaviour.Properties properties) {
-        return IMPL.copy(properties);
-    }
-    
-    public interface Impl {
-        BlockProperties of(Material material, MaterialColor color);
-        
-        BlockProperties of(Material material, Function<BlockState, MaterialColor> color);
-        
-        BlockProperties copy(BlockBehaviour block);
-        
-        BlockProperties copy(BlockBehaviour.Properties properties);
-    }
-    
-    static {
-        ArchitecturyPopulator.populate();
+        throw new AssertionError();
     }
 }

+ 5 - 17
common/src/main/java/me/shedaniel/architectury/registry/ColorHandlers.java

@@ -16,8 +16,7 @@
 
 package me.shedaniel.architectury.registry;
 
-import me.shedaniel.architectury.ArchitecturyPopulator;
-import me.shedaniel.architectury.Populatable;
+import me.shedaniel.architectury.ExpectPlatform;
 import net.fabricmc.api.EnvType;
 import net.fabricmc.api.Environment;
 import net.minecraft.client.color.block.BlockColor;
@@ -29,24 +28,13 @@ import net.minecraft.world.level.block.Block;
 public final class ColorHandlers {
     private ColorHandlers() {}
     
-    @Populatable
-    private static final Impl IMPL = null;
-    
+    @ExpectPlatform
     public static void registerItemColors(ItemColor color, ItemLike... items) {
-        IMPL.registerItemColors(color, items);
+        throw new AssertionError();
     }
     
+    @ExpectPlatform
     public static void registerBlockColors(BlockColor color, Block... blocks) {
-        IMPL.registerBlockColors(color, blocks);
-    }
-    
-    public interface Impl {
-        void registerItemColors(ItemColor color, ItemLike... items);
-        
-        void registerBlockColors(BlockColor color, Block... blocks);
-    }
-    
-    static {
-        ArchitecturyPopulator.populate(ColorHandlers.class);
+        throw new AssertionError();
     }
 }

+ 3 - 14
common/src/main/java/me/shedaniel/architectury/registry/CreativeTabs.java

@@ -16,8 +16,7 @@
 
 package me.shedaniel.architectury.registry;
 
-import me.shedaniel.architectury.ArchitecturyPopulator;
-import me.shedaniel.architectury.Populatable;
+import me.shedaniel.architectury.ExpectPlatform;
 import net.minecraft.resources.ResourceLocation;
 import net.minecraft.world.item.CreativeModeTab;
 import net.minecraft.world.item.ItemStack;
@@ -27,19 +26,9 @@ import java.util.function.Supplier;
 public final class CreativeTabs {
     public CreativeTabs() {}
     
-    @Populatable
-    private static final Impl IMPL = null;
-    
     // I am sorry, fabric wants a resource location instead of the translation key for whatever reason
+    @ExpectPlatform
     public static CreativeModeTab create(ResourceLocation name, Supplier<ItemStack> icon) {
-        return IMPL.create(name, icon);
-    }
-    
-    public interface Impl {
-        CreativeModeTab create(ResourceLocation name, Supplier<ItemStack> icon);
-    }
-    
-    static {
-        ArchitecturyPopulator.populate(CreativeTabs.class);
+        throw new AssertionError();
     }
 }

+ 3 - 14
common/src/main/java/me/shedaniel/architectury/registry/KeyBindings.java

@@ -16,8 +16,7 @@
 
 package me.shedaniel.architectury.registry;
 
-import me.shedaniel.architectury.ArchitecturyPopulator;
-import me.shedaniel.architectury.Populatable;
+import me.shedaniel.architectury.ExpectPlatform;
 import net.fabricmc.api.EnvType;
 import net.fabricmc.api.Environment;
 import net.minecraft.client.KeyMapping;
@@ -26,18 +25,8 @@ import net.minecraft.client.KeyMapping;
 public final class KeyBindings {
     private KeyBindings() {}
     
-    @Populatable
-    private static final Impl IMPL = null;
-    
+    @ExpectPlatform
     public static void registerKeyBinding(KeyMapping binding) {
-        IMPL.registerKeyBinding(binding);
-    }
-    
-    public interface Impl {
-        void registerKeyBinding(KeyMapping binding);
-    }
-    
-    static {
-        ArchitecturyPopulator.populate(KeyBindings.class);
+        throw new AssertionError();
     }
 }

+ 10 - 18
common/src/main/java/me/shedaniel/architectury/registry/Registries.java

@@ -16,8 +16,7 @@
 
 package me.shedaniel.architectury.registry;
 
-import me.shedaniel.architectury.ArchitecturyPopulator;
-import me.shedaniel.architectury.Populatable;
+import me.shedaniel.architectury.ExpectPlatform;
 import net.minecraft.resources.ResourceKey;
 import net.minecraft.resources.ResourceLocation;
 import org.jetbrains.annotations.Nullable;
@@ -26,8 +25,6 @@ import java.util.HashMap;
 import java.util.Map;
 
 public final class Registries {
-    @Populatable
-    private static final Impl IMPL = null;
     private static final Map<String, Registries> REGISTRIES = new HashMap<>();
     private final RegistryProvider provider;
     
@@ -36,7 +33,7 @@ public final class Registries {
     }
     
     private Registries(String modId) {
-        this.provider = IMPL.get(modId);
+        this.provider = _get(modId);
     }
     
     public <T> Registry<T> get(ResourceKey<net.minecraft.core.Registry<T>> key) {
@@ -53,8 +50,9 @@ public final class Registries {
      * Fabric: Use registry
      */
     @Nullable
+    @ExpectPlatform
     public static <T> ResourceLocation getId(T object, @Nullable ResourceKey<net.minecraft.core.Registry<T>> fallback) {
-        return IMPL.getId(object, fallback);
+        throw new AssertionError();
     }
     
     /**
@@ -63,8 +61,9 @@ public final class Registries {
      */
     @Nullable
     @Deprecated
+    @ExpectPlatform
     public static <T> ResourceLocation getId(T object, @Nullable net.minecraft.core.Registry<T> fallback) {
-        return IMPL.getId(object, fallback);
+        throw new AssertionError();
     }
     
     /**
@@ -74,15 +73,12 @@ public final class Registries {
     @Deprecated
     @Nullable
     public static <T> ResourceLocation getRegistryName(T object) {
-        return IMPL.getId(object, (ResourceKey<net.minecraft.core.Registry<T>>) null);
+        return getId(object, (ResourceKey<net.minecraft.core.Registry<T>>) null);
     }
     
-    public interface Impl {
-        RegistryProvider get(String modId);
-        
-        <T> ResourceLocation getId(T object, ResourceKey<net.minecraft.core.Registry<T>> fallback);
-        
-        <T> ResourceLocation getId(T object, net.minecraft.core.Registry<T> fallback);
+    @ExpectPlatform
+    private static RegistryProvider _get(String modId) {
+        throw new AssertionError();
     }
     
     public interface RegistryProvider {
@@ -91,8 +87,4 @@ public final class Registries {
         @Deprecated
         <T> Registry<T> get(net.minecraft.core.Registry<T> registry);
     }
-    
-    static {
-        ArchitecturyPopulator.populate(Registries.class);
-    }
 }

+ 3 - 14
common/src/main/java/me/shedaniel/architectury/registry/ReloadListeners.java

@@ -16,26 +16,15 @@
 
 package me.shedaniel.architectury.registry;
 
-import me.shedaniel.architectury.ArchitecturyPopulator;
-import me.shedaniel.architectury.Populatable;
+import me.shedaniel.architectury.ExpectPlatform;
 import net.minecraft.server.packs.PackType;
 import net.minecraft.server.packs.resources.PreparableReloadListener;
 
 public final class ReloadListeners {
     private ReloadListeners() {}
     
-    @Populatable
-    private static final Impl IMPL = null;
-    
+    @ExpectPlatform
     public static void registerReloadListener(PackType type, PreparableReloadListener listener) {
-        IMPL.registerReloadListener(type, listener);
-    }
-    
-    public interface Impl {
-        void registerReloadListener(PackType type, PreparableReloadListener listener);
-    }
-    
-    static {
-        ArchitecturyPopulator.populate(ReloadListeners.class);
+        throw new AssertionError();
     }
 }

+ 5 - 16
common/src/main/java/me/shedaniel/architectury/registry/RenderTypes.java

@@ -16,8 +16,7 @@
 
 package me.shedaniel.architectury.registry;
 
-import me.shedaniel.architectury.ArchitecturyPopulator;
-import me.shedaniel.architectury.Populatable;
+import me.shedaniel.architectury.ExpectPlatform;
 import net.fabricmc.api.EnvType;
 import net.fabricmc.api.Environment;
 import net.minecraft.client.renderer.RenderType;
@@ -28,25 +27,15 @@ import net.minecraft.world.level.material.Fluid;
 public final class RenderTypes {
     private RenderTypes() {}
     
-    @Populatable
-    private static final Impl IMPL = null;
-    
+    @ExpectPlatform
     public static void register(RenderType type, Block... blocks) {
-        IMPL.register(type, blocks);
+        throw new AssertionError();
     }
     
+    @ExpectPlatform
     public static void register(RenderType type, Fluid... fluids) {
-        IMPL.register(type, fluids);
-    }
-    
-    public interface Impl {
-        void register(RenderType type, Block... blocks);
-        
-        void register(RenderType type, Fluid... fluids);
+        throw new AssertionError();
     }
     
-    static {
-        ArchitecturyPopulator.populate(RenderTypes.class);
-    }
 }
 

+ 9 - 17
common/src/main/java/me/shedaniel/architectury/registry/ToolType.java

@@ -17,7 +17,7 @@
 package me.shedaniel.architectury.registry;
 
 import com.google.common.collect.Maps;
-import me.shedaniel.architectury.Populatable;
+import me.shedaniel.architectury.ExpectPlatform;
 import net.minecraft.tags.Tag;
 import net.minecraft.world.item.Item;
 
@@ -29,23 +29,25 @@ public final class ToolType {
     public static final ToolType AXE = create("axe", ToolType::axeTag);
     public static final ToolType HOE = create("hoe", ToolType::hoeTag);
     public static final ToolType SHOVEL = create("shovel", ToolType::shovelTag);
-    @Populatable
-    private static final Impl IMPL = null;
     
+    @ExpectPlatform
     private static Tag<Item> pickaxeTag() {
-        return IMPL.pickaxeTag();
+        throw new AssertionError();
     }
     
+    @ExpectPlatform
     private static Tag<Item> axeTag() {
-        return IMPL.axeTag();
+        throw new AssertionError();
     }
     
+    @ExpectPlatform
     private static Tag<Item> hoeTag() {
-        return IMPL.hoeTag();
+        throw new AssertionError();
     }
     
+    @ExpectPlatform
     private static Tag<Item> shovelTag() {
-        return IMPL.shovelTag();
+        throw new AssertionError();
     }
     
     private static final Map<String, ToolType> TYPES = Maps.newConcurrentMap();
@@ -65,14 +67,4 @@ public final class ToolType {
     public static ToolType byName(String forgeName) {
         return TYPES.get(forgeName);
     }
-    
-    public interface Impl {
-        Tag<Item> pickaxeTag();
-        
-        Tag<Item> axeTag();
-        
-        Tag<Item> hoeTag();
-        
-        Tag<Item> shovelTag();
-    }
 }

+ 3 - 15
common/src/main/java/me/shedaniel/architectury/utils/GameInstance.java

@@ -16,32 +16,20 @@
 
 package me.shedaniel.architectury.utils;
 
-import me.shedaniel.architectury.ArchitecturyPopulator;
-import me.shedaniel.architectury.Populatable;
+import me.shedaniel.architectury.ExpectPlatform;
 import net.fabricmc.api.EnvType;
 import net.fabricmc.api.Environment;
 import net.minecraft.client.Minecraft;
 import net.minecraft.server.MinecraftServer;
 
 public final class GameInstance {
-    @Populatable
-    private static final Impl IMPL = null;
-    
     @Environment(EnvType.CLIENT)
     public static Minecraft getClient() {
         return Minecraft.getInstance();
     }
     
-    @Environment(EnvType.SERVER)
+    @ExpectPlatform
     public static MinecraftServer getServer() {
-        return IMPL.getServer();
-    }
-    
-    public interface Impl {
-        MinecraftServer getServer();
-    }
-    
-    static {
-        ArchitecturyPopulator.populate(GameInstance.class);
+        throw new AssertionError();
     }
 }

+ 5 - 2
fabric/build.gradle

@@ -20,10 +20,13 @@ dependencies {
     implementation "net.jodah:typetools:0.6.2"
     shadow "net.jodah:typetools:0.6.2"
 
-    compile(project(":common")) {
+    compileOnly(project(path: ":common", configuration: "transformed")) {
         transitive = false
     }
-    shadow(project(":common")) {
+    runtimeOnly(project(path: ":common", configuration: "transformed")) {
+        transitive = false
+    }
+    shadow(project(path: ":common", configuration: "transformed")) {
         transitive = false
     }
 }

+ 4 - 8
fabric/src/main/java/me/shedaniel/architectury/event/fabric/EventHandlerImpl.java

@@ -16,7 +16,6 @@
 
 package me.shedaniel.architectury.event.fabric;
 
-import me.shedaniel.architectury.event.EventHandler;
 import me.shedaniel.architectury.event.events.*;
 import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientLifecycleEvents;
 import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents;
@@ -31,9 +30,8 @@ import net.fabricmc.fabric.api.event.player.UseBlockCallback;
 import net.fabricmc.fabric.api.event.player.UseItemCallback;
 import net.minecraft.commands.Commands;
 
-public class EventHandlerImpl implements EventHandler.Impl {
-    @Override
-    public void registerClient() {
+public class EventHandlerImpl {
+    public static void registerClient() {
         ClientLifecycleEvents.CLIENT_STARTED.register(LifecycleEvent.CLIENT_STARTED.invoker()::stateChanged);
         ClientLifecycleEvents.CLIENT_STOPPING.register(LifecycleEvent.CLIENT_STOPPING.invoker()::stateChanged);
         
@@ -46,8 +44,7 @@ public class EventHandlerImpl implements EventHandler.Impl {
         HudRenderCallback.EVENT.register(GuiEvent.RENDER_HUD.invoker()::renderHud);
     }
     
-    @Override
-    public void registerCommon() {
+    public static void registerCommon() {
         ServerLifecycleEvents.SERVER_STARTING.register(LifecycleEvent.SERVER_STARTING.invoker()::stateChanged);
         ServerLifecycleEvents.SERVER_STARTED.register(LifecycleEvent.SERVER_STARTED.invoker()::stateChanged);
         ServerLifecycleEvents.SERVER_STOPPING.register(LifecycleEvent.SERVER_STOPPING.invoker()::stateChanged);
@@ -68,8 +65,7 @@ public class EventHandlerImpl implements EventHandler.Impl {
         AttackBlockCallback.EVENT.register((player, world, hand, pos, face) -> InteractionEvent.LEFT_CLICK_BLOCK.invoker().click(player, hand, pos, face));
     }
     
-    @Override
-    public void registerServer() {
+    public static void registerServer() {
         
     }
 }

+ 2 - 4
fabric/src/main/java/me/shedaniel/architectury/hooks/fabric/DyeColorHooksImpl.java

@@ -16,12 +16,10 @@
 
 package me.shedaniel.architectury.hooks.fabric;
 
-import me.shedaniel.architectury.hooks.DyeColorHooks;
 import net.minecraft.world.item.DyeColor;
 
-public class DyeColorHooksImpl implements DyeColorHooks.Impl {
-    @Override
-    public int getColorValue(DyeColor color) {
+public class DyeColorHooksImpl {
+    public static int getColorValue(DyeColor color) {
         return color.textureDiffuseColor;
     }
 }

+ 2 - 4
fabric/src/main/java/me/shedaniel/architectury/hooks/fabric/EntityHooksImpl.java

@@ -16,12 +16,10 @@
 
 package me.shedaniel.architectury.hooks.fabric;
 
-import me.shedaniel.architectury.hooks.EntityHooks;
 import net.minecraft.world.entity.Entity;
 
-public class EntityHooksImpl implements EntityHooks.Impl {
-    @Override
-    public String getEncodeId(Entity entity) {
+public class EntityHooksImpl {
+    public static String getEncodeId(Entity entity) {
         return entity.getEncodeId();
     }
 }

+ 5 - 10
fabric/src/main/java/me/shedaniel/architectury/hooks/fabric/ExplosionHooksImpl.java

@@ -16,29 +16,24 @@
 
 package me.shedaniel.architectury.hooks.fabric;
 
-import me.shedaniel.architectury.hooks.ExplosionHooks;
 import net.minecraft.world.entity.Entity;
 import net.minecraft.world.level.Explosion;
 import net.minecraft.world.phys.Vec3;
 
-public class ExplosionHooksImpl implements ExplosionHooks.Impl {
-    @Override
-    public Vec3 getPosition(Explosion explosion) {
+public class ExplosionHooksImpl {
+    public static Vec3 getPosition(Explosion explosion) {
         return ((ExplosionExtensions) explosion).architectury_getPosition();
     }
     
-    @Override
-    public Entity getSource(Explosion explosion) {
+    public static Entity getSource(Explosion explosion) {
         return ((ExplosionExtensions) explosion).architectury_getSource();
     }
     
-    @Override
-    public float getRadius(Explosion explosion) {
+    public static float getRadius(Explosion explosion) {
         return ((ExplosionExtensions) explosion).architectury_getRadius();
     }
     
-    @Override
-    public void setRadius(Explosion explosion, float radius) {
+    public static void setRadius(Explosion explosion, float radius) {
         ((ExplosionExtensions) explosion).architectury_setRadius(radius);
     }
     

+ 2 - 4
fabric/src/main/java/me/shedaniel/architectury/hooks/fabric/ItemEntityHooksImpl.java

@@ -16,13 +16,11 @@
 
 package me.shedaniel.architectury.hooks.fabric;
 
-import me.shedaniel.architectury.hooks.ItemEntityHooks;
 import me.shedaniel.architectury.utils.IntValue;
 import net.minecraft.world.entity.item.ItemEntity;
 
-public class ItemEntityHooksImpl implements ItemEntityHooks.Impl {
-    @Override
-    public IntValue lifespan(ItemEntity entity) {
+public class ItemEntityHooksImpl {
+    public static IntValue lifespan(ItemEntity entity) {
         return new IntValue() {
             @Override
             public void accept(int value) {

+ 2 - 4
fabric/src/main/java/me/shedaniel/architectury/hooks/fabric/PackRepositoryHooksImpl.java

@@ -17,16 +17,14 @@
 package me.shedaniel.architectury.hooks.fabric;
 
 import com.google.common.collect.ImmutableSet;
-import me.shedaniel.architectury.hooks.PackRepositoryHooks;
 import net.minecraft.server.packs.repository.PackRepository;
 import net.minecraft.server.packs.repository.RepositorySource;
 
 import java.util.ArrayList;
 import java.util.List;
 
-public class PackRepositoryHooksImpl implements PackRepositoryHooks.Impl {
-    @Override
-    public void addSource(PackRepository repository, RepositorySource source) {
+public class PackRepositoryHooksImpl {
+    public static void addSource(PackRepository repository, RepositorySource source) {
         List<RepositorySource> set = new ArrayList<>(repository.sources);
         set.add(source);
         repository.sources = ImmutableSet.copyOf(set);

+ 3 - 6
fabric/src/main/java/me/shedaniel/architectury/hooks/fabric/PlayerHooksImpl.java

@@ -16,17 +16,14 @@
 
 package me.shedaniel.architectury.hooks.fabric;
 
-import me.shedaniel.architectury.hooks.PlayerHooks;
 import net.minecraft.world.entity.player.Player;
 
-public class PlayerHooksImpl implements PlayerHooks.Impl {
-    @Override
-    public boolean isFake(Player player) {
+public class PlayerHooksImpl {
+    public static boolean isFake(Player player) {
         return false;
     }
     
-    @Override
-    public void closeContainer(Player player) {
+    public static void closeContainer(Player player) {
         player.closeContainer();
     }
 }

+ 4 - 8
fabric/src/main/java/me/shedaniel/architectury/hooks/fabric/ScreenHooksImpl.java

@@ -16,7 +16,6 @@
 
 package me.shedaniel.architectury.hooks.fabric;
 
-import me.shedaniel.architectury.hooks.ScreenHooks;
 import net.fabricmc.api.EnvType;
 import net.fabricmc.api.Environment;
 import net.minecraft.client.gui.components.AbstractWidget;
@@ -26,19 +25,16 @@ import net.minecraft.client.gui.screens.Screen;
 import java.util.List;
 
 @Environment(EnvType.CLIENT)
-public class ScreenHooksImpl implements ScreenHooks.Impl {
-    @Override
-    public List<AbstractWidget> getButtons(Screen screen) {
+public class ScreenHooksImpl {
+    public static List<AbstractWidget> getButtons(Screen screen) {
         return screen.buttons;
     }
     
-    @Override
-    public <T extends AbstractWidget> T addButton(Screen screen, T widget) {
+    public static <T extends AbstractWidget> T addButton(Screen screen, T widget) {
         return screen.addButton(widget);
     }
     
-    @Override
-    public <T extends GuiEventListener> T addChild(Screen screen, T listener) {
+    public static <T extends GuiEventListener> T addChild(Screen screen, T listener) {
         return screen.addWidget(listener);
     }
 }

+ 10 - 14
fabric/src/main/java/me/shedaniel/architectury/networking/fabric/NetworkManagerImpl.java

@@ -29,9 +29,8 @@ import net.minecraft.resources.ResourceLocation;
 import net.minecraft.server.level.ServerPlayer;
 import net.minecraft.world.entity.player.Player;
 
-public class NetworkManagerImpl implements NetworkManager.Impl {
-    @Override
-    public void registerReceiver(NetworkManager.Side side, ResourceLocation id, NetworkReceiver receiver) {
+public class NetworkManagerImpl {
+    public static void registerReceiver(NetworkManager.Side side, ResourceLocation id, NetworkReceiver receiver) {
         if (side == NetworkManager.Side.C2S) {
             registerC2SReceiver(id, receiver);
         } else if (side == NetworkManager.Side.S2C) {
@@ -39,16 +38,16 @@ public class NetworkManagerImpl implements NetworkManager.Impl {
         }
     }
     
-    private void registerC2SReceiver(ResourceLocation id, NetworkReceiver receiver) {
+    private static void registerC2SReceiver(ResourceLocation id, NetworkReceiver receiver) {
         ServerSidePacketRegistry.INSTANCE.register(id, (packetContext, buf) -> receiver.receive(buf, to(packetContext)));
     }
     
     @Environment(EnvType.CLIENT)
-    private void registerS2CReceiver(ResourceLocation id, NetworkReceiver receiver) {
+    private static void registerS2CReceiver(ResourceLocation id, NetworkReceiver receiver) {
         ClientSidePacketRegistry.INSTANCE.register(id, (packetContext, buf) -> receiver.receive(buf, to(packetContext)));
     }
     
-    private NetworkManager.PacketContext to(PacketContext context) {
+    private static NetworkManager.PacketContext to(PacketContext context) {
         return new NetworkManager.PacketContext() {
             @Override
             public Player getPlayer() {
@@ -67,8 +66,7 @@ public class NetworkManagerImpl implements NetworkManager.Impl {
         };
     }
     
-    @Override
-    public Packet<?> toPacket(NetworkManager.Side side, ResourceLocation id, FriendlyByteBuf buf) {
+    public static Packet<?> toPacket(NetworkManager.Side side, ResourceLocation id, FriendlyByteBuf buf) {
         if (side == NetworkManager.Side.C2S) {
             return toC2SPacket(id, buf);
         } else if (side == NetworkManager.Side.S2C) {
@@ -78,22 +76,20 @@ public class NetworkManagerImpl implements NetworkManager.Impl {
         throw new IllegalArgumentException("Invalid side: " + side);
     }
     
-    @Override
-    public boolean canServerReceive(ResourceLocation id) {
+    public static boolean canServerReceive(ResourceLocation id) {
         return ClientSidePacketRegistry.INSTANCE.canServerReceive(id);
     }
     
-    @Override
-    public boolean canPlayerReceive(ServerPlayer player, ResourceLocation id) {
+    public static boolean canPlayerReceive(ServerPlayer player, ResourceLocation id) {
         return ServerSidePacketRegistry.INSTANCE.canPlayerReceive(player, id);
     }
     
     @Environment(EnvType.CLIENT)
-    private Packet<?> toC2SPacket(ResourceLocation id, FriendlyByteBuf buf) {
+    private static Packet<?> toC2SPacket(ResourceLocation id, FriendlyByteBuf buf) {
         return ClientSidePacketRegistry.INSTANCE.toPacket(id, buf);
     }
     
-    private Packet<?> toS2CPacket(ResourceLocation id, FriendlyByteBuf buf) {
+    private static Packet<?> toS2CPacket(ResourceLocation id, FriendlyByteBuf buf) {
         return ServerSidePacketRegistry.INSTANCE.toPacket(id, buf);
     }
 }

+ 13 - 23
fabric/src/main/java/me/shedaniel/architectury/platform/fabric/PlatformImpl.java

@@ -17,7 +17,6 @@
 package me.shedaniel.architectury.platform.fabric;
 
 import me.shedaniel.architectury.platform.Mod;
-import me.shedaniel.architectury.platform.Platform;
 import net.fabricmc.api.EnvType;
 import net.fabricmc.loader.api.FabricLoader;
 import net.fabricmc.loader.api.ModContainer;
@@ -30,55 +29,46 @@ import java.util.HashMap;
 import java.util.Map;
 import java.util.stream.Collectors;
 
-public class PlatformImpl implements Platform.Impl {
+public class PlatformImpl {
     public static final Map<String, Mod.ConfigurationScreenProvider> CONFIG_SCREENS = new HashMap<>();
-    private final Map<String, Mod> mods = new HashMap<>();
+    private static final Map<String, Mod> mods = new HashMap<>();
     
-    @Override
-    public Path getGameFolder() {
+    public static Path getGameFolder() {
         return FabricLoader.getInstance().getGameDir();
     }
     
-    @Override
-    public Path getConfigFolder() {
+    public static Path getConfigFolder() {
         return FabricLoader.getInstance().getConfigDir();
     }
     
-    @Override
-    public Path getModsFolder() {
+    public static Path getModsFolder() {
         return getGameFolder().resolve("mods");
     }
     
-    @Override
-    public EnvType getEnv() {
+    public static EnvType getEnv() {
         return FabricLoader.getInstance().getEnvironmentType();
     }
     
-    @Override
-    public boolean isModLoaded(String id) {
+    public static boolean isModLoaded(String id) {
         return FabricLoader.getInstance().isModLoaded(id);
     }
     
-    @Override
-    public Mod getMod(String id) {
-        return this.mods.computeIfAbsent(id, ModImpl::new);
+    public static Mod getMod(String id) {
+        return mods.computeIfAbsent(id, ModImpl::new);
     }
     
-    @Override
-    public Collection<Mod> getMods() {
+    public static Collection<Mod> getMods() {
         for (ModContainer mod : FabricLoader.getInstance().getAllMods()) {
             getMod(mod.getMetadata().getId());
         }
-        return this.mods.values();
+        return mods.values();
     }
     
-    @Override
-    public Collection<String> getModIds() {
+    public static Collection<String> getModIds() {
         return FabricLoader.getInstance().getAllMods().stream().map(ModContainer::getMetadata).map(ModMetadata::getId).collect(Collectors.toList());
     }
     
-    @Override
-    public boolean isDevelopmentEnvironment() {
+    public static boolean isDevelopmentEnvironment() {
         return FabricLoader.getInstance().isDevelopmentEnvironment();
     }
     

+ 2 - 4
fabric/src/main/java/me/shedaniel/architectury/registry/fabric/BlockEntityRenderersImpl.java

@@ -16,7 +16,6 @@
 
 package me.shedaniel.architectury.registry.fabric;
 
-import me.shedaniel.architectury.registry.BlockEntityRenderers;
 import net.fabricmc.fabric.api.client.rendereregistry.v1.BlockEntityRendererRegistry;
 import net.minecraft.client.renderer.blockentity.BlockEntityRenderDispatcher;
 import net.minecraft.client.renderer.blockentity.BlockEntityRenderer;
@@ -25,9 +24,8 @@ import net.minecraft.world.level.block.entity.BlockEntityType;
 
 import java.util.function.Function;
 
-public class BlockEntityRenderersImpl implements BlockEntityRenderers.Impl {
-    @Override
-    public <T extends BlockEntity> void registerRenderer(BlockEntityType<T> type, Function<BlockEntityRenderDispatcher, BlockEntityRenderer<T>> provider) {
+public class BlockEntityRenderersImpl {
+    public static <T extends BlockEntity> void registerRenderer(BlockEntityType<T> type, Function<BlockEntityRenderDispatcher, BlockEntityRenderer<T>> provider) {
         BlockEntityRendererRegistry.INSTANCE.register(type, provider);
     }
 }

+ 6 - 10
fabric/src/main/java/me/shedaniel/architectury/registry/fabric/BlockPropertiesImpl.java

@@ -27,24 +27,20 @@ import net.minecraft.world.level.material.MaterialColor;
 
 import java.util.function.Function;
 
-public class BlockPropertiesImpl implements BlockProperties.Impl {
-    @Override
-    public BlockProperties of(Material material, MaterialColor color) {
+public class BlockPropertiesImpl {
+    public static BlockProperties of(Material material, MaterialColor color) {
         return new Impl(material, (state) -> color);
     }
     
-    @Override
-    public BlockProperties of(Material material, Function<BlockState, MaterialColor> color) {
+    public static BlockProperties of(Material material, Function<BlockState, MaterialColor> color) {
         return new Impl(material, color);
     }
     
-    @Override
-    public BlockProperties copy(BlockBehaviour old) {
+    public static BlockProperties copy(BlockBehaviour old) {
         return copy(old.properties);
     }
     
-    @Override
-    public BlockProperties copy(BlockBehaviour.Properties old) {
+    public static BlockProperties copy(BlockBehaviour.Properties old) {
         BlockProperties properties = of(old.material, old.materialColor);
         properties.material = old.material;
         properties.destroyTime = old.destroyTime;
@@ -63,7 +59,7 @@ public class BlockPropertiesImpl implements BlockProperties.Impl {
         BlockSettingsInternals otherInternals = (BlockSettingsInternals) old;
         FabricBlockInternals.ExtraData extraData = otherInternals.getExtraData();
         if (extraData != null) {
-            ((BlockSettingsInternals) this).setExtraData(extraData);
+            ((BlockSettingsInternals) properties).setExtraData(extraData);
         }
         return properties;
     }

+ 3 - 6
fabric/src/main/java/me/shedaniel/architectury/registry/fabric/ColorHandlersImpl.java

@@ -16,21 +16,18 @@
 
 package me.shedaniel.architectury.registry.fabric;
 
-import me.shedaniel.architectury.registry.ColorHandlers;
 import net.fabricmc.fabric.api.client.rendering.v1.ColorProviderRegistry;
 import net.minecraft.client.color.block.BlockColor;
 import net.minecraft.client.color.item.ItemColor;
 import net.minecraft.world.level.ItemLike;
 import net.minecraft.world.level.block.Block;
 
-public class ColorHandlersImpl implements ColorHandlers.Impl {
-    @Override
-    public void registerItemColors(ItemColor color, ItemLike... items) {
+public class ColorHandlersImpl {
+    public static void registerItemColors(ItemColor color, ItemLike... items) {
         ColorProviderRegistry.ITEM.register(color, items);
     }
     
-    @Override
-    public void registerBlockColors(BlockColor color, Block... blocks) {
+    public static void registerBlockColors(BlockColor color, Block... blocks) {
         ColorProviderRegistry.BLOCK.register(color, blocks);
     }
 }

+ 2 - 4
fabric/src/main/java/me/shedaniel/architectury/registry/fabric/CreativeTabsImpl.java

@@ -16,7 +16,6 @@
 
 package me.shedaniel.architectury.registry.fabric;
 
-import me.shedaniel.architectury.registry.CreativeTabs;
 import net.fabricmc.fabric.api.client.itemgroup.FabricItemGroupBuilder;
 import net.minecraft.resources.ResourceLocation;
 import net.minecraft.world.item.CreativeModeTab;
@@ -24,9 +23,8 @@ import net.minecraft.world.item.ItemStack;
 
 import java.util.function.Supplier;
 
-public class CreativeTabsImpl implements CreativeTabs.Impl {
-    @Override
-    public CreativeModeTab create(ResourceLocation name, Supplier<ItemStack> icon) {
+public class CreativeTabsImpl {
+    public static CreativeModeTab create(ResourceLocation name, Supplier<ItemStack> icon) {
         return FabricItemGroupBuilder.build(name, icon);
     }
 }

+ 2 - 4
fabric/src/main/java/me/shedaniel/architectury/registry/fabric/KeyBindingsImpl.java

@@ -16,13 +16,11 @@
 
 package me.shedaniel.architectury.registry.fabric;
 
-import me.shedaniel.architectury.registry.KeyBindings;
 import net.fabricmc.fabric.api.client.keybinding.v1.KeyBindingHelper;
 import net.minecraft.client.KeyMapping;
 
-public class KeyBindingsImpl implements KeyBindings.Impl {
-    @Override
-    public void registerKeyBinding(KeyMapping binding) {
+public class KeyBindingsImpl {
+    public static void registerKeyBinding(KeyMapping binding) {
         KeyBindingHelper.registerKeyBinding(binding);
     }
 }

+ 4 - 7
fabric/src/main/java/me/shedaniel/architectury/registry/fabric/RegistriesImpl.java

@@ -30,21 +30,18 @@ import java.util.Optional;
 import java.util.Set;
 import java.util.function.Supplier;
 
-public class RegistriesImpl implements Registries.Impl {
-    @Override
-    public Registries.RegistryProvider get(String modId) {
+public class RegistriesImpl {
+    public static Registries.RegistryProvider _get(String modId) {
         return RegistryProviderImpl.INSTANCE;
     }
     
-    @Override
-    public <T> ResourceLocation getId(T object, ResourceKey<net.minecraft.core.Registry<T>> fallback) {
+    public static <T> ResourceLocation getId(T object, ResourceKey<net.minecraft.core.Registry<T>> fallback) {
         if (fallback == null)
             return null;
         return RegistryProviderImpl.INSTANCE.get(fallback).getId(object);
     }
     
-    @Override
-    public <T> ResourceLocation getId(T object, net.minecraft.core.Registry<T> fallback) {
+    public static <T> ResourceLocation getId(T object, net.minecraft.core.Registry<T> fallback) {
         if (fallback == null)
             return null;
         return RegistryProviderImpl.INSTANCE.get(fallback).getId(object);

+ 4 - 6
fabric/src/main/java/me/shedaniel/architectury/registry/fabric/ReloadListenersImpl.java

@@ -17,7 +17,6 @@
 package me.shedaniel.architectury.registry.fabric;
 
 import com.google.common.primitives.Longs;
-import me.shedaniel.architectury.registry.ReloadListeners;
 import net.fabricmc.fabric.api.resource.IdentifiableResourceReloadListener;
 import net.fabricmc.fabric.api.resource.ResourceManagerHelper;
 import net.minecraft.resources.ResourceLocation;
@@ -31,11 +30,10 @@ import java.security.SecureRandom;
 import java.util.concurrent.CompletableFuture;
 import java.util.concurrent.Executor;
 
-public class ReloadListenersImpl implements ReloadListeners.Impl {
+public class ReloadListenersImpl {
     private static final SecureRandom RANDOM = new SecureRandom();
     
-    @Override
-    public void registerReloadListener(PackType type, PreparableReloadListener listener) {
+    public static void registerReloadListener(PackType type, PreparableReloadListener listener) {
         byte[] bytes = new byte[8];
         RANDOM.nextBytes(bytes);
         ResourceLocation id = new ResourceLocation("architectury:reload_" + StringUtils.leftPad(Math.abs(Longs.fromByteArray(bytes)) + "", 19));
@@ -44,12 +42,12 @@ public class ReloadListenersImpl implements ReloadListeners.Impl {
             public ResourceLocation getFabricId() {
                 return id;
             }
-    
+            
             @Override
             public String getName() {
                 return listener.getName();
             }
-    
+            
             @Override
             public CompletableFuture<Void> reload(PreparationBarrier preparationBarrier, ResourceManager resourceManager, ProfilerFiller profilerFiller, ProfilerFiller profilerFiller2, Executor executor, Executor executor2) {
                 return listener.reload(preparationBarrier, resourceManager, profilerFiller, profilerFiller2, executor, executor2);

+ 3 - 6
fabric/src/main/java/me/shedaniel/architectury/registry/fabric/RenderTypesImpl.java

@@ -16,20 +16,17 @@
 
 package me.shedaniel.architectury.registry.fabric;
 
-import me.shedaniel.architectury.registry.RenderTypes;
 import net.fabricmc.fabric.api.blockrenderlayer.v1.BlockRenderLayerMap;
 import net.minecraft.client.renderer.RenderType;
 import net.minecraft.world.level.block.Block;
 import net.minecraft.world.level.material.Fluid;
 
-public class RenderTypesImpl implements RenderTypes.Impl {
-    @Override
-    public void register(RenderType type, Block... blocks) {
+public class RenderTypesImpl {
+    public static void register(RenderType type, Block... blocks) {
         BlockRenderLayerMap.INSTANCE.putBlocks(type, blocks);
     }
     
-    @Override
-    public void register(RenderType type, Fluid... fluids) {
+    public static void register(RenderType type, Fluid... fluids) {
         BlockRenderLayerMap.INSTANCE.putFluids(type, fluids);
     }
 }

+ 5 - 10
fabric/src/main/java/me/shedaniel/architectury/registry/fabric/ToolTypeImpl.java

@@ -16,29 +16,24 @@
 
 package me.shedaniel.architectury.registry.fabric;
 
-import me.shedaniel.architectury.registry.ToolType;
 import net.fabricmc.fabric.api.tool.attribute.v1.FabricToolTags;
 import net.minecraft.tags.Tag;
 import net.minecraft.world.item.Item;
 
-public class ToolTypeImpl implements ToolType.Impl {
-    @Override
-    public Tag<Item> pickaxeTag() {
+public class ToolTypeImpl {
+    public static Tag<Item> pickaxeTag() {
         return FabricToolTags.PICKAXES;
     }
     
-    @Override
-    public Tag<Item> axeTag() {
+    public static Tag<Item> axeTag() {
         return FabricToolTags.AXES;
     }
     
-    @Override
-    public Tag<Item> hoeTag() {
+    public static Tag<Item> hoeTag() {
         return FabricToolTags.HOES;
     }
     
-    @Override
-    public Tag<Item> shovelTag() {
+    public static Tag<Item> shovelTag() {
         return FabricToolTags.SHOVELS;
     }
 }

+ 2 - 4
fabric/src/main/java/me/shedaniel/architectury/utils/fabric/GameInstanceImpl.java

@@ -19,17 +19,15 @@ package me.shedaniel.architectury.utils.fabric;
 import me.shedaniel.architectury.event.EventHandler;
 import me.shedaniel.architectury.event.events.LifecycleEvent;
 import me.shedaniel.architectury.platform.Platform;
-import me.shedaniel.architectury.utils.GameInstance;
 import net.fabricmc.api.EnvType;
 import net.fabricmc.api.Environment;
 import net.minecraft.client.Minecraft;
 import net.minecraft.server.MinecraftServer;
 
-public class GameInstanceImpl implements GameInstance.Impl {
+public class GameInstanceImpl {
     private static MinecraftServer server = null;
     
-    @Override
-    public MinecraftServer getServer() {
+    public static MinecraftServer getServer() {
         MinecraftServer server = null;
         if (GameInstanceImpl.server != null) server = GameInstanceImpl.server;
         if (Platform.getEnv() == EnvType.CLIENT) {

+ 10 - 400
forge/src/main/java/me/shedaniel/architectury/event/forge/EventHandlerImpl.java

@@ -16,417 +16,27 @@
 
 package me.shedaniel.architectury.event.forge;
 
-import me.shedaniel.architectury.event.EventHandler;
-import me.shedaniel.architectury.event.events.PlayerEvent;
-import me.shedaniel.architectury.event.events.TextureStitchEvent;
-import me.shedaniel.architectury.event.events.*;
 import me.shedaniel.architectury.forge.ArchitecturyForge;
 import me.shedaniel.architectury.platform.forge.EventBuses;
-import net.minecraft.client.Minecraft;
-import net.minecraft.client.gui.IGuiEventListener;
-import net.minecraft.client.world.ClientWorld;
-import net.minecraft.entity.player.ServerPlayerEntity;
-import net.minecraft.item.ItemStack;
-import net.minecraft.util.ActionResult;
-import net.minecraft.util.ActionResultType;
-import net.minecraft.util.text.ITextComponent;
-import net.minecraft.world.server.ServerWorld;
 import net.minecraftforge.api.distmarker.Dist;
 import net.minecraftforge.api.distmarker.OnlyIn;
-import net.minecraftforge.client.event.*;
 import net.minecraftforge.common.MinecraftForge;
-import net.minecraftforge.event.CommandEvent;
-import net.minecraftforge.event.RegisterCommandsEvent;
-import net.minecraftforge.event.ServerChatEvent;
-import net.minecraftforge.event.TickEvent.*;
-import net.minecraftforge.event.entity.EntityJoinWorldEvent;
-import net.minecraftforge.event.entity.item.ItemTossEvent;
-import net.minecraftforge.event.entity.living.LivingAttackEvent;
-import net.minecraftforge.event.entity.living.LivingDeathEvent;
-import net.minecraftforge.event.entity.player.*;
-import net.minecraftforge.event.entity.player.PlayerEvent.*;
-import net.minecraftforge.event.world.ExplosionEvent.Detonate;
-import net.minecraftforge.event.world.ExplosionEvent.Start;
-import net.minecraftforge.event.world.WorldEvent;
-import net.minecraftforge.eventbus.api.Event;
-import net.minecraftforge.eventbus.api.SubscribeEvent;
-import net.minecraftforge.fml.LogicalSide;
-import net.minecraftforge.fml.event.server.FMLServerStartedEvent;
-import net.minecraftforge.fml.event.server.FMLServerStartingEvent;
-import net.minecraftforge.fml.event.server.FMLServerStoppedEvent;
-import net.minecraftforge.fml.event.server.FMLServerStoppingEvent;
-import net.minecraftforge.fml.server.ServerLifecycleHooks;
 
-import java.util.List;
-
-public class EventHandlerImpl implements EventHandler.Impl {
-    @Override
-    public void registerClient() {
-        MinecraftForge.EVENT_BUS.register(Client.class);
-        EventBuses.getModEventBus(ArchitecturyForge.MOD_ID).orElseThrow(() -> new IllegalStateException("Where is architectury?")).register(ModBasedEventHandlerImpl.Client.class);
-    }
-    
-    @Override
-    public void registerCommon() {
-        MinecraftForge.EVENT_BUS.register(Common.class);
-        EventBuses.getModEventBus(ArchitecturyForge.MOD_ID).orElseThrow(() -> new IllegalStateException("Where is architectury?")).register(ModBasedEventHandlerImpl.Common.class);
-    }
-    
-    @Override
-    public void registerServer() {
-        MinecraftForge.EVENT_BUS.register(Server.class);
-        EventBuses.getModEventBus(ArchitecturyForge.MOD_ID).orElseThrow(() -> new IllegalStateException("Where is architectury?")).register(ModBasedEventHandlerImpl.Server.class);
-    }
-    
+public class EventHandlerImpl {
     @OnlyIn(Dist.CLIENT)
-    public static class Client {
-        @SubscribeEvent
-        public static void event(ItemTooltipEvent event) {
-            TooltipEvent.ITEM.invoker().append(event.getItemStack(), event.getToolTip(), event.getFlags());
-        }
-        
-        @SubscribeEvent
-        public static void event(ClientTickEvent event) {
-            if (event.phase == Phase.START)
-                TickEvent.CLIENT_PRE.invoker().tick(Minecraft.getInstance());
-            else if (event.phase == Phase.END)
-                TickEvent.CLIENT_POST.invoker().tick(Minecraft.getInstance());
-        }
-        
-        @SubscribeEvent
-        public static void event(RenderGameOverlayEvent.Post event) {
-            if (event.getType() == RenderGameOverlayEvent.ElementType.ALL)
-                GuiEvent.RENDER_HUD.invoker().renderHud(event.getMatrixStack(), event.getPartialTicks());
-        }
-        
-        @SubscribeEvent
-        public static void event(ClientPlayerNetworkEvent.LoggedInEvent event) {
-            PlayerEvent.CLIENT_PLAYER_JOIN.invoker().join(event.getPlayer());
-        }
-        
-        @SubscribeEvent
-        public static void event(ClientPlayerNetworkEvent.LoggedOutEvent event) {
-            PlayerEvent.CLIENT_PLAYER_QUIT.invoker().quit(event.getPlayer());
-        }
-        
-        @SubscribeEvent
-        public static void event(ClientPlayerNetworkEvent.RespawnEvent event) {
-            PlayerEvent.CLIENT_PLAYER_RESPAWN.invoker().respawn(event.getOldPlayer(), event.getNewPlayer());
-        }
-        
-        @SubscribeEvent
-        public static void event(GuiScreenEvent.InitGuiEvent.Pre event) {
-            if (GuiEvent.INIT_PRE.invoker().init(event.getGui(), event.getWidgetList(), (List<IGuiEventListener>) event.getGui().children()) == ActionResultType.FAIL) {
-                event.setCanceled(true);
-            }
-        }
-        
-        @SubscribeEvent
-        public static void event(GuiScreenEvent.InitGuiEvent.Post event) {
-            GuiEvent.INIT_POST.invoker().init(event.getGui(), event.getWidgetList(), (List<IGuiEventListener>) event.getGui().children());
-        }
-        
-        @SubscribeEvent
-        public static void event(RenderGameOverlayEvent.Text event) {
-            GuiEvent.DEBUG_TEXT_LEFT.invoker().gatherText(event.getLeft());
-            GuiEvent.DEBUG_TEXT_RIGHT.invoker().gatherText(event.getRight());
-        }
-        
-        @SubscribeEvent
-        public static void event(ClientChatEvent event) {
-            ActionResult<String> process = ChatEvent.CLIENT.invoker().process(event.getMessage());
-            if (process.getObject() != null)
-                event.setMessage(process.getObject());
-            if (process.getResult() == ActionResultType.FAIL)
-                event.setCanceled(true);
-        }
-        
-        @SubscribeEvent
-        public static void event(ClientChatReceivedEvent event) {
-            ActionResult<ITextComponent> process = ChatEvent.CLIENT_RECEIVED.invoker().process(event.getType(), event.getMessage(), event.getSenderUUID());
-            if (process.getObject() != null)
-                event.setMessage(process.getObject());
-            if (process.getResult() == ActionResultType.FAIL)
-                event.setCanceled(true);
-        }
-        
-        @SubscribeEvent
-        public static void event(WorldEvent.Save event) {
-            if (event.getWorld() instanceof ClientWorld) {
-                ClientWorld world = (ClientWorld) event.getWorld();
-                LifecycleEvent.CLIENT_WORLD_LOAD.invoker().act(world);
-            }
-        }
-        
-        @SubscribeEvent
-        public static void event(GuiScreenEvent.DrawScreenEvent.Pre event) {
-            if (GuiEvent.RENDER_PRE.invoker().render(event.getGui(), event.getMatrixStack(), event.getMouseX(), event.getMouseY(), event.getRenderPartialTicks()) == ActionResultType.FAIL) {
-                event.setCanceled(true);
-            }
-        }
-        
-        @SubscribeEvent
-        public static void event(GuiScreenEvent.DrawScreenEvent.Post event) {
-            GuiEvent.RENDER_POST.invoker().render(event.getGui(), event.getMatrixStack(), event.getMouseX(), event.getMouseY(), event.getRenderPartialTicks());
-        }
-        
-        @SubscribeEvent
-        public static void event(PlayerInteractEvent.RightClickEmpty event) {
-            InteractionEvent.CLIENT_RIGHT_CLICK_AIR.invoker().click(event.getPlayer(), event.getHand());
-        }
-        
-        @SubscribeEvent
-        public static void event(PlayerInteractEvent.LeftClickEmpty event) {
-            InteractionEvent.CLIENT_LEFT_CLICK_AIR.invoker().click(event.getPlayer(), event.getHand());
-        }
-        
-        @SubscribeEvent
-        public static void event(net.minecraftforge.client.event.TextureStitchEvent.Pre event) {
-            TextureStitchEvent.PRE.invoker().stitch(event.getMap(), event::addSprite);
-        }
-        
-        @SubscribeEvent
-        public static void event(net.minecraftforge.client.event.TextureStitchEvent.Post event) {
-            TextureStitchEvent.POST.invoker().stitch(event.getMap());
-        }
+    public static void registerClient() {
+        MinecraftForge.EVENT_BUS.register(EventHandlerImplClient.class);
+        EventBuses.getModEventBus(ArchitecturyForge.MOD_ID).orElseThrow(() -> new IllegalStateException("Where is architectury?")).register(EventHandlerImplClient.ModBasedEventHandler.class);
     }
     
-    public static class Common {
-        @SubscribeEvent
-        public static void event(ServerTickEvent event) {
-            if (event.phase == Phase.START)
-                TickEvent.SERVER_PRE.invoker().tick(ServerLifecycleHooks.getCurrentServer());
-            else if (event.phase == Phase.END)
-                TickEvent.SERVER_POST.invoker().tick(ServerLifecycleHooks.getCurrentServer());
-        }
-        
-        @SubscribeEvent
-        public static void event(WorldTickEvent event) {
-            if (event.side == LogicalSide.SERVER) {
-                if (event.phase == Phase.START)
-                    TickEvent.SERVER_WORLD_PRE.invoker().tick((ServerWorld) event.world);
-                else if (event.phase == Phase.END)
-                    TickEvent.SERVER_WORLD_POST.invoker().tick((ServerWorld) event.world);
-            }
-        }
-        
-        @SubscribeEvent
-        public static void event(FMLServerStartingEvent event) {
-            LifecycleEvent.SERVER_STARTING.invoker().stateChanged(event.getServer());
-        }
-        
-        @SubscribeEvent
-        public static void event(FMLServerStartedEvent event) {
-            LifecycleEvent.SERVER_STARTED.invoker().stateChanged(event.getServer());
-        }
-        
-        @SubscribeEvent
-        public static void event(FMLServerStoppingEvent event) {
-            LifecycleEvent.SERVER_STOPPING.invoker().stateChanged(event.getServer());
-        }
-        
-        @SubscribeEvent
-        public static void event(FMLServerStoppedEvent event) {
-            LifecycleEvent.SERVER_STOPPED.invoker().stateChanged(event.getServer());
-        }
-        
-        @SubscribeEvent
-        public static void event(RegisterCommandsEvent event) {
-            CommandRegistrationEvent.EVENT.invoker().register(event.getDispatcher(), event.getEnvironment());
-        }
-        
-        @SubscribeEvent
-        public static void event(PlayerLoggedInEvent event) {
-            PlayerEvent.PLAYER_JOIN.invoker().join((ServerPlayerEntity) event.getPlayer());
-        }
-        
-        @SubscribeEvent
-        public static void event(PlayerLoggedOutEvent event) {
-            PlayerEvent.PLAYER_QUIT.invoker().quit((ServerPlayerEntity) event.getPlayer());
-        }
-        
-        @SubscribeEvent
-        public static void event(PlayerRespawnEvent event) {
-            PlayerEvent.PLAYER_RESPAWN.invoker().respawn((ServerPlayerEntity) event.getPlayer(), event.isEndConquered());
-        }
-        
-        @SubscribeEvent
-        public static void event(CommandEvent event) {
-            CommandPerformEvent performEvent = new CommandPerformEvent(event.getParseResults(), event.getException());
-            if (CommandPerformEvent.EVENT.invoker().act(performEvent) == ActionResultType.FAIL) {
-                event.setCanceled(true);
-            }
-            event.setParseResults(performEvent.getResults());
-            event.setException(performEvent.getThrowable());
-        }
-        
-        @SubscribeEvent
-        public static void event(PlayerTickEvent event) {
-            if (event.phase == Phase.START) {
-                TickEvent.PLAYER_PRE.invoker().tick(event.player);
-            } else if (event.phase == Phase.END) {
-                TickEvent.PLAYER_POST.invoker().tick(event.player);
-            }
-        }
-        
-        @SubscribeEvent
-        public static void event(ServerChatEvent event) {
-            ActionResult<ITextComponent> process = ChatEvent.SERVER.invoker().process(event.getPlayer(), event.getMessage(), event.getComponent());
-            if (process.getObject() != null)
-                event.setComponent(process.getObject());
-            if (process.getResult() == ActionResultType.FAIL)
-                event.setCanceled(true);
-        }
-        
-        @SubscribeEvent
-        public static void event(WorldEvent.Load event) {
-            if (event.getWorld() instanceof ServerWorld) {
-                ServerWorld world = (ServerWorld) event.getWorld();
-                LifecycleEvent.SERVER_WORLD_LOAD.invoker().act(world);
-            }
-        }
-        
-        @SubscribeEvent
-        public static void event(WorldEvent.Unload event) {
-            if (event.getWorld() instanceof ServerWorld) {
-                ServerWorld world = (ServerWorld) event.getWorld();
-                LifecycleEvent.SERVER_WORLD_UNLOAD.invoker().act(world);
-            }
-        }
-        
-        @SubscribeEvent
-        public static void event(WorldEvent.Save event) {
-            if (event.getWorld() instanceof ServerWorld) {
-                ServerWorld world = (ServerWorld) event.getWorld();
-                LifecycleEvent.SERVER_WORLD_SAVE.invoker().act(world);
-            }
-        }
-        
-        @SubscribeEvent
-        public static void event(LivingDeathEvent event) {
-            if (EntityEvent.LIVING_DEATH.invoker().die(event.getEntityLiving(), event.getSource()) == ActionResultType.FAIL) {
-                event.setCanceled(true);
-            }
-        }
-        
-        @SubscribeEvent
-        public static void event(AdvancementEvent event) {
-            if (event.getPlayer() instanceof ServerPlayerEntity) {
-                PlayerEvent.PLAYER_ADVANCEMENT.invoker().award((ServerPlayerEntity) event.getPlayer(), event.getAdvancement());
-            }
-        }
-        
-        @SubscribeEvent
-        public static void event(Clone event) {
-            if (event.getOriginal() instanceof ServerPlayerEntity && event.getPlayer() instanceof ServerPlayerEntity) {
-                PlayerEvent.PLAYER_CLONE.invoker().clone((ServerPlayerEntity) event.getOriginal(), (ServerPlayerEntity) event.getPlayer(), !event.isWasDeath());
-            }
-        }
-        
-        @SubscribeEvent
-        public static void event(Start event) {
-            if (ExplosionEvent.PRE.invoker().explode(event.getWorld(), event.getExplosion()) == ActionResultType.FAIL) {
-                event.setCanceled(true);
-            }
-        }
-        
-        @SubscribeEvent
-        public static void event(Detonate event) {
-            ExplosionEvent.DETONATE.invoker().explode(event.getWorld(), event.getExplosion(), event.getAffectedEntities());
-        }
-        
-        @SubscribeEvent
-        public static void event(LivingAttackEvent event) {
-            if (EntityEvent.LIVING_ATTACK.invoker().attack(event.getEntityLiving(), event.getSource(), event.getAmount()) == ActionResultType.FAIL) {
-                event.setCanceled(true);
-            }
-        }
-        
-        @SubscribeEvent
-        public static void event(EntityJoinWorldEvent event) {
-            if (EntityEvent.ADD.invoker().add(event.getEntity(), event.getWorld()) == ActionResultType.FAIL) {
-                event.setCanceled(true);
-            }
-        }
-        
-        @SubscribeEvent
-        public static void event(ItemCraftedEvent event) {
-            PlayerEvent.CRAFT_ITEM.invoker().craft(event.getPlayer(), event.getCrafting(), event.getInventory());
-        }
-        
-        @SubscribeEvent
-        public static void event(ItemSmeltedEvent event) {
-            PlayerEvent.SMELT_ITEM.invoker().smelt(event.getPlayer(), event.getSmelting());
-        }
-        
-        @SubscribeEvent
-        public static void event(EntityItemPickupEvent event) {
-            PlayerEvent.PICKUP_ITEM_PRE.invoker().canPickup(event.getPlayer(), event.getItem(), event.getItem().getItem());
-        }
-        
-        @SubscribeEvent
-        public static void event(ItemPickupEvent event) {
-            PlayerEvent.PICKUP_ITEM_POST.invoker().pickup(event.getPlayer(), event.getOriginalEntity(), event.getStack());
-        }
-        
-        @SubscribeEvent
-        public static void event(ItemTossEvent event) {
-            PlayerEvent.DROP_ITEM.invoker().drop(event.getPlayer(), event.getEntityItem());
-        }
-        
-        @SubscribeEvent
-        public static void event(PlayerContainerEvent.Open event) {
-            PlayerEvent.OPEN_MENU.invoker().open(event.getPlayer(), event.getContainer());
-        }
-        
-        @SubscribeEvent
-        public static void event(PlayerContainerEvent.Close event) {
-            PlayerEvent.CLOSE_MENU.invoker().close(event.getPlayer(), event.getContainer());
-        }
-        
-        @SubscribeEvent
-        public static void event(PlayerInteractEvent.RightClickItem event) {
-            ActionResult<ItemStack> result = InteractionEvent.RIGHT_CLICK_ITEM.invoker().click(event.getPlayer(), event.getHand());
-            if (result.getResult() != ActionResultType.PASS) {
-                event.setCanceled(true);
-                event.setCancellationResult(result.getResult());
-            }
-        }
-        
-        @SubscribeEvent
-        public static void event(PlayerInteractEvent.RightClickBlock event) {
-            ActionResultType result = InteractionEvent.RIGHT_CLICK_BLOCK.invoker().click(event.getPlayer(), event.getHand(), event.getPos(), event.getFace());
-            if (result != ActionResultType.PASS) {
-                event.setCanceled(true);
-                event.setCancellationResult(result);
-                event.setUseBlock(Event.Result.DENY);
-                event.setUseItem(Event.Result.DENY);
-            }
-        }
-        
-        @SubscribeEvent
-        public static void event(PlayerInteractEvent.EntityInteract event) {
-            ActionResultType result = InteractionEvent.INTERACT_ENTITY.invoker().interact(event.getPlayer(), event.getTarget(), event.getHand());
-            if (result != ActionResultType.PASS) {
-                event.setCanceled(true);
-                event.setCancellationResult(result);
-            }
-        }
-        
-        @SubscribeEvent
-        public static void event(PlayerInteractEvent.LeftClickBlock event) {
-            ActionResultType result = InteractionEvent.LEFT_CLICK_BLOCK.invoker().click(event.getPlayer(), event.getHand(), event.getPos(), event.getFace());
-            if (result != ActionResultType.PASS) {
-                event.setCanceled(true);
-                event.setCancellationResult(result);
-                event.setUseBlock(Event.Result.DENY);
-                event.setUseItem(Event.Result.DENY);
-            }
-        }
+    public static void registerCommon() {
+        MinecraftForge.EVENT_BUS.register(EventHandlerImplCommon.class);
+        EventBuses.getModEventBus(ArchitecturyForge.MOD_ID).orElseThrow(() -> new IllegalStateException("Where is architectury?")).register(EventHandlerImplCommon.ModBasedEventHandler.class);
     }
     
     @OnlyIn(Dist.DEDICATED_SERVER)
-    public static class Server {
-        
+    public static void registerServer() {
+        MinecraftForge.EVENT_BUS.register(EventHandlerImplServer.class);
+        EventBuses.getModEventBus(ArchitecturyForge.MOD_ID).orElseThrow(() -> new IllegalStateException("Where is architectury?")).register(EventHandlerImplServer.ModBasedEventHandler.class);
     }
 }

+ 136 - 0
forge/src/main/java/me/shedaniel/architectury/event/forge/EventHandlerImplClient.java

@@ -0,0 +1,136 @@
+package me.shedaniel.architectury.event.forge;
+
+import me.shedaniel.architectury.event.events.TextureStitchEvent;
+import me.shedaniel.architectury.event.events.*;
+import net.minecraft.client.Minecraft;
+import net.minecraft.client.gui.IGuiEventListener;
+import net.minecraft.client.world.ClientWorld;
+import net.minecraft.util.ActionResult;
+import net.minecraft.util.ActionResultType;
+import net.minecraft.util.text.ITextComponent;
+import net.minecraftforge.api.distmarker.Dist;
+import net.minecraftforge.api.distmarker.OnlyIn;
+import net.minecraftforge.client.event.*;
+import net.minecraftforge.event.TickEvent.ClientTickEvent;
+import net.minecraftforge.event.entity.player.ItemTooltipEvent;
+import net.minecraftforge.event.entity.player.PlayerInteractEvent;
+import net.minecraftforge.event.world.WorldEvent;
+import net.minecraftforge.eventbus.api.SubscribeEvent;
+
+import java.util.List;
+
+@OnlyIn(Dist.CLIENT)
+public class EventHandlerImplClient {
+    @SubscribeEvent
+    public static void event(ItemTooltipEvent event) {
+        TooltipEvent.ITEM.invoker().append(event.getItemStack(), event.getToolTip(), event.getFlags());
+    }
+    
+    @SubscribeEvent
+    public static void event(ClientTickEvent event) {
+        if (event.phase == net.minecraftforge.event.TickEvent.Phase.START)
+            TickEvent.CLIENT_PRE.invoker().tick(Minecraft.getInstance());
+        else if (event.phase == net.minecraftforge.event.TickEvent.Phase.END)
+            TickEvent.CLIENT_POST.invoker().tick(Minecraft.getInstance());
+    }
+    
+    @SubscribeEvent
+    public static void event(RenderGameOverlayEvent.Post event) {
+        if (event.getType() == RenderGameOverlayEvent.ElementType.ALL)
+            GuiEvent.RENDER_HUD.invoker().renderHud(event.getMatrixStack(), event.getPartialTicks());
+    }
+    
+    @SubscribeEvent
+    public static void event(ClientPlayerNetworkEvent.LoggedInEvent event) {
+        PlayerEvent.CLIENT_PLAYER_JOIN.invoker().join(event.getPlayer());
+    }
+    
+    @SubscribeEvent
+    public static void event(ClientPlayerNetworkEvent.LoggedOutEvent event) {
+        PlayerEvent.CLIENT_PLAYER_QUIT.invoker().quit(event.getPlayer());
+    }
+    
+    @SubscribeEvent
+    public static void event(ClientPlayerNetworkEvent.RespawnEvent event) {
+        PlayerEvent.CLIENT_PLAYER_RESPAWN.invoker().respawn(event.getOldPlayer(), event.getNewPlayer());
+    }
+    
+    @SubscribeEvent
+    public static void event(GuiScreenEvent.InitGuiEvent.Pre event) {
+        if (GuiEvent.INIT_PRE.invoker().init(event.getGui(), event.getWidgetList(), (List<IGuiEventListener>) event.getGui().children()) == ActionResultType.FAIL) {
+            event.setCanceled(true);
+        }
+    }
+    
+    @SubscribeEvent
+    public static void event(GuiScreenEvent.InitGuiEvent.Post event) {
+        GuiEvent.INIT_POST.invoker().init(event.getGui(), event.getWidgetList(), (List<IGuiEventListener>) event.getGui().children());
+    }
+    
+    @SubscribeEvent
+    public static void event(RenderGameOverlayEvent.Text event) {
+        GuiEvent.DEBUG_TEXT_LEFT.invoker().gatherText(event.getLeft());
+        GuiEvent.DEBUG_TEXT_RIGHT.invoker().gatherText(event.getRight());
+    }
+    
+    @SubscribeEvent
+    public static void event(ClientChatEvent event) {
+        ActionResult<String> process = ChatEvent.CLIENT.invoker().process(event.getMessage());
+        if (process.getObject() != null)
+            event.setMessage(process.getObject());
+        if (process.getResult() == ActionResultType.FAIL)
+            event.setCanceled(true);
+    }
+    
+    @SubscribeEvent
+    public static void event(ClientChatReceivedEvent event) {
+        ActionResult<ITextComponent> process = ChatEvent.CLIENT_RECEIVED.invoker().process(event.getType(), event.getMessage(), event.getSenderUUID());
+        if (process.getObject() != null)
+            event.setMessage(process.getObject());
+        if (process.getResult() == ActionResultType.FAIL)
+            event.setCanceled(true);
+    }
+    
+    @SubscribeEvent
+    public static void event(WorldEvent.Save event) {
+        if (event.getWorld() instanceof ClientWorld) {
+            ClientWorld world = (ClientWorld) event.getWorld();
+            LifecycleEvent.CLIENT_WORLD_LOAD.invoker().act(world);
+        }
+    }
+    
+    @SubscribeEvent
+    public static void event(GuiScreenEvent.DrawScreenEvent.Pre event) {
+        if (GuiEvent.RENDER_PRE.invoker().render(event.getGui(), event.getMatrixStack(), event.getMouseX(), event.getMouseY(), event.getRenderPartialTicks()) == ActionResultType.FAIL) {
+            event.setCanceled(true);
+        }
+    }
+    
+    @SubscribeEvent
+    public static void event(GuiScreenEvent.DrawScreenEvent.Post event) {
+        GuiEvent.RENDER_POST.invoker().render(event.getGui(), event.getMatrixStack(), event.getMouseX(), event.getMouseY(), event.getRenderPartialTicks());
+    }
+    
+    @SubscribeEvent
+    public static void event(PlayerInteractEvent.RightClickEmpty event) {
+        InteractionEvent.CLIENT_RIGHT_CLICK_AIR.invoker().click(event.getPlayer(), event.getHand());
+    }
+    
+    @SubscribeEvent
+    public static void event(PlayerInteractEvent.LeftClickEmpty event) {
+        InteractionEvent.CLIENT_LEFT_CLICK_AIR.invoker().click(event.getPlayer(), event.getHand());
+    }
+    
+    @OnlyIn(Dist.CLIENT)
+    public static class ModBasedEventHandler {
+        @SubscribeEvent
+        public static void event(net.minecraftforge.client.event.TextureStitchEvent.Pre event) {
+            TextureStitchEvent.PRE.invoker().stitch(event.getMap(), event::addSprite);
+        }
+        
+        @SubscribeEvent
+        public static void event(net.minecraftforge.client.event.TextureStitchEvent.Post event) {
+            TextureStitchEvent.POST.invoker().stitch(event.getMap());
+        }
+    }
+}

+ 274 - 0
forge/src/main/java/me/shedaniel/architectury/event/forge/EventHandlerImplCommon.java

@@ -0,0 +1,274 @@
+package me.shedaniel.architectury.event.forge;
+
+import me.shedaniel.architectury.event.events.*;
+import net.minecraft.entity.player.ServerPlayerEntity;
+import net.minecraft.item.ItemStack;
+import net.minecraft.util.ActionResult;
+import net.minecraft.util.ActionResultType;
+import net.minecraft.util.text.ITextComponent;
+import net.minecraft.world.server.ServerWorld;
+import net.minecraftforge.event.CommandEvent;
+import net.minecraftforge.event.RegisterCommandsEvent;
+import net.minecraftforge.event.ServerChatEvent;
+import net.minecraftforge.event.TickEvent.Phase;
+import net.minecraftforge.event.TickEvent.PlayerTickEvent;
+import net.minecraftforge.event.TickEvent.ServerTickEvent;
+import net.minecraftforge.event.TickEvent.WorldTickEvent;
+import net.minecraftforge.event.entity.EntityJoinWorldEvent;
+import net.minecraftforge.event.entity.item.ItemTossEvent;
+import net.minecraftforge.event.entity.living.LivingAttackEvent;
+import net.minecraftforge.event.entity.living.LivingDeathEvent;
+import net.minecraftforge.event.entity.player.AdvancementEvent;
+import net.minecraftforge.event.entity.player.EntityItemPickupEvent;
+import net.minecraftforge.event.entity.player.PlayerContainerEvent;
+import net.minecraftforge.event.entity.player.PlayerEvent.*;
+import net.minecraftforge.event.entity.player.PlayerInteractEvent;
+import net.minecraftforge.event.world.ExplosionEvent.Detonate;
+import net.minecraftforge.event.world.ExplosionEvent.Start;
+import net.minecraftforge.event.world.WorldEvent;
+import net.minecraftforge.eventbus.api.Event;
+import net.minecraftforge.eventbus.api.SubscribeEvent;
+import net.minecraftforge.fml.LogicalSide;
+import net.minecraftforge.fml.event.server.FMLServerStartedEvent;
+import net.minecraftforge.fml.event.server.FMLServerStartingEvent;
+import net.minecraftforge.fml.event.server.FMLServerStoppedEvent;
+import net.minecraftforge.fml.event.server.FMLServerStoppingEvent;
+import net.minecraftforge.fml.server.ServerLifecycleHooks;
+
+public class EventHandlerImplCommon {
+    @SubscribeEvent
+    public static void event(ServerTickEvent event) {
+        if (event.phase == Phase.START)
+            TickEvent.SERVER_PRE.invoker().tick(ServerLifecycleHooks.getCurrentServer());
+        else if (event.phase == Phase.END)
+            TickEvent.SERVER_POST.invoker().tick(ServerLifecycleHooks.getCurrentServer());
+    }
+    
+    @SubscribeEvent
+    public static void event(WorldTickEvent event) {
+        if (event.side == LogicalSide.SERVER) {
+            if (event.phase == Phase.START)
+                TickEvent.SERVER_WORLD_PRE.invoker().tick((ServerWorld) event.world);
+            else if (event.phase == Phase.END)
+                TickEvent.SERVER_WORLD_POST.invoker().tick((ServerWorld) event.world);
+        }
+    }
+    
+    @SubscribeEvent
+    public static void event(FMLServerStartingEvent event) {
+        LifecycleEvent.SERVER_STARTING.invoker().stateChanged(event.getServer());
+    }
+    
+    @SubscribeEvent
+    public static void event(FMLServerStartedEvent event) {
+        LifecycleEvent.SERVER_STARTED.invoker().stateChanged(event.getServer());
+    }
+    
+    @SubscribeEvent
+    public static void event(FMLServerStoppingEvent event) {
+        LifecycleEvent.SERVER_STOPPING.invoker().stateChanged(event.getServer());
+    }
+    
+    @SubscribeEvent
+    public static void event(FMLServerStoppedEvent event) {
+        LifecycleEvent.SERVER_STOPPED.invoker().stateChanged(event.getServer());
+    }
+    
+    @SubscribeEvent
+    public static void event(RegisterCommandsEvent event) {
+        CommandRegistrationEvent.EVENT.invoker().register(event.getDispatcher(), event.getEnvironment());
+    }
+    
+    @SubscribeEvent
+    public static void event(PlayerLoggedInEvent event) {
+        PlayerEvent.PLAYER_JOIN.invoker().join((ServerPlayerEntity) event.getPlayer());
+    }
+    
+    @SubscribeEvent
+    public static void event(PlayerLoggedOutEvent event) {
+        PlayerEvent.PLAYER_QUIT.invoker().quit((ServerPlayerEntity) event.getPlayer());
+    }
+    
+    @SubscribeEvent
+    public static void event(PlayerRespawnEvent event) {
+        PlayerEvent.PLAYER_RESPAWN.invoker().respawn((ServerPlayerEntity) event.getPlayer(), event.isEndConquered());
+    }
+    
+    @SubscribeEvent
+    public static void event(CommandEvent event) {
+        CommandPerformEvent performEvent = new CommandPerformEvent(event.getParseResults(), event.getException());
+        if (CommandPerformEvent.EVENT.invoker().act(performEvent) == ActionResultType.FAIL) {
+            event.setCanceled(true);
+        }
+        event.setParseResults(performEvent.getResults());
+        event.setException(performEvent.getThrowable());
+    }
+    
+    @SubscribeEvent
+    public static void event(PlayerTickEvent event) {
+        if (event.phase == Phase.START) {
+            TickEvent.PLAYER_PRE.invoker().tick(event.player);
+        } else if (event.phase == Phase.END) {
+            TickEvent.PLAYER_POST.invoker().tick(event.player);
+        }
+    }
+    
+    @SubscribeEvent
+    public static void event(ServerChatEvent event) {
+        ActionResult<ITextComponent> process = ChatEvent.SERVER.invoker().process(event.getPlayer(), event.getMessage(), event.getComponent());
+        if (process.getObject() != null)
+            event.setComponent(process.getObject());
+        if (process.getResult() == ActionResultType.FAIL)
+            event.setCanceled(true);
+    }
+    
+    @SubscribeEvent
+    public static void event(WorldEvent.Load event) {
+        if (event.getWorld() instanceof ServerWorld) {
+            ServerWorld world = (ServerWorld) event.getWorld();
+            LifecycleEvent.SERVER_WORLD_LOAD.invoker().act(world);
+        }
+    }
+    
+    @SubscribeEvent
+    public static void event(WorldEvent.Unload event) {
+        if (event.getWorld() instanceof ServerWorld) {
+            ServerWorld world = (ServerWorld) event.getWorld();
+            LifecycleEvent.SERVER_WORLD_UNLOAD.invoker().act(world);
+        }
+    }
+    
+    @SubscribeEvent
+    public static void event(WorldEvent.Save event) {
+        if (event.getWorld() instanceof ServerWorld) {
+            ServerWorld world = (ServerWorld) event.getWorld();
+            LifecycleEvent.SERVER_WORLD_SAVE.invoker().act(world);
+        }
+    }
+    
+    @SubscribeEvent
+    public static void event(LivingDeathEvent event) {
+        if (EntityEvent.LIVING_DEATH.invoker().die(event.getEntityLiving(), event.getSource()) == ActionResultType.FAIL) {
+            event.setCanceled(true);
+        }
+    }
+    
+    @SubscribeEvent
+    public static void event(AdvancementEvent event) {
+        if (event.getPlayer() instanceof ServerPlayerEntity) {
+            PlayerEvent.PLAYER_ADVANCEMENT.invoker().award((ServerPlayerEntity) event.getPlayer(), event.getAdvancement());
+        }
+    }
+    
+    @SubscribeEvent
+    public static void event(Clone event) {
+        if (event.getOriginal() instanceof ServerPlayerEntity && event.getPlayer() instanceof ServerPlayerEntity) {
+            PlayerEvent.PLAYER_CLONE.invoker().clone((ServerPlayerEntity) event.getOriginal(), (ServerPlayerEntity) event.getPlayer(), !event.isWasDeath());
+        }
+    }
+    
+    @SubscribeEvent
+    public static void event(Start event) {
+        if (ExplosionEvent.PRE.invoker().explode(event.getWorld(), event.getExplosion()) == ActionResultType.FAIL) {
+            event.setCanceled(true);
+        }
+    }
+    
+    @SubscribeEvent
+    public static void event(Detonate event) {
+        ExplosionEvent.DETONATE.invoker().explode(event.getWorld(), event.getExplosion(), event.getAffectedEntities());
+    }
+    
+    @SubscribeEvent
+    public static void event(LivingAttackEvent event) {
+        if (EntityEvent.LIVING_ATTACK.invoker().attack(event.getEntityLiving(), event.getSource(), event.getAmount()) == ActionResultType.FAIL) {
+            event.setCanceled(true);
+        }
+    }
+    
+    @SubscribeEvent
+    public static void event(EntityJoinWorldEvent event) {
+        if (EntityEvent.ADD.invoker().add(event.getEntity(), event.getWorld()) == ActionResultType.FAIL) {
+            event.setCanceled(true);
+        }
+    }
+    
+    @SubscribeEvent
+    public static void event(ItemCraftedEvent event) {
+        PlayerEvent.CRAFT_ITEM.invoker().craft(event.getPlayer(), event.getCrafting(), event.getInventory());
+    }
+    
+    @SubscribeEvent
+    public static void event(ItemSmeltedEvent event) {
+        PlayerEvent.SMELT_ITEM.invoker().smelt(event.getPlayer(), event.getSmelting());
+    }
+    
+    @SubscribeEvent
+    public static void event(EntityItemPickupEvent event) {
+        PlayerEvent.PICKUP_ITEM_PRE.invoker().canPickup(event.getPlayer(), event.getItem(), event.getItem().getItem());
+    }
+    
+    @SubscribeEvent
+    public static void event(ItemPickupEvent event) {
+        PlayerEvent.PICKUP_ITEM_POST.invoker().pickup(event.getPlayer(), event.getOriginalEntity(), event.getStack());
+    }
+    
+    @SubscribeEvent
+    public static void event(ItemTossEvent event) {
+        PlayerEvent.DROP_ITEM.invoker().drop(event.getPlayer(), event.getEntityItem());
+    }
+    
+    @SubscribeEvent
+    public static void event(PlayerContainerEvent.Open event) {
+        PlayerEvent.OPEN_MENU.invoker().open(event.getPlayer(), event.getContainer());
+    }
+    
+    @SubscribeEvent
+    public static void event(PlayerContainerEvent.Close event) {
+        PlayerEvent.CLOSE_MENU.invoker().close(event.getPlayer(), event.getContainer());
+    }
+    
+    @SubscribeEvent
+    public static void event(PlayerInteractEvent.RightClickItem event) {
+        ActionResult<ItemStack> result = InteractionEvent.RIGHT_CLICK_ITEM.invoker().click(event.getPlayer(), event.getHand());
+        if (result.getResult() != ActionResultType.PASS) {
+            event.setCanceled(true);
+            event.setCancellationResult(result.getResult());
+        }
+    }
+    
+    @SubscribeEvent
+    public static void event(PlayerInteractEvent.RightClickBlock event) {
+        ActionResultType result = InteractionEvent.RIGHT_CLICK_BLOCK.invoker().click(event.getPlayer(), event.getHand(), event.getPos(), event.getFace());
+        if (result != ActionResultType.PASS) {
+            event.setCanceled(true);
+            event.setCancellationResult(result);
+            event.setUseBlock(Event.Result.DENY);
+            event.setUseItem(Event.Result.DENY);
+        }
+    }
+    
+    @SubscribeEvent
+    public static void event(PlayerInteractEvent.EntityInteract event) {
+        ActionResultType result = InteractionEvent.INTERACT_ENTITY.invoker().interact(event.getPlayer(), event.getTarget(), event.getHand());
+        if (result != ActionResultType.PASS) {
+            event.setCanceled(true);
+            event.setCancellationResult(result);
+        }
+    }
+    
+    @SubscribeEvent
+    public static void event(PlayerInteractEvent.LeftClickBlock event) {
+        ActionResultType result = InteractionEvent.LEFT_CLICK_BLOCK.invoker().click(event.getPlayer(), event.getHand(), event.getPos(), event.getFace());
+        if (result != ActionResultType.PASS) {
+            event.setCanceled(true);
+            event.setCancellationResult(result);
+            event.setUseBlock(Event.Result.DENY);
+            event.setUseItem(Event.Result.DENY);
+        }
+    }
+    
+    public static class ModBasedEventHandler {
+        
+    }
+}

+ 12 - 0
forge/src/main/java/me/shedaniel/architectury/event/forge/EventHandlerImplServer.java

@@ -0,0 +1,12 @@
+package me.shedaniel.architectury.event.forge;
+
+import net.minecraftforge.api.distmarker.Dist;
+import net.minecraftforge.api.distmarker.OnlyIn;
+
+@OnlyIn(Dist.DEDICATED_SERVER)
+public class EventHandlerImplServer {
+    @OnlyIn(Dist.DEDICATED_SERVER)
+    public static class ModBasedEventHandler {
+        
+    }
+}

+ 6 - 0
forge/src/main/java/me/shedaniel/architectury/forge/ArchitecturyForge.java

@@ -17,15 +17,21 @@
 package me.shedaniel.architectury.forge;
 
 import me.shedaniel.architectury.event.EventHandler;
+import me.shedaniel.architectury.platform.Platform;
 import me.shedaniel.architectury.platform.forge.EventBuses;
 import net.minecraftforge.fml.common.Mod;
 import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext;
 
+import java.util.stream.Collectors;
+
 @Mod(ArchitecturyForge.MOD_ID)
 public class ArchitecturyForge {
     public static final String MOD_ID = "architectury";
     
     public ArchitecturyForge() {
+        System.out.println(Platform.getMods().stream()
+                .map(me.shedaniel.architectury.platform.Mod::getModId)
+                .collect(Collectors.joining(", ")));
         EventBuses.registerModEventBus(ArchitecturyForge.MOD_ID, FMLJavaModLoadingContext.get().getModEventBus());
         EventHandler.init();
     }

+ 2 - 4
forge/src/main/java/me/shedaniel/architectury/hooks/forge/DyeColorHooksImpl.java

@@ -16,12 +16,10 @@
 
 package me.shedaniel.architectury.hooks.forge;
 
-import me.shedaniel.architectury.hooks.DyeColorHooks;
 import net.minecraft.item.DyeColor;
 
-public class DyeColorHooksImpl implements DyeColorHooks.Impl {
-    @Override
-    public int getColorValue(DyeColor dyeColor) {
+public class DyeColorHooksImpl {
+    public static int getColorValue(DyeColor dyeColor) {
         return dyeColor.getColorValue();
     }
 }

+ 2 - 4
forge/src/main/java/me/shedaniel/architectury/hooks/forge/EntityHooksImpl.java

@@ -16,12 +16,10 @@
 
 package me.shedaniel.architectury.hooks.forge;
 
-import me.shedaniel.architectury.hooks.EntityHooks;
 import net.minecraft.entity.Entity;
 
-public class EntityHooksImpl implements EntityHooks.Impl {
-    @Override
-    public String getEncodeId(Entity entity) {
+public class EntityHooksImpl {
+    public static String getEncodeId(Entity entity) {
         return entity.getEncodeId();
     }
 }

+ 5 - 10
forge/src/main/java/me/shedaniel/architectury/hooks/forge/ExplosionHooksImpl.java

@@ -16,29 +16,24 @@
 
 package me.shedaniel.architectury.hooks.forge;
 
-import me.shedaniel.architectury.hooks.ExplosionHooks;
 import net.minecraft.entity.Entity;
 import net.minecraft.util.math.vector.Vector3d;
 import net.minecraft.world.Explosion;
 
-public class ExplosionHooksImpl implements ExplosionHooks.Impl {
-    @Override
-    public Vector3d getPosition(Explosion explosion) {
+public class ExplosionHooksImpl {
+    public static Vector3d getPosition(Explosion explosion) {
         return explosion.getPosition();
     }
     
-    @Override
-    public Entity getSource(Explosion explosion) {
+    public static Entity getSource(Explosion explosion) {
         return explosion.getExploder();
     }
     
-    @Override
-    public float getRadius(Explosion explosion) {
+    public static float getRadius(Explosion explosion) {
         return explosion.radius;
     }
     
-    @Override
-    public void setRadius(Explosion explosion, float v) {
+    public static void setRadius(Explosion explosion, float v) {
         explosion.radius = v;
     }
 }

+ 2 - 4
forge/src/main/java/me/shedaniel/architectury/hooks/forge/ItemEntityHooksImpl.java

@@ -16,13 +16,11 @@
 
 package me.shedaniel.architectury.hooks.forge;
 
-import me.shedaniel.architectury.hooks.ItemEntityHooks;
 import me.shedaniel.architectury.utils.IntValue;
 import net.minecraft.entity.item.ItemEntity;
 
-public class ItemEntityHooksImpl implements ItemEntityHooks.Impl {
-    @Override
-    public IntValue lifespan(ItemEntity entity) {
+public class ItemEntityHooksImpl {
+    public static IntValue lifespan(ItemEntity entity) {
         return new IntValue() {
             @Override
             public void accept(int value) {

+ 2 - 4
forge/src/main/java/me/shedaniel/architectury/hooks/forge/PackRepositoryHooksImpl.java

@@ -16,13 +16,11 @@
 
 package me.shedaniel.architectury.hooks.forge;
 
-import me.shedaniel.architectury.hooks.PackRepositoryHooks;
 import net.minecraft.resources.IPackFinder;
 import net.minecraft.resources.ResourcePackList;
 
-public class PackRepositoryHooksImpl implements PackRepositoryHooks.Impl{
-    @Override
-    public void addSource(ResourcePackList resourcePackList, IPackFinder iPackFinder) {
+public class PackRepositoryHooksImpl {
+    public static void addSource(ResourcePackList resourcePackList, IPackFinder iPackFinder) {
         resourcePackList.addPackFinder(iPackFinder);
     }
 }

+ 3 - 6
forge/src/main/java/me/shedaniel/architectury/hooks/forge/PlayerHooksImpl.java

@@ -16,18 +16,15 @@
 
 package me.shedaniel.architectury.hooks.forge;
 
-import me.shedaniel.architectury.hooks.PlayerHooks;
 import net.minecraft.entity.player.PlayerEntity;
 import net.minecraftforge.common.util.FakePlayer;
 
-public class PlayerHooksImpl implements PlayerHooks.Impl {
-    @Override
-    public boolean isFake(PlayerEntity playerEntity) {
+public class PlayerHooksImpl {
+    public static boolean isFake(PlayerEntity playerEntity) {
         return playerEntity instanceof FakePlayer;
     }
     
-    @Override
-    public void closeContainer(PlayerEntity playerEntity) {
+    public static void closeContainer(PlayerEntity playerEntity) {
         playerEntity.closeContainer();
     }
 }

+ 4 - 8
forge/src/main/java/me/shedaniel/architectury/hooks/forge/ScreenHooksImpl.java

@@ -16,7 +16,6 @@
 
 package me.shedaniel.architectury.hooks.forge;
 
-import me.shedaniel.architectury.hooks.ScreenHooks;
 import net.minecraft.client.gui.IGuiEventListener;
 import net.minecraft.client.gui.screen.Screen;
 import net.minecraft.client.gui.widget.Widget;
@@ -25,14 +24,12 @@ import net.minecraftforge.fml.common.ObfuscationReflectionHelper;
 import java.lang.reflect.InvocationTargetException;
 import java.util.List;
 
-public class ScreenHooksImpl implements ScreenHooks.Impl {
-    @Override
-    public List<Widget> getButtons(Screen screen) {
+public class ScreenHooksImpl {
+    public static List<Widget> getButtons(Screen screen) {
         return screen.buttons;
     }
     
-    @Override
-    public <T extends Widget> T addButton(Screen screen, T t) {
+    public static <T extends Widget> T addButton(Screen screen, T t) {
         try {
             return (T) ObfuscationReflectionHelper.findMethod(Screen.class, "func_230480_a_", Widget.class).invoke(screen, t);
         } catch (IllegalAccessException | InvocationTargetException e) {
@@ -40,8 +37,7 @@ public class ScreenHooksImpl implements ScreenHooks.Impl {
         }
     }
     
-    @Override
-    public <T extends IGuiEventListener> T addChild(Screen screen, T t) {
+    public static <T extends IGuiEventListener> T addChild(Screen screen, T t) {
         try {
             return (T) ObfuscationReflectionHelper.findMethod(Screen.class, "func_230481_d_", IGuiEventListener.class).invoke(screen, t);
         } catch (IllegalAccessException | InvocationTargetException e) {

+ 2 - 3
forge/src/main/java/me/shedaniel/architectury/networking/forge/ClientNetworkingManager.java

@@ -27,18 +27,17 @@ import net.minecraftforge.common.MinecraftForge;
 import net.minecraftforge.fml.network.NetworkEvent;
 
 import java.util.Set;
-import java.util.function.Consumer;
 
 import static me.shedaniel.architectury.networking.forge.NetworkManagerImpl.C2S;
 import static me.shedaniel.architectury.networking.forge.NetworkManagerImpl.SYNC_IDS;
 
 @OnlyIn(Dist.CLIENT)
 public class ClientNetworkingManager {
-    public static Consumer<NetworkManagerImpl> initClient() {
+    public static void initClient() {
         NetworkManagerImpl.CHANNEL.addListener(NetworkManagerImpl.createPacketHandler(NetworkEvent.ServerCustomPayloadEvent.class, NetworkManagerImpl.S2C));
         MinecraftForge.EVENT_BUS.<ClientPlayerNetworkEvent.LoggedOutEvent>addListener(event -> NetworkManagerImpl.serverReceivables.clear());
         
-        return impl -> impl.registerS2CReceiver(SYNC_IDS, (buffer, context) -> {
+        NetworkManagerImpl.registerS2CReceiver(SYNC_IDS, (buffer, context) -> {
             Set<ResourceLocation> receivables = NetworkManagerImpl.serverReceivables;
             int size = buffer.readInt();
             receivables.clear();

+ 9 - 13
forge/src/main/java/me/shedaniel/architectury/networking/forge/NetworkManagerImpl.java

@@ -43,9 +43,8 @@ import java.util.Map;
 import java.util.Set;
 import java.util.function.Consumer;
 
-public class NetworkManagerImpl implements NetworkManager.Impl {
-    @Override
-    public void registerReceiver(NetworkManager.Side side, ResourceLocation id, NetworkReceiver receiver) {
+public class NetworkManagerImpl {
+    public static void registerReceiver(NetworkManager.Side side, ResourceLocation id, NetworkReceiver receiver) {
         if (side == NetworkManager.Side.C2S) {
             registerC2SReceiver(id, receiver);
         } else if (side == NetworkManager.Side.S2C) {
@@ -53,8 +52,7 @@ public class NetworkManagerImpl implements NetworkManager.Impl {
         }
     }
     
-    @Override
-    public IPacket<?> toPacket(NetworkManager.Side side, ResourceLocation id, PacketBuffer buffer) {
+    public static IPacket<?> toPacket(NetworkManager.Side side, ResourceLocation id, PacketBuffer buffer) {
         PacketBuffer packetBuffer = new PacketBuffer(Unpooled.buffer());
         packetBuffer.writeResourceLocation(id);
         packetBuffer.writeBytes(buffer);
@@ -69,10 +67,10 @@ public class NetworkManagerImpl implements NetworkManager.Impl {
     static final Set<ResourceLocation> serverReceivables = Sets.newHashSet();
     private static final Multimap<PlayerEntity, ResourceLocation> clientReceivables = Multimaps.newMultimap(Maps.newHashMap(), Sets::newHashSet);
     
-    public NetworkManagerImpl() {
+    static  {
         CHANNEL.addListener(createPacketHandler(NetworkEvent.ClientCustomPayloadEvent.class, C2S));
         
-        DistExecutor.unsafeCallWhenOn(Dist.CLIENT, () -> ClientNetworkingManager::initClient).accept(this);
+        DistExecutor.unsafeRunWhenOn(Dist.CLIENT, () -> ClientNetworkingManager::initClient);
         
         MinecraftForge.EVENT_BUS.<PlayerEvent.PlayerLoggedInEvent>addListener(event -> NetworkManager.sendToPlayer((ServerPlayerEntity) event.getPlayer(), SYNC_IDS, sendSyncPacket(C2S)));
         MinecraftForge.EVENT_BUS.<PlayerEvent.PlayerLoggedOutEvent>addListener(event -> clientReceivables.removeAll(event.getPlayer()));
@@ -123,21 +121,19 @@ public class NetworkManagerImpl implements NetworkManager.Impl {
     }
     
     @OnlyIn(Dist.CLIENT)
-    public void registerS2CReceiver(ResourceLocation id, NetworkReceiver receiver) {
+    public static void registerS2CReceiver(ResourceLocation id, NetworkReceiver receiver) {
         S2C.put(id, receiver);
     }
     
-    public void registerC2SReceiver(ResourceLocation id, NetworkReceiver receiver) {
+    public static void registerC2SReceiver(ResourceLocation id, NetworkReceiver receiver) {
         C2S.put(id, receiver);
     }
     
-    @Override
-    public boolean canServerReceive(ResourceLocation id) {
+    public static boolean canServerReceive(ResourceLocation id) {
         return serverReceivables.contains(id);
     }
     
-    @Override
-    public boolean canPlayerReceive(ServerPlayerEntity player, ResourceLocation id) {
+    public static boolean canPlayerReceive(ServerPlayerEntity player, ResourceLocation id) {
         return clientReceivables.get(player).contains(id);
     }
     

+ 13 - 23
forge/src/main/java/me/shedaniel/architectury/platform/forge/PlatformImpl.java

@@ -17,7 +17,6 @@
 package me.shedaniel.architectury.platform.forge;
 
 import me.shedaniel.architectury.platform.Mod;
-import me.shedaniel.architectury.platform.Platform;
 import net.minecraftforge.api.distmarker.Dist;
 import net.minecraftforge.fml.ExtensionPoint;
 import net.minecraftforge.fml.ModContainer;
@@ -35,54 +34,45 @@ import java.util.HashMap;
 import java.util.Map;
 import java.util.stream.Collectors;
 
-public class PlatformImpl implements Platform.Impl {
-    private final Map<String, Mod> mods = new HashMap<>();
+public class PlatformImpl {
+    private static final Map<String, Mod> mods = new HashMap<>();
     
-    @Override
-    public Path getGameFolder() {
+    public static Path getGameFolder() {
         return FMLPaths.GAMEDIR.get();
     }
     
-    @Override
-    public Path getConfigFolder() {
+    public static Path getConfigFolder() {
         return FMLPaths.CONFIGDIR.get();
     }
     
-    @Override
-    public Path getModsFolder() {
+    public static Path getModsFolder() {
         return FMLPaths.MODSDIR.get();
     }
     
-    @Override
-    public Dist getEnv() {
+    public static Dist getEnv() {
         return FMLEnvironment.dist;
     }
     
-    @Override
-    public boolean isModLoaded(String id) {
+    public static boolean isModLoaded(String id) {
         return ModList.get().isLoaded(id);
     }
     
-    @Override
-    public Mod getMod(String id) {
-        return this.mods.computeIfAbsent(id, ModImpl::new);
+    public static Mod getMod(String id) {
+        return mods.computeIfAbsent(id, ModImpl::new);
     }
     
-    @Override
-    public Collection<Mod> getMods() {
+    public static Collection<Mod> getMods() {
         for (IModInfo mod : ModList.get().getMods()) {
             getMod(mod.getModId());
         }
-        return this.mods.values();
+        return mods.values();
     }
     
-    @Override
-    public Collection<String> getModIds() {
+    public static Collection<String> getModIds() {
         return ModList.get().getMods().stream().map(ModInfo::getModId).collect(Collectors.toList());
     }
     
-    @Override
-    public boolean isDevelopmentEnvironment() {
+    public static boolean isDevelopmentEnvironment() {
         return !FMLLoader.isProduction();
     }
     

+ 2 - 4
forge/src/main/java/me/shedaniel/architectury/registry/forge/BlockEntityRenderersImpl.java

@@ -16,7 +16,6 @@
 
 package me.shedaniel.architectury.registry.forge;
 
-import me.shedaniel.architectury.registry.BlockEntityRenderers;
 import net.minecraft.client.renderer.tileentity.TileEntityRenderer;
 import net.minecraft.client.renderer.tileentity.TileEntityRendererDispatcher;
 import net.minecraft.tileentity.TileEntity;
@@ -25,9 +24,8 @@ import net.minecraftforge.fml.client.registry.ClientRegistry;
 
 import java.util.function.Function;
 
-public class BlockEntityRenderersImpl implements BlockEntityRenderers.Impl {
-    @Override
-    public <T extends TileEntity> void registerRenderer(TileEntityType<T> type, Function<TileEntityRendererDispatcher, TileEntityRenderer<T>> provider) {
+public class BlockEntityRenderersImpl {
+    public static <T extends TileEntity> void registerRenderer(TileEntityType<T> type, Function<TileEntityRendererDispatcher, TileEntityRenderer<T>> provider) {
         ClientRegistry.bindTileEntityRenderer(type, provider);
     }
 }

+ 5 - 9
forge/src/main/java/me/shedaniel/architectury/registry/forge/BlockPropertiesImpl.java

@@ -25,24 +25,20 @@ import net.minecraft.block.material.MaterialColor;
 
 import java.util.function.Function;
 
-public class BlockPropertiesImpl implements BlockProperties.Impl {
-    @Override
-    public BlockProperties of(Material material, MaterialColor materialColor) {
+public class BlockPropertiesImpl {
+    public static BlockProperties of(Material material, MaterialColor materialColor) {
         return new Impl(material, (state) -> materialColor);
     }
     
-    @Override
-    public BlockProperties of(Material material, Function<BlockState, MaterialColor> function) {
+    public static BlockProperties of(Material material, Function<BlockState, MaterialColor> function) {
         return new Impl(material, function);
     }
     
-    @Override
-    public BlockProperties copy(AbstractBlock abstractBlock) {
+    public static BlockProperties copy(AbstractBlock abstractBlock) {
         return copy(abstractBlock.properties);
     }
     
-    @Override
-    public BlockProperties copy(AbstractBlock.Properties old) {
+    public static BlockProperties copy(AbstractBlock.Properties old) {
         BlockProperties properties = of(old.material, old.materialColor);
         properties.material = old.material;
         properties.destroyTime = old.destroyTime;

+ 4 - 7
forge/src/main/java/me/shedaniel/architectury/registry/forge/ColorHandlersImpl.java

@@ -17,7 +17,6 @@
 package me.shedaniel.architectury.registry.forge;
 
 import com.google.common.collect.Lists;
-import me.shedaniel.architectury.registry.ColorHandlers;
 import net.minecraft.block.Block;
 import net.minecraft.client.Minecraft;
 import net.minecraft.client.renderer.color.IBlockColor;
@@ -29,11 +28,11 @@ import org.apache.commons.lang3.tuple.Pair;
 
 import java.util.List;
 
-public class ColorHandlersImpl implements ColorHandlers.Impl {
+public class ColorHandlersImpl {
     private static final List<Pair<IItemColor, IItemProvider[]>> ITEM_COLORS = Lists.newArrayList();
     private static final List<Pair<IBlockColor, Block[]>> BLOCK_COLORS = Lists.newArrayList();
     
-    public ColorHandlersImpl() {
+    static {
         MinecraftForge.EVENT_BUS.<ColorHandlerEvent.Item>addListener(event -> {
             for (Pair<IItemColor, IItemProvider[]> pair : ITEM_COLORS) {
                 event.getItemColors().register(pair.getLeft(), pair.getRight());
@@ -46,8 +45,7 @@ public class ColorHandlersImpl implements ColorHandlers.Impl {
         });
     }
     
-    @Override
-    public void registerItemColors(IItemColor itemColor, IItemProvider... items) {
+    public static void registerItemColors(IItemColor itemColor, IItemProvider... items) {
         if (Minecraft.getInstance().getItemColors() == null) {
             ITEM_COLORS.add(Pair.of(itemColor, items));
         } else {
@@ -55,8 +53,7 @@ public class ColorHandlersImpl implements ColorHandlers.Impl {
         }
     }
     
-    @Override
-    public void registerBlockColors(IBlockColor blockColor, Block... blocks) {
+    public static void registerBlockColors(IBlockColor blockColor, Block... blocks) {
         if (Minecraft.getInstance().getBlockColors() == null) {
             BLOCK_COLORS.add(Pair.of(blockColor, blocks));
         } else {

+ 2 - 4
forge/src/main/java/me/shedaniel/architectury/registry/forge/CreativeTabsImpl.java

@@ -16,7 +16,6 @@
 
 package me.shedaniel.architectury.registry.forge;
 
-import me.shedaniel.architectury.registry.CreativeTabs;
 import net.minecraft.item.ItemGroup;
 import net.minecraft.item.ItemStack;
 import net.minecraft.util.ResourceLocation;
@@ -24,9 +23,8 @@ import net.minecraft.util.ResourceLocation;
 import javax.annotation.Nonnull;
 import java.util.function.Supplier;
 
-public class CreativeTabsImpl implements CreativeTabs.Impl {
-    @Override
-    public ItemGroup create(ResourceLocation resourceLocation, Supplier<ItemStack> supplier) {
+public class CreativeTabsImpl {
+    public static ItemGroup create(ResourceLocation resourceLocation, Supplier<ItemStack> supplier) {
         return new ItemGroup(String.format("%s.%s", resourceLocation.getNamespace(), resourceLocation.getPath())) {
             @Override
             @Nonnull

+ 2 - 4
forge/src/main/java/me/shedaniel/architectury/registry/forge/KeyBindingsImpl.java

@@ -16,13 +16,11 @@
 
 package me.shedaniel.architectury.registry.forge;
 
-import me.shedaniel.architectury.registry.KeyBindings;
 import net.minecraft.client.settings.KeyBinding;
 import net.minecraftforge.fml.client.registry.ClientRegistry;
 
-public class KeyBindingsImpl implements KeyBindings.Impl {
-    @Override
-    public void registerKeyBinding(KeyBinding keyBinding) {
+public class KeyBindingsImpl {
+    public static void registerKeyBinding(KeyBinding keyBinding) {
         ClientRegistry.registerKeyBinding(keyBinding);
     }
 }

+ 4 - 7
forge/src/main/java/me/shedaniel/architectury/registry/forge/RegistriesImpl.java

@@ -40,21 +40,18 @@ import java.util.Optional;
 import java.util.Set;
 import java.util.function.Supplier;
 
-public class RegistriesImpl implements Registries.Impl {
-    @Override
-    public Registries.RegistryProvider get(String modId) {
+public class RegistriesImpl {
+    public static Registries.RegistryProvider _get(String modId) {
         return new RegistryProviderImpl(modId);
     }
     
-    @Override
-    public <T> ResourceLocation getId(T t, RegistryKey<net.minecraft.util.registry.Registry<T>> registryKey) {
+    public static <T> ResourceLocation getId(T t, RegistryKey<net.minecraft.util.registry.Registry<T>> registryKey) {
         if (t instanceof IForgeRegistryEntry)
             return ((IForgeRegistryEntry<?>) t).getRegistryName();
         return null;
     }
     
-    @Override
-    public <T> ResourceLocation getId(T t, net.minecraft.util.registry.Registry<T> registry) {
+    public static <T> ResourceLocation getId(T t, net.minecraft.util.registry.Registry<T> registry) {
         if (t instanceof IForgeRegistryEntry)
             return ((IForgeRegistryEntry<?>) t).getRegistryName();
         return null;

+ 5 - 7
forge/src/main/java/me/shedaniel/architectury/registry/forge/ReloadListenersImpl.java

@@ -17,7 +17,6 @@
 package me.shedaniel.architectury.registry.forge;
 
 import com.google.common.collect.Lists;
-import me.shedaniel.architectury.registry.ReloadListeners;
 import net.minecraft.client.Minecraft;
 import net.minecraft.resources.IFutureReloadListener;
 import net.minecraft.resources.IReloadableResourceManager;
@@ -29,10 +28,10 @@ import net.minecraftforge.event.AddReloadListenerEvent;
 
 import java.util.List;
 
-public class ReloadListenersImpl implements ReloadListeners.Impl {
-    private List<IFutureReloadListener> serverDataReloadListeners = Lists.newArrayList();
+public class ReloadListenersImpl {
+    private static List<IFutureReloadListener> serverDataReloadListeners = Lists.newArrayList();
     
-    public ReloadListenersImpl() {
+    static {
         MinecraftForge.EVENT_BUS.<AddReloadListenerEvent>addListener(event -> {
             for (IFutureReloadListener listener : serverDataReloadListeners) {
                 event.addListener(listener);
@@ -40,8 +39,7 @@ public class ReloadListenersImpl implements ReloadListeners.Impl {
         });
     }
     
-    @Override
-    public void registerReloadListener(ResourcePackType type, IFutureReloadListener listener) {
+    public static void registerReloadListener(ResourcePackType type, IFutureReloadListener listener) {
         if (type == ResourcePackType.SERVER_DATA) {
             serverDataReloadListeners.add(listener);
         } else if (type == ResourcePackType.CLIENT_RESOURCES) {
@@ -50,7 +48,7 @@ public class ReloadListenersImpl implements ReloadListeners.Impl {
     }
     
     @OnlyIn(Dist.CLIENT)
-    private void reloadClientReloadListener(IFutureReloadListener listener) {
+    private static void reloadClientReloadListener(IFutureReloadListener listener) {
         ((IReloadableResourceManager) Minecraft.getInstance().getResourceManager()).registerReloadListener(listener);
     }
 }

+ 3 - 6
forge/src/main/java/me/shedaniel/architectury/registry/forge/RenderTypesImpl.java

@@ -16,22 +16,19 @@
 
 package me.shedaniel.architectury.registry.forge;
 
-import me.shedaniel.architectury.registry.RenderTypes;
 import net.minecraft.block.Block;
 import net.minecraft.client.renderer.RenderType;
 import net.minecraft.client.renderer.RenderTypeLookup;
 import net.minecraft.fluid.Fluid;
 
-public class RenderTypesImpl implements RenderTypes.Impl {
-    @Override
-    public void register(RenderType type, Block... blocks) {
+public class RenderTypesImpl {
+    public static void register(RenderType type, Block... blocks) {
         for (Block block : blocks) {
             RenderTypeLookup.setRenderLayer(block, type);
         }
     }
     
-    @Override
-    public void register(RenderType type, Fluid... fluids) {
+    public static void register(RenderType type, Fluid... fluids) {
         for (Fluid fluid : fluids) {
             RenderTypeLookup.setRenderLayer(fluid, type);
         }

+ 5 - 10
forge/src/main/java/me/shedaniel/architectury/registry/forge/ToolTypeImpl.java

@@ -17,28 +17,23 @@
 package me.shedaniel.architectury.registry.forge;
 
 
-import me.shedaniel.architectury.registry.ToolType;
 import net.minecraft.item.Item;
 import net.minecraft.tags.ITag;
 
-public class ToolTypeImpl implements ToolType.Impl {
-    @Override
-    public ITag<Item> pickaxeTag() {
+public class ToolTypeImpl {
+    public static ITag<Item> pickaxeTag() {
         return null;
     }
     
-    @Override
-    public ITag<Item> axeTag() {
+    public static ITag<Item> axeTag() {
         return null;
     }
     
-    @Override
-    public ITag<Item> hoeTag() {
+    public static ITag<Item> hoeTag() {
         return null;
     }
     
-    @Override
-    public ITag<Item> shovelTag() {
+    public static ITag<Item> shovelTag() {
         return null;
     }
 }

+ 2 - 4
forge/src/main/java/me/shedaniel/architectury/utils/forge/GameInstanceImpl.java

@@ -16,13 +16,11 @@
 
 package me.shedaniel.architectury.utils.forge;
 
-import me.shedaniel.architectury.utils.GameInstance;
 import net.minecraft.server.MinecraftServer;
 import net.minecraftforge.fml.server.ServerLifecycleHooks;
 
-public class GameInstanceImpl implements GameInstance.Impl {
-    @Override
-    public MinecraftServer getServer() {
+public class GameInstanceImpl {
+    public static MinecraftServer getServer() {
         return ServerLifecycleHooks.getCurrentServer();
     }
 }

+ 6 - 0
forge/src/main/resources/pack.mcmeta

@@ -0,0 +1,6 @@
+{
+  "pack": {
+    "description": "Architectury",
+    "pack_format": 6
+  }
+}