diff --git a/Common/src/main/java/com/example/examplemod/CommonClass.java b/Common/src/main/java/com/example/examplemod/CommonClass.java index dd2d653..7cd816f 100644 --- a/Common/src/main/java/com/example/examplemod/CommonClass.java +++ b/Common/src/main/java/com/example/examplemod/CommonClass.java @@ -1,40 +1,31 @@ package com.example.examplemod; import com.example.examplemod.platform.Services; -import net.minecraft.core.Registry; -import net.minecraft.network.chat.Component; -import net.minecraft.world.food.FoodProperties; -import net.minecraft.world.item.ItemStack; +import net.minecraft.core.registries.BuiltInRegistries; import net.minecraft.world.item.Items; -import net.minecraft.world.item.TooltipFlag; - -import java.util.List; +// This class is part of the common project meaning it is shared between all supported loaders. Code written here can only +// import and access the vanilla codebase, libraries used by vanilla, and optionally third party libraries that provide +// common compatible binaries. This means common code can not directly use loader specific concepts such as Forge events +// however it will be compatible with all supported mod loaders. public class CommonClass { - // This method serves as an initialization hook for the mod. The vanilla - // game has no mechanism to load tooltip listeners so this must be - // invoked from a mod loader specific project like Forge or Fabric. + // The loader specific projects are able to import and use any code from the common project. This allows you to + // write the majority of your code here and load it from your loader specific projects. This example has some + // code that gets invoked by the entry point of the loader specific projects. public static void init() { - Constants.LOG.info("Hello from Common init on {}! we are currently in a {} environment!", Services.PLATFORM.getPlatformName(), Services.PLATFORM.isDevelopmentEnvironment() ? "development" : "production"); - Constants.LOG.info("Diamond Item >> {}", Registry.ITEM.getKey(Items.DIAMOND)); - } + Constants.LOG.info("Hello from Common init on {}! we are currently in a {} environment!", Services.PLATFORM.getPlatformName(), Services.PLATFORM.getEnvironmentName()); + Constants.LOG.info("The ID for diamonds is {}", BuiltInRegistries.ITEM.getKey(Items.DIAMOND)); - // This method serves as a hook to modify item tooltips. The vanilla game - // has no mechanism to load tooltip listeners so this must be registered - // by a mod loader like Forge or Fabric. - public static void onItemTooltip(ItemStack stack, TooltipFlag context, List tooltip) { + // It is common for all supported loaders to provide a similar feature that can not be used directly in the + // common code. A popular way to get around this is using Java's built-in service loader feature to create + // your own abstraction layer. You can learn more about this in our provided services class. In this example + // we have an interface in the common code and use a loader specific implementation to delegate our call to + // the platform specific approach. + if (Services.PLATFORM.isModLoaded("examplemod")) { - if (!stack.isEmpty()) { - - final FoodProperties food = stack.getItem().getFoodProperties(); - - if (food != null) { - - tooltip.add(Component.literal("Nutrition: " + food.getNutrition())); - tooltip.add(Component.literal("Saturation: " + food.getSaturationModifier())); - } + Constants.LOG.info("Hello to examplemod"); } } } \ No newline at end of file diff --git a/Common/src/main/java/com/example/examplemod/platform/Services.java b/Common/src/main/java/com/example/examplemod/platform/Services.java index 738a418..b3a1530 100644 --- a/Common/src/main/java/com/example/examplemod/platform/Services.java +++ b/Common/src/main/java/com/example/examplemod/platform/Services.java @@ -5,10 +5,20 @@ import com.example.examplemod.platform.services.IPlatformHelper; import java.util.ServiceLoader; +// Service loaders are a built-in Java feature that allow us to locate implementations of an interface that vary from one +// environment to another. In the context of MultiLoader we use this feature to access a mock API in the common code that +// is swapped out for the platform specific implementation at runtime. public class Services { + // In this example we provide a platform helper which provides information about what platform the mod is running on. + // For example this can be used to check if the code is running on Forge vs Fabric, or to ask the modloader if another + // mod is loaded. public static final IPlatformHelper PLATFORM = load(IPlatformHelper.class); + // This code is used to load a service for the current environment. Your implementation of the service must be defined + // manually by including a text file in META-INF/services named with the fully qualified class name of the service. + // Inside the file you should write the fully qualified class name of the implementation to load for the platform. For + // example our file on Forge points to ForgePlatformHelper while Fabric points to FabricPlatformHelper. public static T load(Class clazz) { final T loadedService = ServiceLoader.load(clazz) @@ -17,4 +27,4 @@ public class Services { Constants.LOG.debug("Loaded {} for service {}", loadedService, clazz); return loadedService; } -} +} \ No newline at end of file diff --git a/Common/src/main/java/com/example/examplemod/platform/services/IPlatformHelper.java b/Common/src/main/java/com/example/examplemod/platform/services/IPlatformHelper.java index 21e3452..3553cac 100644 --- a/Common/src/main/java/com/example/examplemod/platform/services/IPlatformHelper.java +++ b/Common/src/main/java/com/example/examplemod/platform/services/IPlatformHelper.java @@ -23,4 +23,14 @@ public interface IPlatformHelper { * @return True if in a development environment, false otherwise. */ boolean isDevelopmentEnvironment(); -} + + /** + * Gets the name of the environment type as a string. + * + * @return The name of the environment type. + */ + default String getEnvironmentName() { + + return isDevelopmentEnvironment() ? "development" : "production"; + } +} \ No newline at end of file diff --git a/Fabric/build.gradle b/Fabric/build.gradle index 337a4a2..535c5e4 100644 --- a/Fabric/build.gradle +++ b/Fabric/build.gradle @@ -1,5 +1,5 @@ plugins { - id 'fabric-loom' version '0.12-SNAPSHOT' + id 'fabric-loom' version '1.0-SNAPSHOT' id 'maven-publish' id 'idea' } diff --git a/Fabric/src/main/java/com/example/examplemod/ExampleMod.java b/Fabric/src/main/java/com/example/examplemod/ExampleMod.java index 9dddb74..e53f1a7 100644 --- a/Fabric/src/main/java/com/example/examplemod/ExampleMod.java +++ b/Fabric/src/main/java/com/example/examplemod/ExampleMod.java @@ -1,7 +1,6 @@ package com.example.examplemod; import net.fabricmc.api.ModInitializer; -import net.fabricmc.fabric.api.client.item.v1.ItemTooltipCallback; public class ExampleMod implements ModInitializer { @@ -15,9 +14,5 @@ public class ExampleMod implements ModInitializer { // Use Fabric to bootstrap the Common mod. Constants.LOG.info("Hello Fabric world!"); CommonClass.init(); - - // Some code like events require special initialization from the - // loader specific code. - ItemTooltipCallback.EVENT.register(CommonClass::onItemTooltip); } } diff --git a/Fabric/src/main/resources/fabric.mod.json b/Fabric/src/main/resources/fabric.mod.json index 4cbbe42..c45f5c6 100644 --- a/Fabric/src/main/resources/fabric.mod.json +++ b/Fabric/src/main/resources/fabric.mod.json @@ -29,7 +29,7 @@ "depends": { "fabricloader": ">=0.14", "fabric": "*", - "minecraft": "1.19.x", + "minecraft": "1.19.3", "java": ">=17" }, "suggests": { diff --git a/Forge/build.gradle b/Forge/build.gradle index ab9c78e..6762a90 100644 --- a/Forge/build.gradle +++ b/Forge/build.gradle @@ -1,16 +1,9 @@ -buildscript { - repositories { - maven { url = 'https://maven.minecraftforge.net' } - mavenCentral() - } - dependencies { - classpath group: 'net.minecraftforge.gradle', name: 'ForgeGradle', version: '5.1.+', changing: true - } +plugins { + id 'java' + id 'eclipse' + id 'maven-publish' + id 'net.minecraftforge.gradle' version '5.1.+' } -apply plugin: 'java' -apply plugin: 'net.minecraftforge.gradle' -apply plugin: 'eclipse' -apply plugin: 'maven-publish' archivesBaseName = "${mod_name}-forge-${minecraft_version}" diff --git a/Forge/src/main/java/com/example/examplemod/ExampleMod.java b/Forge/src/main/java/com/example/examplemod/ExampleMod.java index 22d578d..06f3628 100644 --- a/Forge/src/main/java/com/example/examplemod/ExampleMod.java +++ b/Forge/src/main/java/com/example/examplemod/ExampleMod.java @@ -1,7 +1,5 @@ package com.example.examplemod; -import net.minecraftforge.common.MinecraftForge; -import net.minecraftforge.event.entity.player.ItemTooltipEvent; import net.minecraftforge.fml.common.Mod; @Mod(Constants.MOD_ID) @@ -16,18 +14,6 @@ public class ExampleMod { // Use Forge to bootstrap the Common mod. Constants.LOG.info("Hello Forge world!"); CommonClass.init(); - - // Some code like events require special initialization from the - // loader specific code. - MinecraftForge.EVENT_BUS.addListener(this::onItemTooltip); } - - // This method exists as a wrapper for the code in the Common project. - // It takes Forge's event object and passes the parameters along to - // the Common listener. - private void onItemTooltip(ItemTooltipEvent event) { - - CommonClass.onItemTooltip(event.getItemStack(), event.getFlags(), event.getToolTip()); - } } \ No newline at end of file diff --git a/Forge/src/main/java/com/example/examplemod/platform/ForgePlatformHelper.java b/Forge/src/main/java/com/example/examplemod/platform/ForgePlatformHelper.java index 43edb0d..22ef9e4 100644 --- a/Forge/src/main/java/com/example/examplemod/platform/ForgePlatformHelper.java +++ b/Forge/src/main/java/com/example/examplemod/platform/ForgePlatformHelper.java @@ -23,4 +23,4 @@ public class ForgePlatformHelper implements IPlatformHelper { return !FMLLoader.isProduction(); } -} +} \ No newline at end of file diff --git a/Forge/src/main/resources/META-INF/mods.toml b/Forge/src/main/resources/META-INF/mods.toml index a2889e3..c430a3a 100644 --- a/Forge/src/main/resources/META-INF/mods.toml +++ b/Forge/src/main/resources/META-INF/mods.toml @@ -6,7 +6,7 @@ # The name of the mod loader type to load - for regular FML @Mod mods it should be javafml modLoader="javafml" #mandatory # A version range to match for said mod loader - for regular FML @Mod it will be the forge version -loaderVersion="[43,)" #mandatory This is typically bumped every Minecraft version by Forge. See our download page for lists of versions. +loaderVersion="[44,)" #mandatory This is typically bumped every Minecraft version by Forge. See our download page for lists of versions. # The license for you mod. This is mandatory metadata and allows for easier comprehension of your redistributive properties. # Review your options at https://choosealicense.com/. All rights reserved is the default copyright stance, and is thus the default here. license="All rights reserved" @@ -47,7 +47,7 @@ Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed mollis lacinia magn # Does this dependency have to exist - if not, ordering below must be specified mandatory=true #mandatory # The version range of the dependency - versionRange="[43,)" #mandatory + versionRange="[44,)" #mandatory # An ordering relationship for the dependency - BEFORE or AFTER required if the relationship is not mandatory ordering="NONE" # Side this dependency is applied on - BOTH, CLIENT or SERVER @@ -57,6 +57,6 @@ Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed mollis lacinia magn modId="minecraft" mandatory=true # This version range declares a minimum of the current minecraft version up to but not including the next major version - versionRange="[1.19.2,1.20)" + versionRange="[1.19.3,1.20)" ordering="NONE" side="BOTH" diff --git a/build.gradle b/build.gradle index 98616ee..3c3c1ca 100644 --- a/build.gradle +++ b/build.gradle @@ -19,7 +19,7 @@ subprojects { 'Implementation-Version' : project.jar.archiveVersion, 'Implementation-Vendor' : mod_author, 'Implementation-Timestamp': new Date().format("yyyy-MM-dd'T'HH:mm:ssZ"), - 'Timestamp' : System.currentTimeMillis(), + 'Timestamp' : System.currentTimeMillis(), 'Built-On-Java' : "${System.getProperty('java.vm.version')} (${System.getProperty('java.vm.vendor')})", 'Built-On-Minecraft' : minecraft_version ]) diff --git a/gradle.properties b/gradle.properties index 4c81531..79f8fe0 100644 --- a/gradle.properties +++ b/gradle.properties @@ -3,18 +3,18 @@ version=1.0.0 group=com.example.examplemod # Common -minecraft_version=1.19.2 +minecraft_version=1.19.3 common_runs_enabled=false common_client_run_name=Common Client common_server_run_name=Common Server # Forge -forge_version=43.1.30 +forge_version=44.0.1 //forge_ats_enabled=true # Fabric -fabric_version=0.62.0+1.19.2 -fabric_loader_version=0.14.9 +fabric_version=0.68.1+1.19.3 +fabric_loader_version=0.14.11 # Mod options mod_name=MultiLoader diff --git a/settings.gradle b/settings.gradle index 174e944..f8a3342 100644 --- a/settings.gradle +++ b/settings.gradle @@ -1,6 +1,10 @@ pluginManagement { repositories { gradlePluginPortal() + maven { + name = 'Forge' + url = 'https://maven.minecraftforge.net/' + } maven { name = 'Fabric' url = 'https://maven.fabricmc.net/'