User: rednesto Date: 08 Jun 23 22:56 Revision: 2618fdcef723942477bfd618ed925109ec203a6b Summary: Update Forge templates for FG6 & 1.20 Also fix velocity BuildConstants being put in the wrong directory TeamCity URL: http://ci.mcdev.io:80/viewModification.html?tab=vcsModificationFiles&modId=8515&personal=false Index: src/main/kotlin/platform/forge/creator/asset-steps.kt =================================================================== --- src/main/kotlin/platform/forge/creator/asset-steps.kt (revision ac35e7d53524e24c145ac9fe9206bb2295e1b38d) +++ src/main/kotlin/platform/forge/creator/asset-steps.kt (revision 2618fdcef723942477bfd618ed925109ec203a6b) @@ -103,6 +103,7 @@ } val mainClassTemplate = when { + mcVersion >= MinecraftVersions.MC1_20 -> MinecraftTemplates.FG3_1_20_MAIN_CLASS_TEMPLATE mcVersion >= MinecraftVersions.MC1_19_3 -> MinecraftTemplates.FG3_1_19_3_MAIN_CLASS_TEMPLATE mcVersion >= MinecraftVersions.MC1_19 -> MinecraftTemplates.FG3_1_19_MAIN_CLASS_TEMPLATE mcVersion >= MinecraftVersions.MC1_18 -> MinecraftTemplates.FG3_1_18_MAIN_CLASS_TEMPLATE Index: src/main/kotlin/platform/forge/creator/gradle-steps.kt =================================================================== --- src/main/kotlin/platform/forge/creator/gradle-steps.kt (revision ac35e7d53524e24c145ac9fe9206bb2295e1b38d) +++ src/main/kotlin/platform/forge/creator/gradle-steps.kt (revision 2618fdcef723942477bfd618ed925109ec203a6b) @@ -35,6 +35,8 @@ import com.demonwav.mcdev.creator.step.AbstractLongRunningAssetsStep import com.demonwav.mcdev.creator.step.AbstractModNameStep import com.demonwav.mcdev.creator.step.AuthorsStep +import com.demonwav.mcdev.creator.step.DescriptionStep +import com.demonwav.mcdev.creator.step.LicenseStep import com.demonwav.mcdev.creator.step.NewProjectWizardChainStep.Companion.nextStep import com.demonwav.mcdev.creator.step.UseMixinsStep import com.demonwav.mcdev.util.MinecraftTemplates @@ -48,7 +50,7 @@ import com.intellij.util.lang.JavaVersion import java.util.Locale -private val fg5WrapperVersion = SemanticVersion.release(7, 5, 1) +private val fg6WrapperVersion = SemanticVersion.release(8, 1, 1) const val MAGIC_RUN_CONFIGS_FILE = ".hello_from_mcdev" @@ -78,19 +80,33 @@ val buildSystemProps = findStep>() val javaVersion = context.projectJdk.versionString?.let(JavaVersion::parse) val authors = data.getUserData(AuthorsStep.KEY) ?: emptyList() + val description = data.getUserData(DescriptionStep.KEY) ?: return + val license = data.getUserData(LicenseStep.KEY) ?: return val useMixins = data.getUserData(UseMixinsStep.KEY) ?: false + val mcNextVersionPart = mcVersion.parts[1] + val mcNextVersion = if (mcNextVersionPart is SemanticVersion.Companion.VersionPart.ReleasePart) { + SemanticVersion.release(1, mcNextVersionPart.version + 1) + } else { + mcVersion + } - data.putUserData(GRADLE_VERSION_KEY, fg5WrapperVersion) + data.putUserData(GRADLE_VERSION_KEY, fg6WrapperVersion) assets.addTemplateProperties( "MOD_NAME" to modName, + "MC_VERSION" to mcVersion, "MCP_CHANNEL" to "official", "MCP_VERSION" to mcVersion, "MCP_MC_VERSION" to mcVersion, - "FORGE_VERSION" to "$mcVersion-$forgeVersion", + "MC_NEXT_VERSION" to mcNextVersion, + "FORGE_VERSION" to forgeVersion, + "FORGE_SPEC_VERSION" to forgeVersion.parts[0].versionString, "GROUP_ID" to buildSystemProps.groupId, "ARTIFACT_ID" to buildSystemProps.artifactId, "MOD_VERSION" to buildSystemProps.version, + "DESCRIPTION" to description, + "AUTHOR_LIST" to authors.joinToString(", "), + "LICENSE" to license.id, "HAS_DATA" to "true", ) @@ -98,10 +114,6 @@ assets.addTemplateProperties("JAVA_VERSION" to javaVersion.feature) } - if (authors.isNotEmpty()) { - assets.addTemplateProperties("AUTHOR_LIST" to authors.joinToString(", ")) - } - if (useMixins) { assets.addTemplateProperties("MIXINS" to "true") } Index: src/main/kotlin/platform/forge/util/ForgePackDescriptor.kt =================================================================== --- src/main/kotlin/platform/forge/util/ForgePackDescriptor.kt (revision ac35e7d53524e24c145ac9fe9206bb2295e1b38d) +++ src/main/kotlin/platform/forge/util/ForgePackDescriptor.kt (revision 2618fdcef723942477bfd618ed925109ec203a6b) @@ -50,8 +50,9 @@ val FORMAT_7 = ForgePackDescriptor(7, "") val FORMAT_8 = ForgePackDescriptor(8, "") val FORMAT_9 = ForgePackDescriptor(9, "") + val FORMAT_10 = ForgePackDescriptor(10, "") val FORMAT_12 = ForgePackDescriptor(12, "") - val FORMAT_13 = ForgePackDescriptor(13, "") + val FORMAT_15 = ForgePackDescriptor(15, "") // See https://minecraft.gamepedia.com/Tutorials/Creating_a_resource_pack#.22pack_format.22 fun forMcVersion(version: SemanticVersion): ForgePackDescriptor? = when { @@ -60,10 +61,11 @@ version <= MinecraftVersions.MC1_16_1 -> FORMAT_5 version < MinecraftVersions.MC1_17 -> FORMAT_6 version < MinecraftVersions.MC1_18 -> FORMAT_7 - version < MinecraftVersions.MC1_19 -> FORMAT_8 - version < MinecraftVersions.MC1_19_3 -> FORMAT_9 - version < MinecraftVersions.MC1_19_4 -> FORMAT_12 - version >= MinecraftVersions.MC1_19_4 -> FORMAT_13 + version < MinecraftVersions.MC1_18_2 -> FORMAT_8 + version < MinecraftVersions.MC1_19 -> FORMAT_9 + version < MinecraftVersions.MC1_19_3 -> FORMAT_10 + version < MinecraftVersions.MC1_20 -> FORMAT_12 + version >= MinecraftVersions.MC1_20 -> FORMAT_15 else -> null } } Index: src/main/kotlin/platform/velocity/creator/gradle-steps.kt =================================================================== --- src/main/kotlin/platform/velocity/creator/gradle-steps.kt (revision ac35e7d53524e24c145ac9fe9206bb2295e1b38d) +++ src/main/kotlin/platform/velocity/creator/gradle-steps.kt (revision 2618fdcef723942477bfd618ed925109ec203a6b) @@ -79,7 +79,7 @@ "PACKAGE" to mainPackage, ) - val buildConstantsJava = "src/main/java/${mainPackage.replace('.', '/')}/BuildConstants.java" + val buildConstantsJava = "src/main/templates/${mainPackage.replace('.', '/')}/BuildConstants.java" assets.addTemplates( project, "build.gradle" to MinecraftTemplates.VELOCITY_BUILD_GRADLE_TEMPLATE, Index: src/main/kotlin/util/MinecraftTemplates.kt =================================================================== --- src/main/kotlin/util/MinecraftTemplates.kt (revision ac35e7d53524e24c145ac9fe9206bb2295e1b38d) +++ src/main/kotlin/util/MinecraftTemplates.kt (revision 2618fdcef723942477bfd618ed925109ec203a6b) @@ -86,6 +86,7 @@ forgeGroup.addTemplate(FileTemplateDescriptor(FG3_1_18_MAIN_CLASS_TEMPLATE)) forgeGroup.addTemplate(FileTemplateDescriptor(FG3_1_19_MAIN_CLASS_TEMPLATE)) forgeGroup.addTemplate(FileTemplateDescriptor(FG3_1_19_3_MAIN_CLASS_TEMPLATE)) + forgeGroup.addTemplate(FileTemplateDescriptor(FG3_1_20_MAIN_CLASS_TEMPLATE)) forgeGroup.addTemplate(FileTemplateDescriptor(FG3_BUILD_GRADLE_TEMPLATE)) forgeGroup.addTemplate(FileTemplateDescriptor(FG3_GRADLE_PROPERTIES_TEMPLATE)) forgeGroup.addTemplate(FileTemplateDescriptor(FG3_SETTINGS_GRADLE_TEMPLATE)) @@ -202,6 +203,7 @@ const val FG3_1_18_MAIN_CLASS_TEMPLATE = "Forge (1.18+) Main Class.java" const val FG3_1_19_MAIN_CLASS_TEMPLATE = "Forge (1.19+) Main Class.java" const val FG3_1_19_3_MAIN_CLASS_TEMPLATE = "Forge (1.19.3+) Main Class.java" + const val FG3_1_20_MAIN_CLASS_TEMPLATE = "Forge (1.20+) Main Class.java" const val FG3_BUILD_GRADLE_TEMPLATE = "Forge (1.13+) build.gradle" const val FG3_GRADLE_PROPERTIES_TEMPLATE = "Forge (1.13+) gradle.properties" const val FG3_SETTINGS_GRADLE_TEMPLATE = "Forge (1.13+) settings.gradle" Index: src/main/kotlin/util/MinecraftVersions.kt =================================================================== --- src/main/kotlin/util/MinecraftVersions.kt (revision ac35e7d53524e24c145ac9fe9206bb2295e1b38d) +++ src/main/kotlin/util/MinecraftVersions.kt (revision 2618fdcef723942477bfd618ed925109ec203a6b) @@ -30,9 +30,11 @@ val MC1_17 = SemanticVersion.release(1, 17) val MC1_17_1 = SemanticVersion.release(1, 17, 1) val MC1_18 = SemanticVersion.release(1, 18) + val MC1_18_2 = SemanticVersion.release(1, 18, 2) val MC1_19 = SemanticVersion.release(1, 19) val MC1_19_3 = SemanticVersion.release(1, 19, 3) val MC1_19_4 = SemanticVersion.release(1, 19, 4) + val MC1_20 = SemanticVersion.release(1, 20) fun requiredJavaVersion(minecraftVersion: SemanticVersion) = when { minecraftVersion <= MC1_16_5 -> JavaSdkVersion.JDK_1_8 Index: src/main/resources/fileTemplates/j2ee/forge/Forge (1.13+) build.gradle.ft =================================================================== --- src/main/resources/fileTemplates/j2ee/forge/Forge (1.13+) build.gradle.ft (revision ac35e7d53524e24c145ac9fe9206bb2295e1b38d) +++ src/main/resources/fileTemplates/j2ee/forge/Forge (1.13+) build.gradle.ft (revision 2618fdcef723942477bfd618ed925109ec203a6b) @@ -12,18 +12,23 @@ #end plugins { - id 'net.minecraftforge.gradle' version '5.1.+' + id 'eclipse' + id 'idea' + id 'net.minecraftforge.gradle' version '[6.0,6.2)' } #if (${MIXINS}) apply plugin: 'org.spongepowered.mixin' #end -group = '${GROUP_ID}' -version = '${MOD_VERSION}' +group = mod_version +version = mod_group_id +base { + archivesName = mod_id +} + java { - archivesBaseName = '${ARTIFACT_ID}' toolchain.languageVersion = JavaLanguageVersion.of(${JAVA_VERSION}) } @@ -41,12 +46,32 @@ // // Use non-default mappings at your own risk. They may not always work. // Simply re-run your setup task after changing the mappings to update your workspace. -#if(${MCP_CHANNEL} == "stable" || ${MCP_CHANNEL} == "snapshot") - mappings channel: '${MCP_CHANNEL}', version: '${MCP_VERSION}-${MCP_MC_VERSION}' -#else - mappings channel: '${MCP_CHANNEL}', version: '${MCP_VERSION}' -#end + mappings channel: mapping_channel, version: mapping_version + // When true, this property will have all Eclipse run configurations run the "prepareX" task for the given run configuration before launching the game. + // In most cases, it is not necessary to enable. + // enableEclipsePrepareRuns = true + + // When true, this property will have all IntelliJ IDEA run configurations run the "prepareX" task for the given run configuration before launching the game. + // In most cases, it is not necessary to enable. + // enableIdeaPrepareRuns = true + + // This property allows configuring Gradle's ProcessResources task(s) to run on IDE output locations before launching the game. + // It is REQUIRED to be set to true for this template to function. + // See https://docs.gradle.org/current/dsl/org.gradle.language.jvm.tasks.ProcessResources.html + copyIdeResources = true + + // When true, this property will add the folder name of all declared run configurations to generated IDE run configurations. + // The folder name can be set on a run configuration using the "folderName" property. + // By default, the folder name of a run configuration is the name of the Gradle project containing it. + // generateRunFolders = true + + // This property enables access transformers for use in development. + // They will be applied to the Minecraft artifact. + // The access transformer file can be anywhere in the project. + // However, it must be at "META-INF/accesstransformer.cfg" in the final mod jar to be loaded by Forge. + // This default location is a best practice to automatically put the file in the right place in the final jar. + // See https://docs.minecraftforge.net/en/latest/advanced/accesstransformers/ for more information. // accessTransformer = file('src/main/resources/META-INF/accesstransformer.cfg') // Default run configurations. @@ -70,11 +95,11 @@ #if (${GAME_TEST_FRAMEWORK}) // Comma-separated list of namespaces to load gametests from. Empty = all namespaces. - property 'forge.enabledGameTestNamespaces', '${ARTIFACT_ID}' + property 'forge.enabledGameTestNamespaces', mod_id #end mods { - ${MOD_NAME} { + "${mod_id}" { source sourceSets.main } } @@ -88,11 +113,11 @@ property 'forge.logging.console.level', 'debug' #if (${GAME_TEST_FRAMEWORK}) - property 'forge.enabledGameTestNamespaces', '${ARTIFACT_ID}' + property 'forge.enabledGameTestNamespaces', mod_id #end mods { - ${MOD_NAME} { + "${mod_id}" { source sourceSets.main } } @@ -109,10 +134,10 @@ property 'forge.logging.console.level', 'debug' - property 'forge.enabledGameTestNamespaces', '${ARTIFACT_ID}' + property 'forge.enabledGameTestNamespaces', mod_id mods { - ${MOD_NAME} { + "${mod_id}" { source sourceSets.main } } @@ -128,10 +153,10 @@ property 'forge.logging.console.level', 'debug' // Specify the modid for data generation, where to output the resulting resource, and where to look for existing resources. - args '--mod', '${MOD_NAME}', '--all', '--output', file('src/generated/resources/'), '--existing', file('src/main/resources/') + args '--mod', mod_id, '--all', '--output', file('src/generated/resources/'), '--existing', file('src/main/resources/') mods { - ${MOD_NAME} { + "${mod_id}" { source sourceSets.main } } @@ -142,9 +167,9 @@ #if (${MIXINS}) mixin { - add sourceSets.main, "${ARTIFACT_ID}.refmap.json" + add sourceSets.main, "${mod_id}.refmap.json" - config "${ARTIFACT_ID}.mixins.json" + config "${mod_id}.mixins.json" } #end @@ -155,27 +180,33 @@ // Put repositories for dependencies here // ForgeGradle automatically adds the Forge maven and Maven Central for you - // If you have mod jar dependencies in ./libs, you can declare them as a repository like so: + // If you have mod jar dependencies in ./libs, you can declare them as a repository like so. + // See https://docs.gradle.org/current/userguide/declaring_repositories.html#sub:flat_dir_resolver // flatDir { // dir 'libs' // } } dependencies { - // Specify the version of Minecraft to use. If this is any group other than 'net.minecraft' it is assumed - // that the dep is a ForgeGradle 'patcher' dependency, and its patches will be applied. - // The userdev artifact is a special name and will get all sorts of transformations applied to it. - minecraft 'net.minecraftforge:forge:${FORGE_VERSION}' + // Specify the version of Minecraft to use. + // Any artifact can be supplied so long as it has a "userdev" classifier artifact and is a compatible patcher artifact. + // The "userdev" classifier will be requested and setup by ForgeGradle. + // If the group id is "net.minecraft" and the artifact id is one of ["client", "server", "joined"], + // then special handling is done to allow a setup of a vanilla dependency without the use of an external repository. + minecraft "net.minecraftforge:forge:${minecraft_version}-${forge_version}" - // Real mod deobf dependency examples - these get remapped to your current mappings - // compileOnly fg.deobf("mezz.jei:jei-${mc_version}:${jei_version}:api") // Adds JEI API as a compile dependency - // runtimeOnly fg.deobf("mezz.jei:jei-${mc_version}:${jei_version}") // Adds the full JEI mod as a runtime dependency - // implementation fg.deobf("com.tterrag.registrate:Registrate:MC${mc_version}-${registrate_version}") // Adds registrate as a dependency + // Example mod dependency with JEI - using fg.deobf() ensures the dependency is remapped to your development mappings + // The JEI API is declared for compile time use, while the full JEI artifact is used at runtime + // compileOnly fg.deobf("mezz.jei:jei-${mc_version}-common-api:${jei_version}") + // compileOnly fg.deobf("mezz.jei:jei-${mc_version}-forge-api:${jei_version}") + // runtimeOnly fg.deobf("mezz.jei:jei-${mc_version}-forge:${jei_version}") - // Examples using mod jars from ./libs + // Example mod dependency using a mod jar from ./libs with a flat dir repository + // This maps to ./libs/coolmod-${mc_version}-${coolmod_version}.jar + // The group id is ignored when searching -- in this case, it is "blank" // implementation fg.deobf("blank:coolmod-${mc_version}:${coolmod_version}") - // For more info... + // For more info: // http://www.gradle.org/docs/current/userguide/artifact_dependencies_tutorial.html // http://www.gradle.org/docs/current/userguide/dependency_management.html #if (${MIXINS}) @@ -184,24 +215,37 @@ #end } +// This block of code expands all declared replace properties in the specified resource targets. +// A missing property will result in an error. Properties are expanded using ${} Groovy notation. +// When "copyIdeResources" is enabled, this will also run before the game launches in IDE environments. +// See https://docs.gradle.org/current/dsl/org.gradle.language.jvm.tasks.ProcessResources.html +def resourceTargets = ['META-INF/mods.toml', 'pack.mcmeta'] +def replaceProperties = [ + minecraft_version: minecraft_version, minecraft_version_range: minecraft_version_range, + forge_version: forge_version, forge_version_range: forge_version_range, + loader_version_range: loader_version_range, + mod_id: mod_id, mod_name: mod_name, mod_license: mod_license, mod_version: mod_version, + mod_authors: mod_authors, mod_description: mod_description +] +processResources { + inputs.properties replaceProperties + replaceProperties.put 'project', project + + filesMatching(resourceTargets) { + expand replaceProperties + } +} + // Example for how to get properties into the manifest for reading at runtime. jar { manifest { attributes([ - "Specification-Title": "${MOD_NAME}", - #if (${AUTHOR_LIST}) - "Specification-Vendor": "${AUTHOR_LIST}", - #else - //"Specification-Vendor": "${MOD_NAME} authors", - #end + "Specification-Title": mod_id, + "Specification-Vendor": mod_authors, "Specification-Version": "1", // We are version 1 of ourselves "Implementation-Title": project.name, "Implementation-Version": project.jar.archiveVersion, - #if (${AUTHOR_LIST}) - "Implementation-Vendor": "${AUTHOR_LIST}", - #else - //"Implementation-Vendor": "${MOD_NAME} authors", - #end + "Implementation-Vendor": mod_authors, "Implementation-Timestamp": new Date().format("yyyy-MM-dd'T'HH:mm:ssZ") ]) } Index: src/main/resources/fileTemplates/j2ee/forge/Forge (1.13+) gradle.properties.ft =================================================================== --- src/main/resources/fileTemplates/j2ee/forge/Forge (1.13+) gradle.properties.ft (revision ac35e7d53524e24c145ac9fe9206bb2295e1b38d) +++ src/main/resources/fileTemplates/j2ee/forge/Forge (1.13+) gradle.properties.ft (revision 2618fdcef723942477bfd618ed925109ec203a6b) @@ -1,2 +1,55 @@ org.gradle.jvmargs=-Xmx3G org.gradle.daemon=false + +## Environment Properties + +# The Minecraft version must agree with the Forge version to get a valid artifact +minecraft_version=${MC_VERSION} +# The Minecraft version range can use any release version of Minecraft as bounds. +# Snapshots, pre-releases, and release candidates are not guaranteed to sort properly +# as they do not follow standard versioning conventions. +minecraft_version_range=[${MC_VERSION},${MC_NEXT_VERSION}) +# The Forge version must agree with the Minecraft version to get a valid artifact +forge_version=${FORGE_VERSION} +# The Forge version range can use any version of Forge as bounds or match the loader version range +forge_version_range=[${FORGE_SPEC_VERSION},) +# The loader version range can only use the major version of Forge/FML as bounds +loader_version_range=[${FORGE_SPEC_VERSION},) +# The mapping channel to use for mappings. +# The default set of supported mapping channels are ["official", "snapshot", "snapshot_nodoc", "stable", "stable_nodoc"]. +# Additional mapping channels can be registered through the "channelProviders" extension in a Gradle plugin. +# +# | Channel | Version | | +# |-----------|----------------------|--------------------------------------------------------------------------------| +# | official | MCVersion | Official field/method names from Mojang mapping files | +# | parchment | YYYY.MM.DD-MCVersion | Open community-sourced parameter names and javadocs layered on top of official | +# +# You must be aware of the Mojang license when using the 'official' or 'parchment' mappings. +# See more information here: https://github.com/MinecraftForge/MCPConfig/blob/master/Mojang.md +# +# Parchment is an unofficial project maintained by ParchmentMC, separate from Minecraft Forge. +# Additional setup is needed to use their mappings, see https://parchmentmc.org/docs/getting-started +mapping_channel=${MCP_CHANNEL} +# The mapping version to query from the mapping channel. +# This must match the format required by the mapping channel. +mapping_version=${MC_VERSION} + +## Mod Properties + +# The unique mod identifier for the mod. Must be lowercase in English locale. Must fit the regex [a-z][a-z0-9_]{1,63} +# Must match the String constant located in the main mod class annotated with @Mod. +mod_id=${ARTIFACT_ID} +# The human-readable display name for the mod. +mod_name=${MOD_NAME} +# The license of the mod. Review your options at https://choosealicense.com/. All Rights Reserved is the default. +mod_license=${LICENSE} +# The mod version. See https://semver.org/ +mod_version=${MOD_VERSION} +# The group ID for the mod. It is only important when publishing as an artifact to a Maven repository. +# This should match the base package used for the mod sources. +# See https://maven.apache.org/guides/mini/guide-naming-conventions.html +mod_group_id=${GROUP_ID} +# The authors of the mod. This is a simple text string that is used for display purposes in the mod list. +mod_authors=${AUTHOR_LIST} +# The description of the mod. This is a simple multiline text string that is used for display purposes in the mod list. +mod_description=${DESCRIPTION} Index: src/main/resources/fileTemplates/j2ee/forge/Forge (1.13+) settings.gradle.ft =================================================================== --- src/main/resources/fileTemplates/j2ee/forge/Forge (1.13+) settings.gradle.ft (revision ac35e7d53524e24c145ac9fe9206bb2295e1b38d) +++ src/main/resources/fileTemplates/j2ee/forge/Forge (1.13+) settings.gradle.ft (revision 2618fdcef723942477bfd618ed925109ec203a6b) @@ -1,8 +1,15 @@ pluginManagement { repositories { gradlePluginPortal() - maven { url = 'https://maven.minecraftforge.net/' } + maven { + name = 'MinecraftForge' + url = 'https://maven.minecraftforge.net/' - } -} + } + } +} +plugins { + id 'org.gradle.toolchains.foojay-resolver-convention' version '0.5.0' +} + rootProject.name = '${ARTIFACT_ID}' Index: src/main/resources/fileTemplates/j2ee/forge/Forge (1.20+) Main Class.java.ft =================================================================== --- src/main/resources/fileTemplates/j2ee/forge/Forge (1.20+) Main Class.java.ft (revision 2618fdcef723942477bfd618ed925109ec203a6b) +++ src/main/resources/fileTemplates/j2ee/forge/Forge (1.20+) Main Class.java.ft (revision 2618fdcef723942477bfd618ed925109ec203a6b) @@ -0,0 +1,113 @@ +package ${PACKAGE_NAME}; + +import com.mojang.logging.LogUtils; +import net.minecraft.client.Minecraft; +import net.minecraft.core.registries.Registries; +import net.minecraft.world.food.FoodProperties; +import net.minecraft.world.item.BlockItem; +import net.minecraft.world.item.CreativeModeTab; +import net.minecraft.world.item.CreativeModeTabs; +import net.minecraft.world.item.Item; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.Blocks; +import net.minecraft.world.level.block.state.BlockBehaviour; +import net.minecraft.world.level.material.MapColor; +import net.minecraftforge.api.distmarker.Dist; +import net.minecraftforge.common.MinecraftForge; +import net.minecraftforge.event.BuildCreativeModeTabContentsEvent; +import net.minecraftforge.event.server.ServerStartingEvent; +import net.minecraftforge.eventbus.api.IEventBus; +import net.minecraftforge.eventbus.api.SubscribeEvent; +import net.minecraftforge.fml.common.Mod; +import net.minecraftforge.fml.event.lifecycle.FMLClientSetupEvent; +import net.minecraftforge.fml.event.lifecycle.FMLCommonSetupEvent; +import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext; +import net.minecraftforge.registries.DeferredRegister; +import net.minecraftforge.registries.ForgeRegistries; +import net.minecraftforge.registries.RegistryObject; +import org.slf4j.Logger; + +// The value here should match an entry in the META-INF/mods.toml file +@Mod(${CLASS_NAME}.MODID) +public class ${CLASS_NAME} { + + // Define mod id in a common place for everything to reference + public static final String MODID = "${ARTIFACT_ID}"; + // Directly reference a slf4j logger + private static final Logger LOGGER = LogUtils.getLogger(); + // Create a Deferred Register to hold Blocks which will all be registered under the "${ARTIFACT_ID}" namespace + public static final DeferredRegister BLOCKS = DeferredRegister.create(ForgeRegistries.BLOCKS, MODID); + // Create a Deferred Register to hold Items which will all be registered under the "${ARTIFACT_ID}" namespace + public static final DeferredRegister ITEMS = DeferredRegister.create(ForgeRegistries.ITEMS, MODID); + // Create a Deferred Register to hold CreativeModeTabs which will all be registered under the "examplemod" namespace + public static final DeferredRegister CREATIVE_MODE_TABS = DeferredRegister.create(Registries.CREATIVE_MODE_TAB, MODID); + + // Creates a new Block with the id "${ARTIFACT_ID}:example_block", combining the namespace and path + public static final RegistryObject EXAMPLE_BLOCK = BLOCKS.register("example_block", () -> new Block(BlockBehaviour.Properties.of().mapColor(MapColor.STONE))); + // Creates a new BlockItem with the id "${ARTIFACT_ID}:example_block", combining the namespace and path + public static final RegistryObject EXAMPLE_BLOCK_ITEM = ITEMS.register("example_block", () -> new BlockItem(EXAMPLE_BLOCK.get(), new Item.Properties())); + + // Creates a new food item with the id "examplemod:example_id", nutrition 1 and saturation 2 + public static final RegistryObject EXAMPLE_ITEM = ITEMS.register("example_item", () -> new Item(new Item.Properties().food(new FoodProperties.Builder() + .alwaysEat().nutrition(1).saturationMod(2f).build()))); + + // Creates a creative tab with the id "examplemod:example_tab" for the example item, that is placed after the combat tab + public static final RegistryObject EXAMPLE_TAB = CREATIVE_MODE_TABS.register("example_tab", () -> CreativeModeTab.builder() + .withTabsBefore(CreativeModeTabs.COMBAT) + .icon(() -> EXAMPLE_ITEM.get().getDefaultInstance()) + .displayItems((parameters, output) -> { + output.accept(EXAMPLE_ITEM.get()); // Add the example item to the tab. For your own tabs, this method is preferred over the event + }).build()); + + public ${CLASS_NAME}() { + IEventBus modEventBus = FMLJavaModLoadingContext.get().getModEventBus(); + + // Register the commonSetup method for modloading + modEventBus.addListener(this::commonSetup); + + // Register the Deferred Register to the mod event bus so blocks get registered + BLOCKS.register(modEventBus); + // Register the Deferred Register to the mod event bus so items get registered + ITEMS.register(modEventBus); + // Register the Deferred Register to the mod event bus so tabs get registered + CREATIVE_MODE_TABS.register(modEventBus); + + // Register ourselves for server and other game events we are interested in + MinecraftForge.EVENT_BUS.register(this); + + // Register the item to a creative tab + modEventBus.addListener(this::addCreative); + } + + private void commonSetup(final FMLCommonSetupEvent event) { + // Some common setup code + LOGGER.info("HELLO FROM COMMON SETUP"); + LOGGER.info("DIRT BLOCK >> {}", ForgeRegistries.BLOCKS.getKey(Blocks.DIRT)); + } + + // Add the example block item to the building blocks tab + private void addCreative(BuildCreativeModeTabContentsEvent event) + { + if (event.getTabKey() == CreativeModeTabs.BUILDING_BLOCKS) + event.accept(EXAMPLE_BLOCK_ITEM); + } + // You can use SubscribeEvent and let the Event Bus discover methods to call + @SubscribeEvent + public void onServerStarting(ServerStartingEvent event) { + // Do something when the server starts + LOGGER.info("HELLO from server starting"); + } + + // You can use EventBusSubscriber to automatically register all static methods in the class annotated with @SubscribeEvent + @Mod.EventBusSubscriber(modid = MODID, bus = Mod.EventBusSubscriber.Bus.MOD, value = Dist.CLIENT) + public static class ClientModEvents { + + @SubscribeEvent + public static void onClientSetup(FMLClientSetupEvent event) + { + // Some client setup code + LOGGER.info("HELLO FROM CLIENT SETUP"); + LOGGER.info("MINECRAFT NAME >> {}", Minecraft.getInstance().getUser().getName()); + } + } +} Index: src/main/resources/fileTemplates/j2ee/forge/Forge (1.20+) Main Class.java.html =================================================================== --- src/main/resources/fileTemplates/j2ee/forge/Forge (1.20+) Main Class.java.html (revision 2618fdcef723942477bfd618ed925109ec203a6b) +++ src/main/resources/fileTemplates/j2ee/forge/Forge (1.20+) Main Class.java.html (revision 2618fdcef723942477bfd618ed925109ec203a6b) @@ -0,0 +1,25 @@ + + + + +

This is a built-in file template used to create a new main class for Forge projects 1.20 and above

+ + Index: src/main/resources/fileTemplates/j2ee/forge/mods.toml.ft =================================================================== --- src/main/resources/fileTemplates/j2ee/forge/mods.toml.ft (revision ac35e7d53524e24c145ac9fe9206bb2295e1b38d) +++ src/main/resources/fileTemplates/j2ee/forge/mods.toml.ft (revision 2618fdcef723942477bfd618ed925109ec203a6b) @@ -6,22 +6,20 @@ # 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="[${FORGE_SPEC_VERSION},)" #mandatory This is typically bumped every Minecraft version by Forge. See our download page for lists of versions. +loaderVersion="${loader_version_range}" #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="${LICENSE}" +license="${mod_license}" # A URL to refer people to when problems occur with this mod #issueTrackerURL="https://change.me.to.your.issue.tracker.example.invalid/" #optional # A list of mods - how many allowed here is determined by the individual mod loader [[mods]] #mandatory # The modid of the mod -modId="${ARTIFACT_ID}" #mandatory -# The version number of the mod - there's a few well known ${} variables useable here or just hardcode it -# ${file.jarVersion} will substitute the value of the Implementation-Version as read from the mod's JAR file metadata -# see the associated build.gradle script for how to populate this completely automatically during a build -version="${file.jarVersion}" #mandatory +modId="${mod_id}" #mandatory +# The version number of the mod +version="${mod_version}" #mandatory # A display name for the mod -displayName="${MOD_NAME}" #mandatory +displayName="${mod_name}" #mandatory # A URL to query for updates for this mod. See the JSON update specification https://docs.minecraftforge.net/en/latest/misc/updatechecker/ #if (${UPDATE_URL}) updateJSONURL="${UPDATE_URL}" #optional @@ -39,11 +37,7 @@ # A text field displayed in the mod UI #credits="Thanks for this example mod goes to Java" #optional # A text field displayed in the mod UI -#if (${AUTHOR_LIST}) -authors="${AUTHOR_LIST}" #optional -#else -#authors="Love, Cheese and small house plants" #optional -#end +authors="${mod_authors}" #optional #if (${DISPLAY_TEST}) # Display Test controls the display for your mod in the server connection screen # MATCH_VERSION means that your mod will cause a red X if the versions on client and server differ. This is the default behaviour and should be what you choose if you have server and client elements to your mod. @@ -55,26 +49,25 @@ #end # The description text for the mod (multi line!) (#mandatory) -description=''' -${DESCRIPTION} -''' +description='''${mod_description}''' # A dependency - use the . to indicate dependency for a specific modid. Dependencies are optional. -[[dependencies.${ARTIFACT_ID}]] #optional +[[dependencies.${mod_id}]] #optional # the modid of the dependency modId="forge" #mandatory # Does this dependency have to exist - if not, ordering below must be specified mandatory=true #mandatory # The version range of the dependency - versionRange="[${FORGE_SPEC_VERSION},)" #mandatory - # An ordering relationship for the dependency - BEFORE or AFTER required if the relationship is not mandatory + versionRange="${forge_version_range}" #mandatory + # An ordering relationship for the dependency - BEFORE or AFTER required if the dependency is not mandatory + # BEFORE - This mod is loaded BEFORE the dependency + # AFTER - This mod is loaded AFTER the dependency ordering="NONE" - # Side this dependency is applied on - BOTH, CLIENT or SERVER - side="BOTH" -# Here's another dependency -[[dependencies.${ARTIFACT_ID}]] + # Side this dependency is applied on - BOTH, CLIENT, or SERVER + side="BOTH"# Here's another dependency +[[dependencies.${mod_id}]] 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="[${MC_VERSION},${MC_NEXT_VERSION})" + versionRange="${minecraft_version_range}" ordering="NONE" side="BOTH"