本篇教程由作者设定未经允许禁止转载。

“时代是在进步的,过去的就不会再回来了

但时间走过的脚印不能全部随风而散,这就是《历史》的必要性”

众所周知,Minecraft如今已经过去20个大版本了,很多东西也和最初的时候不一样了。

某些Mod淹没在了历史的长河中,或者干脆选择原地踏步,这样导致了现代版本的整合难以恢复往日的完整。

并且这些版本的特性也过时了不少,且并非所有的功能都有Mod移植。

这个时候,最好的方法是——自己动手。

反正低版本的Forge对于新手开发者而言更为友好,所以应该不会有太大的难度()

工作区选择与配置

环境变量

如果你接触过高版本开发,那你应该已经将JAVA_HOME这一环境变量设置为Java17的目录。

请修改JAVA_HOME使其重定向至Java8。

魔改版MDK

以下工具均由GTNH团队提供技术支持。

由于年代久远,原先的MDK和Gradle插件都已经严重过时了。

但GTNH团队一直在积极维护一个新的支持现代Gradle版本的RetroFuturaGradle插件

这会为我们省去大量不必要的麻烦。

按照如下所示操作后,请运行一次runClient任务拉取游戏依赖。

1.12.2

1.12.2的开发套件由CleanroomMC团队维护,

默认配置为:Gradle 8.1.1 +  RetroFuturaGradle + Forge 14.23.5.2847。

直接Fork CleanroomMC的TemplateDevEnv仓库即可,无需进行额外的设置。

1.7.10

1.7.10的开发套件由GTNH团队维护,

由于国内的网络环境问题,这个仓库克隆下来无法直接使用,需要进行一些修改。

将下列提到的值设为gradle.properties中对应的选项:

disableSpotless = true
autoUpdateBuildScript = false

然后修改build.gradle:

// 国内无法直接访问Github的原始文件站,强制让其返回false即可。
boolean isNewBuildScriptVersionAvailable() {
//    ...
    return false;
}

接下来导入项目即可。

官方版MDK

虽然支持的版本更多,但并不推荐。

因为这些MDK依赖了大量过时的内容,以至于无法兼容新版本的IDE。

只有你认为必须这么做时才这样做!

版本差异

由于Minecraft现今版本与历史版本的代码结构差异甚大,

所以Mod代码是不可能通用的,需要进行重写。

注册

虽然1.7.10就宣布废除了数字id,但高版本中也依然存在数字id,

只是不显式调用,让程序自动分配。

1.12.2的注册是这样的:

// 原版的注册方案
Item.REGISTRY.register(item);

// 这时Forge的注册非常方便
// 只需要在preInit事件时调用
// GameData.register_impl(obj);
// 原版的可注册物品都可以注册

而1.20是这样的:Forge在高版本膨胀了

// 原版的注册方案【被Forge屏蔽Mod无法调用】
Registry.register(BuiltInRegistries.ITEM, new ResourceLocation("modid:id"), item);

// Forge的注册方案【】
DeferredRegister<Item> ITEMS = DeferredRegister.create(ForgeRegistries.BLOCKS, "modid");
RegistryObject<Item> ITEM = ITEMS.register("item", ()->new Item(new Item.Properties()));

// 在CommonInit事件调用
ITEMS.register(FMLJavaModLoadingContext.get().getModEventBus());

通用设置:

// 下面介绍仅介绍1.12及以下的独有方法,
// 为讲解方便不使用连锁。

// obj 为原版任意可注册实例。

// 低版本没有Properties类
// 所以所有设置选项都是通过直接调用成员方法实现的

// 设置翻译键名,获取时的格式为<类型id>+"."+<此处设置的翻译键>+".name"
// 在低版本中方块的类型id是"tile"而不是"block"
obj.setTranslationKey("id");

// 建议使用现代版本的格式设置翻译键,以免翻译键冲突导致“守护之光”的惨剧重酿。
// obj.setTranslationKey(MOD_ID+".id");

其他设置(物品):

Item item = new Item();

// 设置物品是否使用元数据来区分物品【即不同元数据的物品是否应视为不同物品】
item.setHasSubtypes(true);

// 让物品像工具以及武器那样渲染
item.setFull3D();

// 禁用修复配方(只有物品能够损坏时才会起作用)
item.setNoRepair();

// ------------------------------------------------------

// 在客户端初始化时调用
// 必须手动指定物品模型位置
ModelLoader.setCustomModelResourceLocation(item, metaData,
        new ModelResourceLocation(itemId, "inventory"));

其他设置(方块):

// 这里与1.20类似,但没有Block.Properties
Block block = new Block(Material.IRON);

// 注意,低版本为方块物品中设置创造物品页是无效的
// 必须在方块中设置
block.setCreativeTab(ModRegistries.TAB);