ARTICLE DETAIL

资讯详情

深耕商务建站与企业官网运营的一线实战洞察。

Forge 1.20.1模组开发:实现给鸡挤奶与混沌碎片合成

Forge 1.20.1模组开发:实现给鸡挤奶与混沌碎片合成 在一档名为《石头世界》的系列内容第 4 季第 14 集里“给鸡挤奶还要制作成混沌碎片”听起来像一句整活台词。但把它当成玩法需求交给 Minecraft 模组开发者时这句话包含的信息量并不小玩家要和鸡交互、交互结果要产出一种特殊物品、这个物品还要进入合成链变成“混沌碎片”。这里不讨论剧情只把标题当作需求输入实现一个可运行的 Forge 1.20.1 模组原型并通过这次开发把实体交互、物品注册、事件监听、NBT 冷却、配方 JSON 和配置外置的完整链路串起来。这类需求最大的特征是原始描述很短可执行细节几乎为零。开发者的任务不是照着标题写代码而是先确定一套合理假设再让假设变成可验证的流程。本文使用的假设是玩家手持玻璃瓶右键鸡消耗一个玻璃瓶后获得“鸡奶瓶”鸡奶瓶和一块普通石头在工作台里合成“混沌碎片”。1. 先把“给鸡挤奶做成混沌碎片”拆解成可执行需求任何一个看似荒诞的需求落到代码里都要先拆成可执行动作。标题里的“给鸡挤奶”是行为层“制作成混沌碎片”是结果层。中间还有一个隐含状态挤出来的奶要先变成一种中间物品否则“制作”没有材料来源。1.1 标题里其实有两套玩法如果只看“给鸡挤奶”首先要回答四个问题玩家用什么物品触发这个交互。交互是否消耗物品。交互是否有次数限制或冷却。这个交互是否只对鸡生效还是对一类动物生效。再看“还要制作成混沌碎片”又要回答另外几个问题混沌碎片是一个物品、一个方块还是一种特殊货币。碎片是挤奶时直接掉落还是需要二次合成。如果二次合成使用的配方是什么。合成之后鸡奶瓶是否消耗。原版 Minecraft 里鸡只负责下蛋不存在“挤奶”这个行为。右键鸡时原版逻辑不会给出任何奶类结果。所以这个需求必须通过事件系统拦截实体交互在玩家手持指定物品右键鸡时取消原版逻辑并执行自定义逻辑。这里采用一种最小闭环把鸡奶瓶设计为普通物品而不是真正的流体桶。普通 Item 足够验证行为链路真正的流体桶需要额外实现 Fluid、桶物品和流体渲染会让原型复杂很多。1.2 需求拆成四个模块为了让开发过程不混乱可以把整个需求拆成四个模块。实体交互模块负责判断“玩家手持玻璃瓶右键鸡”这个动作是否成立以及是否处于冷却状态。物品模块负责注册鸡奶瓶和混沌碎片并设置堆叠数量、物品 ID、显示名称等属性。合成模块负责定义“鸡奶瓶 石头 混沌碎片”的配方让碎片能通过工作台制作。状态与配置模块负责记录玩家上次挤奶的时间并把冷却时间、产出数量等参数放到配置文件里避免每次调整都要重新编译。这四个模块不是并列关系而是依赖关系事件模块产生鸡奶瓶物品模块提供鸡奶瓶合成模块消费鸡奶瓶配置模块约束事件模块的触发频率。1.3 先定技术路线数据包、Forge 还是 Fabric| 方案 | 能实现什么 | 不能实现什么 | 适合场景 || --- | --- | --- | --- | | 纯数据包 | 物品标签、配方、进度、部分战利品 | 新增自定义物品、拦截实体交互、写入玩家 NBT | 已经存在基础物品只是调整配方 | | Fabric | 自定义物品、事件监听、服务端逻辑 | 需要掌握 Fabric Loader 和对应 API | 团队已经使用 Fabric 生态 | | Forge | 自定义物品、事件监听、NBT 操作、配置系统 | 需要处理较重的 MDK 结构 | 社区资料多适合教学和快速验证 |这里选择 Forge 1.20.1原因是它的PlayerInteractEvent、DeferredRegister、ForgeConfigSpec都属于比较稳定的 API网上资料也多。对于“给鸡挤奶”这种需要新增交互逻辑的需求纯数据包做不了因为数据包没有办法在玩家右键鸡时执行自定义逻辑。1.4 先想清楚物品是普通 Item 还是流体容器标题里提到“奶”容易让人下意识去实现流体。但一个最小原型不应该一上来就做流体。合理做法是先把“鸡奶”建模成一个普通物品名叫“鸡奶瓶”堆叠数量设为 16。它只是一个中间材料不参与真正桶装液体的倾倒、放置和填充逻辑。这样做的取舍是视觉上不够真实鸡奶瓶不能倒出来换来的是开发链路短能快速验证“交互、产出、合成”这个主干。后续需要真实流体时再基于这个结构扩展 Fluid 和 BucketItem。2. 环境准备与项目骨架先锁版本再写事件2.1 需要准备的环境模组开发中大多数问题都出在版本不匹配。写代码之前先确认 JDK、Minecraft、Forge 和 Gradle 的版本关系。环境项推荐值说明JDK17Minecraft 1.20.1 使用 Java 17 编译和运行开发 IDEIntelliJ IDEA方便导入 Gradle 项目Minecraft1.20.1社区模组兼容性较高Forge MDK47.x以 Forge 官网或 Maven 列表为准GradleMDK 自带 wrapper不需要单独安装下载 Forge MDK 后先不要急着写代码。打开gradle.properties把版本号固定下来再启动gradlew导入项目。如果原始材料没有给出明确版本落地前要先确认依赖版本。不同 Minecraft 主版本对应不同 Forge API代码风格也会不同尤其是事件注册和配置系统的写法。2.2 Gradle 配置要点在gradle.properties中写入以下内容minecraft_version1.20.1 forge_version47.1.0 mappings_channelofficial mappings_version1.20.1其中mappings_channelofficial表示使用 Mojang 官方映射。对新手来说官方映射名称和代码里看到的Chicken、Item、Player一致阅读和调试都比较直观。build.gradle关键段落如下plugins { id net.minecraftforge.gradle version [6.0,6.2) } dependencies { implementation fg.deobf(net.minecraftforge:forge:${minecraft_version}-${forge_version}) }fg.deobf会自动处理 Minecraft 和 Forge 的反混淆依赖开发者不需要手动管理运行时库。2.3 项目目录结构一个最简单的 Forge 模组项目结构如下stoneworld-mod/ ├── build.gradle ├── gradle.properties └── src/main/ ├── java/com/stoneworld/ │ ├── StoneWorldMod.java │ ├── item/ModItems.java │ ├── event/ChickenMilkHandler.java │ └── config/StoneWorldConfig.java └── resources/ ├── META-INF/mods.toml ├── assets/stoneworld/ │ ├── lang/zh_cn.json │ └── textures/item/ └── data/stoneworld/ └── recipes/资源文件的路径非常关键。配方文件必须放在data/stoneworld/recipes/下语言文件必须放在assets/stoneworld/lang/zh_cn.json下。路径一旦写错不会直接报编译错误而是运行时配方便静默失效这是模组开发中最容易浪费时间的坑之一。3. 实现核心交互给鸡挤奶并产出一瓶鸡奶3.1 先把两个物品注册进去使用 Forge 的DeferredRegister注册物品这是当前推荐写法。它会在模组加载阶段统一注册物品同时保证物品 ID 不会冲突。public class ModItems { public static final DeferredRegisterItem ITEMS DeferredRegister.create(ForgeRegistries.ITEMS, StoneWorldMod.MOD_ID); public static final RegistryObjectItem CHICKEN_MILK_BOTTLE ITEMS.register(chicken_milk_bottle, () - new Item(new Item.Properties().stacksTo(16))); public static final RegistryObjectItem CHAOS_FRAGMENT ITEMS.register(chaos_fragment, () - new Item(new Item.Properties().stacksTo(64))); public static void register(IEventBus bus) { ITEMS.register(bus); } }stacksTo(16)是因为这瓶奶被定位为中间材料数量太多会显得不合理混沌碎片作为最终合成材料堆叠到 64 比较顺手。如果后续想让物品拥有特殊提示文字或稀有度再单独继承Item类并重写方法。StoneWorldMod里的注册代码如下Mod(StoneWorldMod.MOD_ID) public class StoneWorldMod { public static final String MOD_ID stoneworld; public StoneWorldMod() { IEventBus bus FMLJavaModLoadingContext.get().getModEventBus(); ModItems.register(bus); ModLoadingContext.get().registerConfig(ModConfig.Type.COMMON, StoneWorldConfig.SPEC); } }3.2 监听玩家与鸡的交互Forge 提供 Player
返回列表
PREV
查看更多资讯
NEXT
返回资讯列表