本篇教程由作者设定未经允许禁止转载。
序
“时代是在进步的,过去的就不会再回来了
但时间走过的脚印不能全部随风而散,这就是《历史》的必要性”
众所周知,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);