这篇阅读时长五分钟的文章可能是目前最有价值的模组开发入门指南。
笔者经常会被动接触到一些教你开发模组的新视频系列,其中总能看到视频作者在雄心勃勃地向你介绍如何创建项目等工作,有的甚至会花费大量时间向你传授编程基础。可往下一划,你就会在推荐视频栏目里看到很多过去类似的教程,它们往往都不了了之,即使你真的耐着性子看完,也可能仅仅学了个皮毛,做不出自己真正想要的东西。
这些教程往往忽视了一个重要且基础的问题,那就是分析并解决问题的思路。下文将试图补足这一点,并对你的模组开发之路有所启发。
这篇文章不是教程。这篇入门指南将会避免技术细节和时效性内容,也不针对特定的平台。笔者将以六年的模组开发经验和一亿次作品下载量保证其可靠性,分析你的处境,给出分析并解决问题的思路,最后分享几个笔者认为最重要的实践。
对于一些人来说,他们希望做出自己心目中的模组。其实,学习模组开发只是达成目的的一种手段。大部分需求都可以通过现有方式更快实现,你需要做的是寻求专业玩家/开发者的建议,说不定某个你未曾听说的模组已经做了你想要做的事。
如果你的需求比较简单,可以考虑使用MCreator。不要小瞧它,笔者就曾经被MCreator网站里作品的功能性震惊到过,或许你也应该了解一下。
如果你的需求复杂但规模较小,笔者的建议是委托专业人士为你完成,毕竟学习模组开发对于零基础者而言并非一朝一夕,让专业的人做专业的事会更好。写到这里,笔者不禁回想起自己被一些开发者报价之低再次震惊到的事了。
对于另一些人来说,他们希望借此增长他们游戏开发、产品设计、或是沟通协作的能力。这是一个很好的选择,因为Minecraft有着最大的玩家基数和模组社区,你可以有充足的机会展示自己的作品。
在正式学习模组开发之前,你应当具备以下知识:
-
首先,你应该有基本的面向对象编程知识。你需要知道基础的数据结构,这样你才能以合适的方式存储数据。你需要知道什么是线程,这样才不会在想要实现动画时卡死游戏。你需要知道什么是垃圾回收,这样才不会把整个维度一直存储在内存里。
-
其次,你应该对Java语法有一定了解,至少能够在看到不熟悉的语法时能通过搜索引擎找到答案。
-
最后,你应该对Minecraft本身有相当程度的了解。这样你才能在想要实现某样东西时立刻联想到游戏中的某个内容或系统有可以利用之处。
如果你看到这里觉得自己还不够格,请选择互联网上大量制作精良的Java教程,它们远比那些模组开发教程里试图教你的要好得多。
还有一些知识,它们并不是必须的,但是会对你很有帮助:
-
玩其他模组的经验。
-
设计模式。这会让你快速理解某个系统的工作原理,也让你在设计自己的系统时更加得心应手。
-
游戏开发经验,最好是RPG网络游戏。这会让你更好地理解服务端和客户端的交互和通信。
到这里,笔者有必要反驳一些关于模组或是游戏本身的常见误区,秉持这样的观点对接下来的学习是有害的:
此观点的拥趸大多不具备完整开发一款软件的经验。事实上,今天的Minecraft代码质量已经得到相当程度的改善,Mojang作为有几十名开发人员的团队,他们的代码会进行足够的审阅。假如把这样复杂的项目交给99%的专业游戏开发者来做,最终都会演变成一场项目管理灾难。所以当我们学习模组开发时,Minecraft代码一直是最好的老师。
此观点混淆了游戏的体积与游戏复杂度之间的区别。传统电子游戏的体积主要来源于大量含有丰富细节的模型、贴图和音频,而Minecraft并不见长于此。Minecraft的世界是无限且高度可变的,这决定了Minecraft无法高效利用多核处理器,这样同传统电子游戏的粗略比较是不公平的。很难想象当《GTA》中的每处地面都能被炸出一个大坑时,它的性能可以和原来一样。
事实上Forge和Fabric之间的区别远没有想象中那样大,通过巧妙的方式可以使你的模组很快迁移到另一种平台。Minecraft本身的代码才是你应该着重了解的。毕竟在最大的模组发布平台CurseForge上,两个平台目前处于分庭抗礼的关系,谁不喜欢更多的用户呢?
在这一部分中,笔者将介绍一个常见模组是如何完成其目标的。
一般来说,模组主要做两件事:添加新的内容,和修改原有内容。
要添加新内容,一般我们会继承或实现游戏对象(物品、方块、配方、实体等),然后将它们注册到游戏的注册表中。
要修改原有的较简单的内容,我们会监听Forge、Fabric API或其他模组提供的事件,然后在事件发生时加入我们的逻辑。对于小众的修改需求,平台永远也不可能面面俱到,这时候就需要使用Mixin直接修改游戏或其他模组的代码。
通过结合这些方法,一个完整的模组就诞生了。
Minecraft Java版现在已经有几十万行代码,这意味着你将永远不可能完全掌握它。幸运的是,你只需要掌握一些基础知识,然后在需要实现某个特定功能时学会相应的部分就可以了。事实上,学会一件事情的最好方法就是真正用到它。对于那些百科全书式的视频教程,完全没有必要细看。
那么,有哪些基础知识是需要了解的呢?笔者这里推荐阅读Fabric官方文档,它简洁明了,并且提供中文翻译。首先你应该浏览一遍目录,在你搞不清楚某个条目的意思时读一下它的导言。然后,你应该阅读整个“基础”部分、“方块和方块实体”的前三个章节、以及“Mixin和ASM”的前四个章节。这些内容可以帮助你更好地理解游戏和模组的运行机制。
对于初学者而言,在面临一个需求时应当首先思考在原版和一些小型模组中是否已经有了类似的实现。一般来说对于初学者,很少出现前所未有的需求,你应当学习相似内容的写法,融会贯通,形成自己的内容。在这里笔者举一个简单的例子,希望能够帮助你理解思考流程,举一反三:
比如,要实现一个特殊的门,它会在开关时播放平滑的过渡动画。首先,门是方块,要为方块制作动画一般采用方块实体渲染器。那么,原版中有没有类似的方块实体,它的某个部分可以绕轴旋转呢?答案是肯定的,比如箱子的开盖动画,又比如钟的摇晃动画,它们都是最有价值的参考资料。
记住,不要吝啬你的想象力!再加上持续的模仿!
最后,不要忘记Minecraft有庞大的开发者社区,你可以通过搜索引擎或在群组中提问获取帮助。不过,最好提高一下自己的英语水平,至少选择一个好点的翻译软件。
“最佳实践”是可以使开发活动达到最优结果的做法,但是接下来介绍的并非最佳实践。因为我们使用的模组开发工具链远非完美,制作模组就是一个不断妥协的过程。笔者在这里仅提供个人觉得舒服的做法,以供参考。
使用官方映射表可以帮助你将模组更快移植到新的平台。的确,官方映射表的质量并不是最高的,也有一些奇技淫巧允许你通过非官方映射表移植,但官方映射表是无可争议使用最广泛的标准。
笔者一般使用IntelliJ IDEA编写代码,用Eclipse进行调试。这是因为它们各有优点:
IntelliJ IDEA:
- 更棒的编程体验
- 使用Minecraft Development插件,尤其是编写mixin
- 使用GitHub Copilot
Eclipse:
- 几乎没有延迟的方法内热重载
- 更好用的Minecraft代码搜索
- Ctrl+Shift+O一键导入包
笔者推荐将Forge和Fabric相关类的引用限制在几个固定的类中,通过引用这些类来完成你的目的。这样可以使你在迁移平台,合并代码时事半功倍。
限制仅客户端存在的注解也并非必需,可以通过编码技巧避免使用。
TOML格式非常受一些模组开发者欢迎。然而根据笔者的经验表明,TOML这种格式存在设计缺陷,目前Java生态也没有任何一款足够好的TOML编码解码器。笔者目前使用的是YAML和JSON格式。
历史表明,Forge的一些特性总是疏于维护,漏洞频出,最终被Forge自己抛弃。建议在看到这些特性时避免盲目乐观,而考虑转而使用多平台通用的解决方案。
这是这篇文章的结尾。感谢GitHub@RisingInIris2017 对格式和措辞的建议。希望你有所收获,在模组开发过程中找到属于自己的乐趣。