Update to 1.20 and support Forge

This commit is contained in:
shedaniel
2023-06-08 12:49:18 +08:00
parent a6e5876dec
commit 82505652eb
13 changed files with 177 additions and 112 deletions

View File

@@ -25,6 +25,7 @@ import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.level.storage.loot.LootDataManager;
import net.minecraft.world.level.storage.loot.LootPool;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.Nullable;
/**
* Events related to loot tables and loot generation.
@@ -65,13 +66,14 @@ public interface LootEvent {
/**
* Modifies a loot table.
*
* @param lootDataManager the {@link LootDataManager} instance containing all loot tables
* @param id the loot table ID
* @param context the context used to modify the loot table
* @param builtin if {@code true}, the loot table is built-in;
* if {@code false}, it is from a user data pack
* @param lootDataManager the {@link LootDataManager} instance containing all loot tables,
* may be {@code null}
* @param id the loot table ID
* @param context the context used to modify the loot table
* @param builtin if {@code true}, the loot table is built-in;
* if {@code false}, it is from a user data pack
*/
void modifyLootTable(LootDataManager lootDataManager, ResourceLocation id, LootTableModificationContext context, boolean builtin);
void modifyLootTable(@Nullable LootDataManager lootDataManager, ResourceLocation id, LootTableModificationContext context, boolean builtin);
}
/**

View File

@@ -113,7 +113,7 @@ unifiedPublishing {
displayName = "[Fabric $rootProject.supported_version] v$project.version"
releaseType = "$rootProject.artifact_type"
changelog = releaseChangelog()
gameVersions = []
gameVersions = ["1.20"]
gameLoaders = ["fabric", "quilt"]
mainPublication renameJarForPublication
relations {
@@ -138,7 +138,7 @@ unifiedPublishing {
token = MODRINTH_TOKEN
id = rootProject.modrinth_id
version = "$project.version+$project.name"
gameVersions.addAll project.minecraft_version
// gameVersions.addAll project.minecraft_version
}
}
}

View File

@@ -126,7 +126,7 @@ unifiedPublishing {
displayName = "[Forge $rootProject.supported_version] v$project.version"
releaseType = "$rootProject.artifact_type"
changelog = releaseChangelog()
gameVersions = ["1.19.4"]
gameVersions = ["1.20"]
gameLoaders = ["forge"]
mainPublication renameJarForPublication

View File

@@ -19,7 +19,6 @@
package dev.architectury.event.forge;
import com.mojang.blaze3d.vertex.PoseStack;
import dev.architectury.event.CompoundEventResult;
import dev.architectury.event.EventResult;
import dev.architectury.event.events.client.ClientChatEvent;
@@ -29,6 +28,7 @@ import dev.architectury.impl.ScreenAccessImpl;
import dev.architectury.impl.TooltipEventColorContextImpl;
import dev.architectury.impl.TooltipEventPositionContextImpl;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.GuiGraphics;
import net.minecraft.client.gui.screens.Screen;
import net.minecraft.client.multiplayer.ClientLevel;
import net.minecraft.network.chat.Component;
@@ -59,7 +59,7 @@ public class EventHandlerImplClient {
@SubscribeEvent(priority = EventPriority.HIGH)
public static void eventRenderGameOverlayEvent(RenderGuiEvent.Post event) {
ClientGuiEvent.RENDER_HUD.invoker().renderHud(event.getPoseStack(), event.getPartialTick());
ClientGuiEvent.RENDER_HUD.invoker().renderHud(event.getGuiGraphics(), event.getPartialTick());
}
@SubscribeEvent(priority = EventPriority.HIGH)
@@ -137,24 +137,24 @@ public class EventHandlerImplClient {
@SubscribeEvent(priority = EventPriority.HIGH)
public static void eventDrawScreenEvent(ScreenEvent.Render.Pre event) {
if (ClientGuiEvent.RENDER_PRE.invoker().render(event.getScreen(), event.getPoseStack(), event.getMouseX(), event.getMouseY(), event.getPartialTick()).isFalse()) {
if (ClientGuiEvent.RENDER_PRE.invoker().render(event.getScreen(), event.getGuiGraphics(), event.getMouseX(), event.getMouseY(), event.getPartialTick()).isFalse()) {
event.setCanceled(true);
}
}
@SubscribeEvent(priority = EventPriority.HIGH)
public static void eventDrawScreenEvent(ScreenEvent.Render.Post event) {
ClientGuiEvent.RENDER_POST.invoker().render(event.getScreen(), event.getPoseStack(), event.getMouseX(), event.getMouseY(), event.getPartialTick());
ClientGuiEvent.RENDER_POST.invoker().render(event.getScreen(), event.getGuiGraphics(), event.getMouseX(), event.getMouseY(), event.getPartialTick());
}
@SubscribeEvent(priority = EventPriority.HIGH)
public static void eventContainerScreenEvent(ContainerScreenEvent.Render.Background event) {
ClientGuiEvent.RENDER_CONTAINER_BACKGROUND.invoker().render(event.getContainerScreen(), event.getPoseStack(), event.getMouseX(), event.getMouseY(), Minecraft.getInstance().getDeltaFrameTime());
ClientGuiEvent.RENDER_CONTAINER_BACKGROUND.invoker().render(event.getContainerScreen(), event.getGuiGraphics(), event.getMouseX(), event.getMouseY(), Minecraft.getInstance().getDeltaFrameTime());
}
@SubscribeEvent(priority = EventPriority.HIGH)
public static void eventContainerScreenEvent(ContainerScreenEvent.Render.Foreground event) {
ClientGuiEvent.RENDER_CONTAINER_FOREGROUND.invoker().render(event.getContainerScreen(), event.getPoseStack(), event.getMouseX(), event.getMouseY(), Minecraft.getInstance().getDeltaFrameTime());
ClientGuiEvent.RENDER_CONTAINER_FOREGROUND.invoker().render(event.getContainerScreen(), event.getGuiGraphics(), event.getMouseX(), event.getMouseY(), Minecraft.getInstance().getDeltaFrameTime());
}
@SubscribeEvent(priority = EventPriority.HIGH)
@@ -177,18 +177,18 @@ public class EventHandlerImplClient {
@SubscribeEvent(priority = EventPriority.HIGH)
public static void eventRenderTooltipEvent(RenderTooltipEvent.Pre event) {
PoseStack stack = event.getPoseStack();
GuiGraphics graphics = event.getGraphics();
ClientTooltipEvent.additionalContexts().setItem(event.getItemStack());
try {
if (ClientTooltipEvent.RENDER_PRE.invoker().renderTooltip(stack, event.getComponents(), event.getX(), event.getY()).isFalse()) {
if (ClientTooltipEvent.RENDER_PRE.invoker().renderTooltip(graphics, event.getComponents(), event.getX(), event.getY()).isFalse()) {
event.setCanceled(true);
return;
}
TooltipEventPositionContextImpl positionContext = tooltipPositionContext.get();
positionContext.reset(event.getX(), event.getY());
ClientTooltipEvent.RENDER_MODIFY_POSITION.invoker().renderTooltip(stack, positionContext);
ClientTooltipEvent.RENDER_MODIFY_POSITION.invoker().renderTooltip(graphics, positionContext);
event.setX(positionContext.getTooltipX());
event.setY(positionContext.getTooltipY());
} finally {
@@ -198,7 +198,7 @@ public class EventHandlerImplClient {
@SubscribeEvent(priority = EventPriority.HIGH)
public static void eventRenderTooltipEvent(RenderTooltipEvent.Color event) {
PoseStack stack = event.getPoseStack();
GuiGraphics graphics = event.getGraphics();
ClientTooltipEvent.additionalContexts().setItem(event.getItemStack());
try {
@@ -207,7 +207,7 @@ public class EventHandlerImplClient {
colorContext.setBackgroundColor(event.getBackgroundStart());
colorContext.setOutlineGradientTopColor(event.getBorderStart());
colorContext.setOutlineGradientBottomColor(event.getBorderEnd());
// ClientTooltipEvent.RENDER_MODIFY_COLOR.invoker().renderTooltip(stack, event.getX(), event.getY(), colorContext);
// ClientTooltipEvent.RENDER_MODIFY_COLOR.invoker().renderTooltip(graphics, event.getX(), event.getY(), colorContext);
event.setBackground(colorContext.getBackgroundColor());
event.setBorderEnd(colorContext.getOutlineGradientBottomColor());
event.setBorderStart(colorContext.getOutlineGradientTopColor());

View File

@@ -30,6 +30,7 @@ import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.LevelAccessor;
import net.minecraft.world.level.storage.loot.LootDataManager;
import net.minecraftforge.event.CommandEvent;
import net.minecraftforge.event.LootTableLoadEvent;
import net.minecraftforge.event.RegisterCommandsEvent;
@@ -61,7 +62,11 @@ import net.minecraftforge.fml.LogicalSide;
import net.minecraftforge.fml.event.lifecycle.FMLCommonSetupEvent;
import net.minecraftforge.server.ServerLifecycleHooks;
import java.lang.ref.WeakReference;
public class EventHandlerImplCommon {
public static WeakReference<LootDataManager> lootDataManagerRef = null;
@SubscribeEvent(priority = EventPriority.HIGH)
public static void event(ServerTickEvent event) {
if (event.phase == Phase.START)
@@ -418,12 +423,12 @@ public class EventHandlerImplCommon {
@SubscribeEvent(priority = EventPriority.HIGH)
public static void event(LootTableLoadEvent event) {
LootEvent.MODIFY_LOOT_TABLE.invoker().modifyLootTable(event.getLootTableManager(), event.getName(), new LootTableModificationContextImpl(event.getTable()), true);
LootEvent.MODIFY_LOOT_TABLE.invoker().modifyLootTable(lootDataManagerRef == null ? null : lootDataManagerRef.get(), event.getName(), new LootTableModificationContextImpl(event.getTable()), true);
}
@SubscribeEvent(priority = EventPriority.HIGH)
public static void event(AttackEntityEvent event) {
EventResult result = PlayerEvent.ATTACK_ENTITY.invoker().attack(event.getEntity(), event.getEntity().level, event.getTarget(), event.getEntity().getUsedItemHand(), null);
EventResult result = PlayerEvent.ATTACK_ENTITY.invoker().attack(event.getEntity(), event.getEntity().level(), event.getTarget(), event.getEntity().getUsedItemHand(), null);
if (result.isFalse()) {
event.setCanceled(true);
}

View File

@@ -22,16 +22,51 @@ package dev.architectury.event.forge;
import dev.architectury.event.events.common.LootEvent;
import net.minecraft.world.level.storage.loot.LootPool;
import net.minecraft.world.level.storage.loot.LootTable;
import net.minecraftforge.fml.util.ObfuscationReflectionHelper;
import java.lang.reflect.Field;
import java.util.List;
final class LootTableModificationContextImpl implements LootEvent.LootTableModificationContext {
private final LootTable table;
private final List<LootPool> pools;
LootTableModificationContextImpl(LootTable table) {
this.table = table;
// This field has the type changed to List<LootPool> by Forge
// Since this is rather unsafe, we are making sure 100% we are getting it
List<LootPool> pools = null;
try {
pools = ObfuscationReflectionHelper.getPrivateValue(LootTable.class, table, "f_79109_");
} catch (ObfuscationReflectionHelper.UnableToFindFieldException ignored) {
for (Field field : LootTable.class.getDeclaredFields()) {
if (field.getType().equals(List.class)) {
// This is probably the field
field.setAccessible(true);
try {
pools = (List<LootPool>) field.get(table);
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
}
}
}
if (pools == null) {
throw new RuntimeException("Unable to find pools field in LootTable!");
}
}
this.pools = pools;
}
@Override
public void addPool(LootPool pool) {
table.addPool(pool);
this.pools.add(pool);
}
@Override
public void addPool(LootPool.Builder pool) {
this.pools.add(pool.build());
}
}

View File

@@ -47,6 +47,6 @@ public abstract class MixinFallingBlockEntity extends Entity {
target = "Lnet/minecraft/world/level/block/Fallable;onLand(Lnet/minecraft/world/level/Level;Lnet/minecraft/core/BlockPos;Lnet/minecraft/world/level/block/state/BlockState;Lnet/minecraft/world/level/block/state/BlockState;Lnet/minecraft/world/entity/item/FallingBlockEntity;)V"),
locals = LocalCapture.CAPTURE_FAILHARD)
public void handleLand(CallbackInfo ci, Block block, BlockPos blockPos2, boolean bl, boolean bl2, double d, BlockState blockState) {
BlockEvent.FALLING_LAND.invoker().onLand(this.level, blockPos2, this.blockState, blockState, (FallingBlockEntity) (Object) this);
BlockEvent.FALLING_LAND.invoker().onLand(this.level(), blockPos2, this.blockState, blockState, (FallingBlockEntity) (Object) this);
}
}

View File

@@ -0,0 +1,43 @@
/*
* This file is part of architectury.
* Copyright (C) 2020, 2021, 2022 architectury
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package dev.architectury.mixin.forge;
import dev.architectury.event.forge.EventHandlerImplCommon;
import net.minecraft.server.packs.resources.PreparableReloadListener;
import net.minecraft.server.packs.resources.ResourceManager;
import net.minecraft.util.profiling.ProfilerFiller;
import net.minecraft.world.level.storage.loot.LootDataManager;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
import java.lang.ref.WeakReference;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Executor;
@Mixin(LootDataManager.class)
public class MixinLootDataManager {
@Inject(method = "reload", at = @At("HEAD"))
private void reload(PreparableReloadListener.PreparationBarrier arg, ResourceManager arg2, ProfilerFiller arg3,
ProfilerFiller arg4, Executor executor, Executor executor2, CallbackInfoReturnable<CompletableFuture<Void>> cir) {
EventHandlerImplCommon.lootDataManagerRef = new WeakReference<>((LootDataManager) (Object) this);
}
}

View File

@@ -127,12 +127,12 @@ public class ParticleProviderRegistryImpl {
return new ParticleProviderRegistrar() {
@Override
public <T extends ParticleOptions> void register(ParticleType<T> type, ParticleProvider<T> provider) {
event.register(type, provider);
event.registerSpecial(type, provider);
}
@Override
public <T extends ParticleOptions> void register(ParticleType<T> type, ParticleEngine.SpriteParticleRegistration<T> registration) {
event.register(type, registration);
event.registerSpriteSet(type, registration);
}
};
}

View File

@@ -25,15 +25,16 @@ import com.google.common.collect.MultimapBuilder;
import dev.architectury.forge.ArchitecturyForge;
import dev.architectury.registry.CreativeTabOutput;
import dev.architectury.registry.CreativeTabRegistry;
import dev.architectury.registry.CreativeTabRegistry.TabSupplier;
import net.minecraft.network.chat.Component;
import dev.architectury.registry.registries.DeferredSupplier;
import net.minecraft.core.registries.BuiltInRegistries;
import net.minecraft.core.registries.Registries;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.item.CreativeModeTab;
import net.minecraft.world.item.ItemStack;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.common.CreativeModeTabRegistry;
import net.minecraftforge.common.util.MutableHashedLinkedMap;
import net.minecraftforge.event.CreativeModeTabEvent;
import net.minecraftforge.event.BuildCreativeModeTabContentsEvent;
import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.fml.common.Mod;
import org.apache.logging.log4j.LogManager;
@@ -49,9 +50,7 @@ import java.util.function.Supplier;
public class CreativeTabRegistryImpl {
private static final Logger LOGGER = LogManager.getLogger(CreativeTabRegistryImpl.class);
@Nullable
private static List<Consumer<CreativeModeTabEvent.Register>> registerListeners = new ArrayList<>();
private static final List<Consumer<CreativeModeTabEvent.BuildContents>> BUILD_CONTENTS_LISTENERS = new ArrayList<>();
private static final List<Consumer<BuildCreativeModeTabContentsEvent>> BUILD_CONTENTS_LISTENERS = new ArrayList<>();
private static final Multimap<TabKey, Supplier<ItemStack>> APPENDS = MultimapBuilder.hashKeys().arrayListValues().build();
static {
@@ -61,7 +60,7 @@ public class CreativeTabRegistryImpl {
.map(Supplier::get)
.toList());
if (keyEntry.getKey() instanceof TabKey.SupplierTabKey supplierTabKey) {
if (Objects.equals(CreativeModeTabRegistry.getName(event.getTab()), supplierTabKey.supplier().getName())) {
if (Objects.equals(CreativeModeTabRegistry.getName(event.getTab()), supplierTabKey.supplier().getId())) {
for (ItemStack stack : stacks.get()) {
event.getEntries().put(stack, CreativeModeTab.TabVisibility.PARENT_AND_SEARCH_TABS);
}
@@ -78,67 +77,34 @@ public class CreativeTabRegistryImpl {
}
@SubscribeEvent
public static void event(CreativeModeTabEvent.Register event) {
if (registerListeners != null) {
for (Consumer<CreativeModeTabEvent.Register> listener : registerListeners) {
listener.accept(event);
}
registerListeners = null;
} else {
LOGGER.warn("Creative tab listeners were already registered!");
}
}
@SubscribeEvent
public static void event(CreativeModeTabEvent.BuildContents event) {
for (Consumer<CreativeModeTabEvent.BuildContents> listener : BUILD_CONTENTS_LISTENERS) {
public static void event(BuildCreativeModeTabContentsEvent event) {
for (Consumer<BuildCreativeModeTabContentsEvent> listener : BUILD_CONTENTS_LISTENERS) {
listener.accept(event);
}
}
public static TabSupplier create(ResourceLocation name, Consumer<CreativeModeTab.Builder> callback) {
if (registerListeners == null) {
throw new IllegalStateException("Creative tab listeners were already registered!");
}
CreativeModeTab[] tab = new CreativeModeTab[1];
registerListeners.add(register -> {
tab[0] = register.registerCreativeModeTab(name, builder -> {
builder.title(Component.translatable("itemGroup.%s.%s".formatted(name.getNamespace(), name.getPath())));
callback.accept(builder);
});
});
return new TabSupplier() {
@Override
public ResourceLocation getName() {
return name;
}
@Override
public CreativeModeTab get() {
if (tab[0] == null) {
throw new IllegalStateException("Creative tab %s was not registered yet!".formatted(name));
}
return tab[0];
}
@Override
public boolean isPresent() {
return tab[0] != null;
}
};
@ApiStatus.Experimental
public static CreativeModeTab create(Consumer<CreativeModeTab.Builder> callback) {
CreativeModeTab.Builder builder = CreativeModeTab.builder();
callback.accept(builder);
return builder.build();
}
@ApiStatus.Experimental
public static TabSupplier ofBuiltin(CreativeModeTab tab) {
ResourceLocation location = CreativeModeTabRegistry.getName(tab);
if (location == null) {
throw new IllegalArgumentException("Tab %s is not registered!".formatted(tab));
public static DeferredSupplier<CreativeModeTab> ofBuiltin(CreativeModeTab tab) {
ResourceLocation key = BuiltInRegistries.CREATIVE_MODE_TAB.getKey(tab);
if (key == null) {
throw new IllegalArgumentException("Builtin tab %s is not registered!".formatted(tab));
}
return new TabSupplier() {
return new DeferredSupplier<>() {
@Override
public ResourceLocation getName() {
return location;
public ResourceLocation getRegistryId() {
return Registries.CREATIVE_MODE_TAB.location();
}
@Override
public ResourceLocation getId() {
return BuiltInRegistries.CREATIVE_MODE_TAB.getKey(tab);
}
@Override
@@ -154,37 +120,50 @@ public class CreativeTabRegistryImpl {
}
@ApiStatus.Experimental
public static TabSupplier defer(ResourceLocation name) {
return new TabSupplier() {
public static DeferredSupplier<CreativeModeTab> defer(ResourceLocation name) {
return new DeferredSupplier<>() {
@Nullable
private CreativeModeTab tab;
@Override
public ResourceLocation getName() {
public ResourceLocation getRegistryId() {
return Registries.CREATIVE_MODE_TAB.location();
}
@Override
public ResourceLocation getId() {
return name;
}
@Override
public boolean isPresent() {
return CreativeModeTabRegistry.getTab(name) != null;
public CreativeModeTab get() {
resolve();
if (tab == null)
throw new IllegalStateException("Creative tab %s was not registered yet!".formatted(name));
return tab;
}
@Override
public CreativeModeTab get() {
CreativeModeTab tab = CreativeModeTabRegistry.getTab(name);
if (tab == null) {
throw new IllegalStateException("Creative tab %s was not registered yet!".formatted(name));
} else {
return tab;
public boolean isPresent() {
resolve();
return tab != null;
}
private void resolve() {
if (this.tab == null) {
this.tab = BuiltInRegistries.CREATIVE_MODE_TAB.get(name);
}
}
};
}
public static void modify(TabSupplier tab, CreativeTabRegistry.ModifyTabCallback filler) {
public static void modify(DeferredSupplier<CreativeModeTab> tab, CreativeTabRegistry.ModifyTabCallback filler) {
BUILD_CONTENTS_LISTENERS.add(event -> {
if (tab.isPresent()) {
if (event.getTab().equals(tab.get())) {
filler.accept(event.getFlags(), wrapTabOutput(event.getEntries()), event.hasPermissions());
}
} else if (Objects.equals(CreativeModeTabRegistry.getName(event.getTab()), tab.getName())) {
} else if (Objects.equals(CreativeModeTabRegistry.getName(event.getTab()), tab.getId())) {
filler.accept(event.getFlags(), wrapTabOutput(event.getEntries()), event.hasPermissions());
}
});
@@ -213,22 +192,22 @@ public class CreativeTabRegistryImpl {
}
@ApiStatus.Experimental
public static void appendStack(TabSupplier tab, Supplier<ItemStack> item) {
public static void appendStack(DeferredSupplier<CreativeModeTab> tab, Supplier<ItemStack> item) {
APPENDS.put(new TabKey.SupplierTabKey(tab), item);
}
private interface TabKey {
record SupplierTabKey(TabSupplier supplier) implements TabKey {
record SupplierTabKey(DeferredSupplier<CreativeModeTab> supplier) implements TabKey {
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof SupplierTabKey that)) return false;
return Objects.equals(supplier.getName(), that.supplier.getName());
return Objects.equals(supplier.getId(), that.supplier.getId());
}
@Override
public int hashCode() {
return Objects.hash(supplier.getName());
return Objects.hash(supplier.getId());
}
}

View File

@@ -13,7 +13,8 @@
"MixinEntitySpawnExtension",
"MixinFallingBlockEntity",
"MixinItemExtension",
"MixinLevelEvent"
"MixinLevelEvent",
"MixinLootDataManager"
],
"injectors": {
"defaultRequire": 1

View File

@@ -1,10 +1,10 @@
org.gradle.jvmargs=-Xmx6G
org.gradle.daemon=false
platforms=fabric
platforms=fabric,forge
minecraft_version=1.20-pre5
supported_version=1.20-pre5
minecraft_version=1.20
supported_version=1.20
artifact_type=beta
@@ -13,11 +13,11 @@ archives_base_name_snapshot=architectury-snapshot
base_version=9.0
maven_group=dev.architectury
fabric_loader_version=0.14.20
fabric_api_version=0.81.3+1.20
mod_menu_version=5.0.2
fabric_loader_version=0.14.21
fabric_api_version=0.83.0+1.20
mod_menu_version=7.0.0
forge_version=45.0.24
forge_version=46.0.1
curseforge_id=419699
modrinth_id=lhGA9TYQ

View File

@@ -13,9 +13,9 @@ if (JavaVersion.current().ordinal() + 1 < 17) {
include("common")
include("fabric")
//include("forge")
include("forge")
include("testmod-common")
include("testmod-fabric")
//include("testmod-forge")
include("testmod-forge")
rootProject.name = "architectury"