Skip to content

Commit b7276ac

Browse files
committed
Minecraft 1.21 templates
1 parent efcfd5d commit b7276ac

14 files changed

+350
-3
lines changed

src/main/kotlin/platform/bungeecord/creator/bungee-platforms.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@ import com.demonwav.mcdev.util.SemanticVersion
2828
class BungeeMainPlatformStep(parent: BungeePlatformStep) : AbstractBungeePlatformStep(parent, PlatformType.BUNGEECORD) {
2929
override fun getRepositories(mcVersion: SemanticVersion) = listOf(
3030
BuildRepository("sonatype", "https://oss.sonatype.org/content/groups/public/"),
31+
// Seems to be required since 1.21
32+
BuildRepository("Minecraft Libraries", "https://libraries.minecraft.net/"),
3133
)
3234

3335
override fun getDependencies(mcVersion: SemanticVersion) = listOf(

src/main/kotlin/platform/forge/creator/asset-steps.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,7 @@ class ForgeProjectFilesStep(parent: NewProjectWizardStep) : AbstractLongRunningA
108108
}
109109

110110
val mainClassTemplate = when {
111+
mcVersion >= MinecraftVersions.MC1_20_6 -> MinecraftTemplates.FG3_1_20_6_MAIN_CLASS_TEMPLATE
111112
mcVersion >= MinecraftVersions.MC1_20 -> MinecraftTemplates.FG3_1_20_MAIN_CLASS_TEMPLATE
112113
mcVersion >= MinecraftVersions.MC1_19_3 -> MinecraftTemplates.FG3_1_19_3_MAIN_CLASS_TEMPLATE
113114
mcVersion >= MinecraftVersions.MC1_19 -> MinecraftTemplates.FG3_1_19_MAIN_CLASS_TEMPLATE
@@ -124,6 +125,7 @@ class ForgeProjectFilesStep(parent: NewProjectWizardStep) : AbstractLongRunningA
124125
)
125126

126127
val configTemplate = when {
128+
mcVersion >= MinecraftVersions.MC1_21 -> MinecraftTemplates.FG3_1_21_CONFIG_TEMPLATE
127129
mcVersion >= MinecraftVersions.MC1_20 -> MinecraftTemplates.FG3_1_20_CONFIG_TEMPLATE
128130
else -> null
129131
}

src/main/kotlin/platform/forge/util/ForgePackDescriptor.kt

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,8 @@ data class ForgePackDescriptor(val format: Int, val comment: String) {
5555
val FORMAT_15 = ForgePackDescriptor(15, "")
5656
val FORMAT_18 = ForgePackDescriptor(18, "")
5757
val FORMAT_26 = ForgePackDescriptor(26, "")
58-
val FORMAT_41 = ForgePackDescriptor(26, "")
58+
val FORMAT_41 = ForgePackDescriptor(41, "")
59+
val FORMAT_48 = ForgePackDescriptor(48, "")
5960

6061
// See https://minecraft.gamepedia.com/Tutorials/Creating_a_resource_pack#.22pack_format.22
6162
fun forMcVersion(version: SemanticVersion): ForgePackDescriptor? = when {
@@ -71,7 +72,8 @@ data class ForgePackDescriptor(val format: Int, val comment: String) {
7172
version < MinecraftVersions.MC1_20_2 -> FORMAT_15
7273
version < MinecraftVersions.MC1_20_3 -> FORMAT_18
7374
version < MinecraftVersions.MC1_20_5 -> FORMAT_26
74-
version >= MinecraftVersions.MC1_20_5 -> FORMAT_41
75+
version < MinecraftVersions.MC1_21 -> FORMAT_41
76+
version >= MinecraftVersions.MC1_21 -> FORMAT_48
7577
else -> null
7678
}
7779
}

src/main/kotlin/platform/neoforge/creator/asset-steps.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,7 @@ class NeoForgeProjectFilesStep(parent: NewProjectWizardStep) : AbstractLongRunni
122122
)
123123

124124
val configClassTemplate = when {
125+
mcVersion >= MinecraftVersions.MC1_21 -> MinecraftTemplates.NEOFORGE_1_21_CONFIG_TEMPLATE
125126
mcVersion >= MinecraftVersions.MC1_20_5 -> MinecraftTemplates.NEOFORGE_1_20_5_CONFIG_TEMPLATE
126127
else -> MinecraftTemplates.NEOFORGE_CONFIG_TEMPLATE
127128
}

src/main/kotlin/platform/neoforge/creator/gradle-steps.kt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,10 @@ class NeoForgeGradleFilesStep(parent: NewProjectWizardStep) : AbstractLongRunnin
8787
} else {
8888
mcVersion
8989
}
90+
val loaderVersion = when {
91+
mcVersion < MinecraftVersions.MC1_21 -> "2"
92+
else -> "4"
93+
}
9094

9195
data.putUserData(GRADLE_VERSION_KEY, ngWrapperVersion)
9296

@@ -97,6 +101,7 @@ class NeoForgeGradleFilesStep(parent: NewProjectWizardStep) : AbstractLongRunnin
97101
"MC_NEXT_VERSION" to mcNextVersion,
98102
"NEOFORGE_VERSION" to neoforgeVersion,
99103
"NEOFORGE_SPEC_VERSION" to neoforgeVersion.parts[0].versionString,
104+
"LOADER_VERSION" to loaderVersion,
100105
"NEOGRADLE_VERSION" to neogradleVersion,
101106
"GROUP_ID" to buildSystemProps.groupId,
102107
"ARTIFACT_ID" to buildSystemProps.artifactId,

src/main/kotlin/util/MinecraftTemplates.kt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,9 @@ class MinecraftTemplates : FileTemplateGroupDescriptorFactory {
8787
forgeGroup.addTemplate(FileTemplateDescriptor(FG3_1_19_MAIN_CLASS_TEMPLATE))
8888
forgeGroup.addTemplate(FileTemplateDescriptor(FG3_1_19_3_MAIN_CLASS_TEMPLATE))
8989
forgeGroup.addTemplate(FileTemplateDescriptor(FG3_1_20_MAIN_CLASS_TEMPLATE))
90+
forgeGroup.addTemplate(FileTemplateDescriptor(FG3_1_20_6_MAIN_CLASS_TEMPLATE))
9091
forgeGroup.addTemplate(FileTemplateDescriptor(FG3_1_20_CONFIG_TEMPLATE))
92+
forgeGroup.addTemplate(FileTemplateDescriptor(FG3_1_21_CONFIG_TEMPLATE))
9193
forgeGroup.addTemplate(FileTemplateDescriptor(FG3_BUILD_GRADLE_TEMPLATE))
9294
forgeGroup.addTemplate(FileTemplateDescriptor(FG3_GRADLE_PROPERTIES_TEMPLATE))
9395
forgeGroup.addTemplate(FileTemplateDescriptor(FG3_SETTINGS_GRADLE_TEMPLATE))
@@ -214,7 +216,9 @@ class MinecraftTemplates : FileTemplateGroupDescriptorFactory {
214216
const val FG3_1_19_MAIN_CLASS_TEMPLATE = "Forge (1.19+) Main Class.java"
215217
const val FG3_1_19_3_MAIN_CLASS_TEMPLATE = "Forge (1.19.3+) Main Class.java"
216218
const val FG3_1_20_MAIN_CLASS_TEMPLATE = "Forge (1.20+) Main Class.java"
219+
const val FG3_1_20_6_MAIN_CLASS_TEMPLATE = "Forge (1.20.6+) Main Class.java"
217220
const val FG3_1_20_CONFIG_TEMPLATE = "Forge (1.20+) Config.java"
221+
const val FG3_1_21_CONFIG_TEMPLATE = "Forge (1.21+) Config.java"
218222
const val FG3_BUILD_GRADLE_TEMPLATE = "Forge (1.13+) build.gradle"
219223
const val FG3_GRADLE_PROPERTIES_TEMPLATE = "Forge (1.13+) gradle.properties"
220224
const val FG3_SETTINGS_GRADLE_TEMPLATE = "Forge (1.13+) settings.gradle"
@@ -282,6 +286,8 @@ class MinecraftTemplates : FileTemplateGroupDescriptorFactory {
282286
const val NEOFORGE_1_20_5_CONFIG_TEMPLATE = "NeoForge (1.20.5) Config.java"
283287
const val NEOFORGE_1_20_5_BUILD_GRADLE_TEMPLATE = "NeoForge (1.20.5) build.gradle"
284288

289+
const val NEOFORGE_1_21_CONFIG_TEMPLATE = "NeoForge (1.21) Config.java"
290+
285291
const val NEOFORGE_BLOCK_TEMPLATE = "NeoForgeBlock.java"
286292
const val NEOFORGE_ITEM_TEMPLATE = "NeoForgeItem.java"
287293
const val NEOFORGE_PACKET_TEMPLATE = "NeoForgePacket.java"

src/main/kotlin/util/MinecraftVersions.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,8 @@ object MinecraftVersions {
3939
val MC1_20_3 = SemanticVersion.release(1, 20, 3)
4040
val MC1_20_4 = SemanticVersion.release(1, 20, 4)
4141
val MC1_20_5 = SemanticVersion.release(1, 20, 5)
42+
val MC1_20_6 = SemanticVersion.release(1, 20, 6)
43+
val MC1_21 = SemanticVersion.release(1, 21)
4244

4345
fun requiredJavaVersion(minecraftVersion: SemanticVersion) = when {
4446
minecraftVersion <= MC1_16_5 -> JavaSdkVersion.JDK_1_8
Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
package ${PACKAGE_NAME};
2+
3+
import com.mojang.logging.LogUtils;
4+
import net.minecraft.client.Minecraft;
5+
import net.minecraft.core.registries.Registries;
6+
import net.minecraft.world.food.FoodProperties;
7+
import net.minecraft.world.item.BlockItem;
8+
import net.minecraft.world.item.CreativeModeTab;
9+
import net.minecraft.world.item.CreativeModeTabs;
10+
import net.minecraft.world.item.Item;
11+
import net.minecraft.world.level.block.Block;
12+
import net.minecraft.world.level.block.Blocks;
13+
import net.minecraft.world.level.block.state.BlockBehaviour;
14+
import net.minecraft.world.level.material.MapColor;
15+
import net.minecraftforge.api.distmarker.Dist;
16+
import net.minecraftforge.common.MinecraftForge;
17+
import net.minecraftforge.event.BuildCreativeModeTabContentsEvent;
18+
import net.minecraftforge.event.server.ServerStartingEvent;
19+
import net.minecraftforge.eventbus.api.IEventBus;
20+
import net.minecraftforge.eventbus.api.SubscribeEvent;
21+
import net.minecraftforge.fml.ModLoadingContext;
22+
import net.minecraftforge.fml.common.Mod;
23+
import net.minecraftforge.fml.config.ModConfig;
24+
import net.minecraftforge.fml.event.lifecycle.FMLClientSetupEvent;
25+
import net.minecraftforge.fml.event.lifecycle.FMLCommonSetupEvent;
26+
import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext;
27+
import net.minecraftforge.registries.DeferredRegister;
28+
import net.minecraftforge.registries.ForgeRegistries;
29+
import net.minecraftforge.registries.RegistryObject;
30+
import org.slf4j.Logger;
31+
32+
// The value here should match an entry in the META-INF/mods.toml file
33+
@Mod(${CLASS_NAME}.MODID)
34+
public class ${CLASS_NAME} {
35+
36+
// Define mod id in a common place for everything to reference
37+
public static final String MODID = "${MOD_ID}";
38+
// Directly reference a slf4j logger
39+
private static final Logger LOGGER = LogUtils.getLogger();
40+
// Create a Deferred Register to hold Blocks which will all be registered under the "${MOD_ID}" namespace
41+
public static final DeferredRegister<Block> BLOCKS = DeferredRegister.create(ForgeRegistries.BLOCKS, MODID);
42+
// Create a Deferred Register to hold Items which will all be registered under the "${MOD_ID}" namespace
43+
public static final DeferredRegister<Item> ITEMS = DeferredRegister.create(ForgeRegistries.ITEMS, MODID);
44+
// Create a Deferred Register to hold CreativeModeTabs which will all be registered under the "examplemod" namespace
45+
public static final DeferredRegister<CreativeModeTab> CREATIVE_MODE_TABS = DeferredRegister.create(Registries.CREATIVE_MODE_TAB, MODID);
46+
47+
// Creates a new Block with the id "${MOD_ID}:example_block", combining the namespace and path
48+
public static final RegistryObject<Block> EXAMPLE_BLOCK = BLOCKS.register("example_block", () -> new Block(BlockBehaviour.Properties.of().mapColor(MapColor.STONE)));
49+
// Creates a new BlockItem with the id "${MOD_ID}:example_block", combining the namespace and path
50+
public static final RegistryObject<Item> EXAMPLE_BLOCK_ITEM = ITEMS.register("example_block", () -> new BlockItem(EXAMPLE_BLOCK.get(), new Item.Properties()));
51+
52+
// Creates a new food item with the id "examplemod:example_id", nutrition 1 and saturation 2
53+
public static final RegistryObject<Item> EXAMPLE_ITEM = ITEMS.register("example_item", () -> new Item(new Item.Properties().food(new FoodProperties.Builder()
54+
.alwaysEdible().nutrition(1).saturationModifier(2f).build())));
55+
56+
// Creates a creative tab with the id "examplemod:example_tab" for the example item, that is placed after the combat tab
57+
public static final RegistryObject<CreativeModeTab> EXAMPLE_TAB = CREATIVE_MODE_TABS.register("example_tab", () -> CreativeModeTab.builder()
58+
.withTabsBefore(CreativeModeTabs.COMBAT)
59+
.icon(() -> EXAMPLE_ITEM.get().getDefaultInstance())
60+
.displayItems((parameters, output) -> {
61+
output.accept(EXAMPLE_ITEM.get()); // Add the example item to the tab. For your own tabs, this method is preferred over the event
62+
}).build());
63+
64+
public ${CLASS_NAME}() {
65+
IEventBus modEventBus = FMLJavaModLoadingContext.get().getModEventBus();
66+
67+
// Register the commonSetup method for modloading
68+
modEventBus.addListener(this::commonSetup);
69+
70+
// Register the Deferred Register to the mod event bus so blocks get registered
71+
BLOCKS.register(modEventBus);
72+
// Register the Deferred Register to the mod event bus so items get registered
73+
ITEMS.register(modEventBus);
74+
// Register the Deferred Register to the mod event bus so tabs get registered
75+
CREATIVE_MODE_TABS.register(modEventBus);
76+
77+
// Register ourselves for server and other game events we are interested in
78+
MinecraftForge.EVENT_BUS.register(this);
79+
80+
// Register the item to a creative tab
81+
modEventBus.addListener(this::addCreative);
82+
83+
// Register our mod's ForgeConfigSpec so that Forge can create and load the config file for us
84+
ModLoadingContext.get().registerConfig(ModConfig.Type.COMMON, Config.SPEC);
85+
}
86+
87+
private void commonSetup(final FMLCommonSetupEvent event) {
88+
// Some common setup code
89+
LOGGER.info("HELLO FROM COMMON SETUP");
90+
LOGGER.info("DIRT BLOCK >> {}", ForgeRegistries.BLOCKS.getKey(Blocks.DIRT));
91+
92+
if (Config.logDirtBlock)
93+
LOGGER.info("DIRT BLOCK >> {}", ForgeRegistries.BLOCKS.getKey(Blocks.DIRT));
94+
95+
LOGGER.info(Config.magicNumberIntroduction + Config.magicNumber);
96+
97+
Config.items.forEach((item) -> LOGGER.info("ITEM >> {}", item.toString()));
98+
}
99+
100+
// Add the example block item to the building blocks tab
101+
private void addCreative(BuildCreativeModeTabContentsEvent event)
102+
{
103+
if (event.getTabKey() == CreativeModeTabs.BUILDING_BLOCKS)
104+
event.accept(EXAMPLE_BLOCK_ITEM);
105+
}
106+
// You can use SubscribeEvent and let the Event Bus discover methods to call
107+
@SubscribeEvent
108+
public void onServerStarting(ServerStartingEvent event) {
109+
// Do something when the server starts
110+
LOGGER.info("HELLO from server starting");
111+
}
112+
113+
// You can use EventBusSubscriber to automatically register all static methods in the class annotated with @SubscribeEvent
114+
@Mod.EventBusSubscriber(modid = MODID, bus = Mod.EventBusSubscriber.Bus.MOD, value = Dist.CLIENT)
115+
public static class ClientModEvents {
116+
117+
@SubscribeEvent
118+
public static void onClientSetup(FMLClientSetupEvent event)
119+
{
120+
// Some client setup code
121+
LOGGER.info("HELLO FROM CLIENT SETUP");
122+
LOGGER.info("MINECRAFT NAME >> {}", Minecraft.getInstance().getUser().getName());
123+
}
124+
}
125+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
<!--
2+
Minecraft Development for IntelliJ
3+
4+
https://mcdev.io/
5+
6+
Copyright (C) 2024 minecraft-dev
7+
8+
This program is free software: you can redistribute it and/or modify
9+
it under the terms of the GNU Lesser General Public License as published
10+
by the Free Software Foundation, version 3.0 only.
11+
12+
This program is distributed in the hope that it will be useful,
13+
but WITHOUT ANY WARRANTY; without even the implied warranty of
14+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15+
GNU General Public License for more details.
16+
17+
You should have received a copy of the GNU Lesser General Public License
18+
along with this program. If not, see <https://www.gnu.org/licenses/>.
19+
-->
20+
21+
<html>
22+
<body>
23+
<p>This is a built-in file template used to create a new main class for Forge projects 1.20.6 and above</p>
24+
</body>
25+
</html>
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
package ${PACKAGE_NAME};
2+
3+
import net.minecraft.resources.ResourceLocation;
4+
import net.minecraft.world.item.Item;
5+
import net.minecraftforge.common.ForgeConfigSpec;
6+
import net.minecraftforge.eventbus.api.SubscribeEvent;
7+
import net.minecraftforge.fml.common.Mod;
8+
import net.minecraftforge.fml.event.config.ModConfigEvent;
9+
import net.minecraftforge.registries.ForgeRegistries;
10+
11+
import java.util.Collections;
12+
import java.util.List;
13+
import java.util.Set;
14+
import java.util.stream.Collectors;
15+
16+
// An example config class. This is not required, but it's a good idea to have one to keep your config organized.
17+
// Demonstrates how to use Forge's config APIs
18+
@Mod.EventBusSubscriber(modid = ${CLASS_NAME}.MODID, bus = Mod.EventBusSubscriber.Bus.MOD)
19+
public class Config
20+
{
21+
private static final ForgeConfigSpec.Builder BUILDER = new ForgeConfigSpec.Builder();
22+
23+
private static final ForgeConfigSpec.BooleanValue LOG_DIRT_BLOCK = BUILDER
24+
.comment("Whether to log the dirt block on common setup")
25+
.define("logDirtBlock", true);
26+
27+
private static final ForgeConfigSpec.IntValue MAGIC_NUMBER = BUILDER
28+
.comment("A magic number")
29+
.defineInRange("magicNumber", 42, 0, Integer.MAX_VALUE);
30+
31+
public static final ForgeConfigSpec.ConfigValue<String> MAGIC_NUMBER_INTRODUCTION = BUILDER
32+
.comment("What you want the introduction message to be for the magic number")
33+
.define("magicNumberIntroduction", "The magic number is... ");
34+
35+
// a list of strings that are treated as resource locations for items
36+
private static final ForgeConfigSpec.ConfigValue<List<? extends String>> ITEM_STRINGS = BUILDER
37+
.comment("A list of items to log on common setup.")
38+
.defineListAllowEmpty("items", List.of("minecraft:iron_ingot"), Config::validateItemName);
39+
40+
static final ForgeConfigSpec SPEC = BUILDER.build();
41+
42+
public static boolean logDirtBlock;
43+
public static int magicNumber;
44+
public static String magicNumberIntroduction;
45+
public static Set<Item> items;
46+
47+
private static boolean validateItemName(final Object obj)
48+
{
49+
return obj instanceof final String itemName && ForgeRegistries.ITEMS.containsKey(ResourceLocation.parse(itemName));
50+
}
51+
52+
@SubscribeEvent
53+
static void onLoad(final ModConfigEvent event)
54+
{
55+
logDirtBlock = LOG_DIRT_BLOCK.get();
56+
magicNumber = MAGIC_NUMBER.get();
57+
magicNumberIntroduction = MAGIC_NUMBER_INTRODUCTION.get();
58+
59+
// convert the list of strings into a set of items
60+
items = ITEM_STRINGS.get().stream()
61+
.map(itemName -> ForgeRegistries.ITEMS.getValue(ResourceLocation.parse(itemName)))
62+
.collect(Collectors.toSet());
63+
}
64+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
<!--
2+
Minecraft Development for IntelliJ
3+
4+
https://mcdev.io/
5+
6+
Copyright (C) 2024 minecraft-dev
7+
8+
This program is free software: you can redistribute it and/or modify
9+
it under the terms of the GNU Lesser General Public License as published
10+
by the Free Software Foundation, version 3.0 only.
11+
12+
This program is distributed in the hope that it will be useful,
13+
but WITHOUT ANY WARRANTY; without even the implied warranty of
14+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15+
GNU General Public License for more details.
16+
17+
You should have received a copy of the GNU Lesser General Public License
18+
along with this program. If not, see <https://www.gnu.org/licenses/>.
19+
-->
20+
21+
<html>
22+
<body>
23+
<p>This is a built-in file template used to create a new config class for Forge projects 1.21 and above</p>
24+
</body>
25+
</html>

0 commit comments

Comments
 (0)