欢迎光临散文网 会员登陆 & 注册

【真正的和平模式】一、模组简介与开发环境

2023-07-19 23:48 作者:VUMO北极鹅  | 我要投稿
你可曾想过,为何在Minecraft这片大陆上的怪物总会无差别或有条件地攻击玩家们?生活在这里,难免会感觉到孤独和恐惧——难道只有不停地战斗才是生存下去的唯一途径?不!或许战斗会让你血脉喷张,或许战斗会给你不一样的体验,但这远远不是热闹,而是另一种孤独。
如果,你能够去完成怪物们的心愿,与他们和谐共处,一起愉快地跳舞,一起在阳光下自由地奔跑——这才是真正的和平,这才是真正的热闹。
《真正的和平模式》这个模组添加了十余种自然结构,近十种生物实体,数十个方块和物品,以及对原版的怪物们分别添加了剧情任务。玩家要运用自己的脑力与技术,去完成怪物们的委托,或击败强敌,或探寻珍宝,或生产劳作,或寻觅真理……当玩家完成一种怪物的全部委托后,这种怪物将不再与玩家对立。
去吧,玩家,让这片冷酷而孤独的大陆变得热闹起来吧!

没错,这段内容是我开发的这个新模组的简介内容。由于近日比赛和项目较多,没什么时间来知乎创作了。但TeaCon 2023的这场比赛增设了【言传身教】奖,要求开发者通过编写技术博客为萌新开发者们快速入门、答疑解惑,那我何不写(shuǐ)几篇文章呢

项目以MIT协议开源,github仓库地址:

https://github.com/Viola-Siemens/Real-Peaceful-Mode

本文首发于知乎,笔者是作者本人,第二转载到bilibili平台。原文链接:https://zhuanlan.zhihu.com/p/644074598

背景

首先我们来看TeaCon 2023的题目:

「热闹」仿佛是中国人的向往的生活目标。春节时节,人们放烟花、贴春联,这是「热闹」的新年;夜市里,人头攒动、摊贩吆喝声不绝于耳,这是「热闹」的集市;闲暇时间,三五好友相约一起,去郊游、去唱歌,这是「热闹」的聚会;灯红酒绿的闹市里,悄然步入远离喧嚣人群的小巷,这是反差的「热闹」
那么你对「热闹」的体会和感觉是什么?什么才是让你感觉身心愉悦的「热闹」?请以此为出发点,写一个模组,自圆其说即可。
示例模组:末影龙舟。

审题

题目首先提供了四种热闹:

  1. 放烟花、贴春联,以节日氛围为主,通过喜庆的元素烘托出【热闹】。由此立意大概率会做出别具特色的装饰mod。

  2. 闹市中的叫卖声、丰富而吸引人的商品,通过物质的属性吸引人们一起【热闹】。由此立意,结合前几天我老家淄博烧烤的爆火,说不定可以写出夜市、烧烤等风格的食物mod,比如可以取名为淄博乐事。

  3. 三五好友相约郊游唱歌,通过玩家间的交互来体现【热闹】。这是本题中最为扩大开发者立意范围的一条,只要丰富了玩家间的交流,都可以算作热闹,甚至还保留了冒险mod等题材的选择可能。示例模组末影龙舟则是通过玩家间一起齐心协力划龙舟、互相组队赛龙舟体现出了【热闹】的氛围。

  4. 远离喧嚣,背弃世俗,选择孤身奋战——也许这是孤独,也许这十分冷清,但这又何尝不是反差的【热闹】?这是本题最难立意的一条,稍有不慎则会跑题,不少参赛者选择放弃从它立意。既然如此,我选择反其道而行之,从这一条上立意,毕竟我头铁,我怕谁!

另外题目的表述似乎在给予开发者们一个暗示,热闹体现在玩家与玩家之间,体现在物品的使用与交互中,事实上并非如此。我也是考虑到了这一点,萌生了一个大胆的想法——玩家怪物之间,是否也算热闹

基于这个想法,我便在考虑,如果在Minecraft的世界,玩家和怪物能够和平共处,互相帮助,从此玩家不再孤身一人,而是有着无数的旅途伙伴,而无需多人联机,那这样的世界该有多热闹!

这便是反向立意法,在立意时考虑【热闹】的反义词是什么,我认为是【冷清】、【孤独】,而解决掉冷清与孤独之后,便是符合题意的热闹!

进一步的,这片大陆中不止有一种怪物,玩家实现了一种怪物的心愿后,悄然离开去帮助其它的生物,正是符合了第四条的立意。

说干就干!模组策划好了,内容便是,玩家需要通过不断探索世界,帮助怪物们完成他们的心愿,从此对应的怪物将不再攻击玩家,实现真真正正的和平模式

环境配置

Minecraft与Forge版本的选择

根据要求,模组的目标平台为Minecraft 1.20.1,Forge 47.0.1以上——事实上TeaCon开幕不久后,Forge 47.1.0稳定版问世,于是我选择使用它来编译和运行模组。

编写build.gradle

1.20+与先前版本不同,需要使用ForgeGradle 6.0,而gradle的版本也变成了8.1.1,我用之前写1.16.5~1.19.4的build.gradle的写法来配置项目时直接失败了,因此需要注意这一点。

由于需要使用spongepowered mixin,因而需要添加一些dependencies:

为了方便调试和生成内容,需添加一些runs的配置,这里我写了四个runs,分别是运行客户端、运行服务端、运行服务端测试和生成内容:

最后则是forge版本、mixin的依赖,打jar包和和mixin的配置,还有最重要的标题、作者、版本与发布设置:

模组核心架构

常言道,万事开头难,那么编写一个模组该从何处开头呢?

首先,Forge模组通过一个注解了“@Mod(value = "modid")”的类作为模组入口,通过实例化这样一个类来对Minecraft的游戏内容进行修改。这个类中,你可以监听Forge事件、注册项目,也可以调用和加载其它的类来进行各种修改等。例如,我可以这样编写构造函数:

注意,这里我调用了Forge的两个不同的bus——ForgeBus和ModBus。ModBus一般执行模组生命周期中发生的注册、加载等事件,而ForgeBus则一般执行游戏过程中Forge的各种Hooks捕获到的事件,如TagsUpdatedEvent(数据包被重新加载)、ServerStartedEvent(服务端,启动!)、VillagerTradesEvent(村民职业对应交易表的添加)等。前者往往是静态的,而后者往往是动态的。这些Event的监听则构成了Forge的API,你可以通过查阅Forge文档,了解Forge的Hooks和注册机制,以及参阅minecraftforge的jar包的源代码内容来了解它们。总之能不mixin尽量不要mixin,除非有一些类中没有Forge的Hooks,或者你需要魔改的部分找不到API(如弓的附魔、新的音符盒乐器等等),而accesstransformer又无法单独完成修改,才考虑去使用mixin。

个人喜欢采用的实现一个功能的逻辑如下:

  1. 确定需求

  2. 从minecraft源代码中找到实现这个需求可行的注入点

  3. 确定有无Forge的Event可以通过监听来实现需求

  4. 若无,考虑可否使用AT(Access Transformer)来修改成员、函数或类的权限(也可以用mixin写Accessor)

  5. 若否,再考虑mixin,尽量使用Inject而避免用Redirect,绝对避免Overwrite和捕获局域变量的方法!

回到构造函数,这里调用了RPMContent.modConstruction,这是各种项目注册的入口:

以创造模式物品栏为例,模组可以选择使用延迟注册机制实现项目的注册:

这里定义了一个名为"real_peaceful_mode:real_peaceful_mode"的创造模式物品栏,对照本地化文件(以英语en_us.json为例),我们可以看到这个物品栏标签的名字:

"itemGroup.real_peaceful_mode": "Real Peaceful Mode"

没错,这是Minecraft原版的本地化系统,最早是自定义格式的.lang文件,如今则是JSON格式。代码中调用时,只需要使用Component.translatable("<本地化键名>")即可。

总结

我们的模组框架成功搭建起来了,那么模组开发的基础部分到此为止,下一篇我将讲解一些或核心或边缘的模组功能的实现。模组仍在持续制作中,敬请期待!


【真正的和平模式】一、模组简介与开发环境的评论 (共 条)

分享到微博请遵守国家法律