ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

CraftTweaker教程:用ZenScript脚本自定义《我的世界》模组合成表

CraftTweaker教程:用ZenScript脚本自定义《我的世界》模组合成表 1. 项目概述从“能用”到“会玩”的模组自定义之路如果你玩《我的世界》的模组整合包尤其是那些大型科技或魔法向的大概率见过一些奇奇怪怪的合成配方。比如用四个钻石和一个下界之星合成一个“终极工具核心”或者把原本需要八个黑曜石才能做的末影箱改成只需要四个。这些改动并不是模组作者预设的而是整合包作者或者服务器管理员通过一个叫做CraftTweaker的工具实现的。CraftTweaker直译过来就是“合成调整者”它允许你通过编写脚本ZenScript对游戏内几乎所有的合成配方进行增、删、改。这不仅仅是改几个物品那么简单它意味着你可以重新设计整个游戏的经济系统和进度曲线让模组之间产生全新的化学反应。我最初接触CraftTweaker是因为自己搭建一个以“艰难生存”为主题的私人整合包。我发现原版和模组的一些合成配方要么太简单破坏了挑战性要么太繁琐让游戏体验变得枯燥。比如工业模组IndustrialCraft的机器框架需要大量铁而另一个魔法模组Thaumcraft的注魔台又需要很多稀有材料两者之间毫无关联。我希望它们能产生联动让玩家在探索一个模组时获得的资源能服务于另一个模组从而形成一个自洽的、有深度的科技树。CraftTweaker就是实现这个愿景的钥匙。它不像一些图形化修改工具那样有诸多限制它提供了近乎底层的API接口只要你懂一点逻辑就能实现天马行空的想法。本教程基于1.18.2版本这是目前长期支持且模组生态较为稳定的一个版本其原理和思路同样适用于相近的版本。2. 环境准备与核心概念解析在开始写第一行脚本之前我们需要把舞台搭建好。CraftTweaker本身只是一个框架它需要对应的加载器如Forge或Fabric以及一些辅助模组才能发挥全部威力。理解这几个核心组件的角色是避免后续各种“脚本不生效”问题的关键。2.1 必需模组与工具选型首先你需要一个《我的世界》1.18.2的Forge客户端。Fabric端也有类似的工具如KubeJS但CraftTweaker在Forge端的生态更成熟教程和社区支持也更丰富。安装好Forge后你需要将以下模组放入游戏的mods文件夹CraftTweaker这是核心模组提供了基础的脚本加载和API框架。没有它你的脚本文件就只是一堆文本。ZenScript语言依赖在1.18.2版本CraftTweaker将ZenScript语言分离成了一个独立模组通常名为CraftTweaker-forge-1.18.2-9.1.xxx.jar这样的格式已经包含了语言支持但请务必在模组下载页面确认其依赖关系。有时你可能需要单独下载一个ZenScript模组。JEI (Just Enough Items)这不是CraftTweaker的必需依赖但它是你进行配方管理和调试的“眼睛”。JEI会在游戏内显示所有物品的合成表。当你用CraftTweaker修改配方后JEI中的显示也会同步更新这是验证脚本是否生效最直观的方式。注意务必确保所有模组的版本与你的游戏版本1.18.2以及彼此之间兼容。最稳妥的方法是使用一个成熟的整合包作为基础或者从CurseForge等模组站点的“关系”页面查看模组的依赖和兼容版本。安装完成后启动一次游戏如果能在模组列表里看到CraftTweaker并且没有报错崩溃那么基础环境就准备好了。接下来你会在游戏根目录下发现一个新的文件夹scripts。你所有自定义合成表的脚本文件后缀名为.zs都将放在这里。2.2 ZenScript脚本基础与文件结构ZenScript是CraftTweaker使用的专用脚本语言它的语法类似于Java和JavaScript的混合体但为了适配《我的世界》而做了大量简化。你不需要成为编程高手只需要理解几个核心概念和结构就能上手。脚本文件(.zs)的创建与加载顺序 在scripts文件夹内你可以创建任意多个.zs文件例如start.zs,machines.zs,magic.zs。游戏加载时会按字母顺序加载这些文件。这很重要因为如果你在b.zs里使用了一个在a.zs里定义的变量而b.zs先被加载了就会报错。一种常见的做法是创建一个init.zs或00_init.zs文件在里面定义所有后续脚本会用到的全局变量和函数确保它最先被加载。基础语法一览// 这是一行注释不会被程序执行 /* 这是一个 多行注释 */ // 1. 导入语句告诉脚本我要使用哪个模组的API import crafttweaker.api.item.IItemStack; // 导入物品栈类 import mods.industrialforegoing.DissolutionChamber; // 导入某个模组的特定机器配方接口 // 2. 变量定义定义一个物品比如“铁锭” val ironIngot item:minecraft:iron_ingot; // val代表不可变的常量 // item:modid:item_name 是获取游戏内物品的标准格式也叫Bracket Handler。 // 3. 打印日志调试神器信息会输出到游戏日志文件logs/debug.log和控制台 print(Hello CraftTweaker!);理解“物品表示法”item:modid:item_name是第一步。minecraft是原版的命名空间iron_ingot是铁锭的内部名称。对于模组物品你需要知道它的Mod ID和物品名JEI可以帮你快速获取在JEI界面将鼠标悬停在物品上按CtrlU显示用途或CtrlR显示配方时屏幕左上角通常会显示该物品的ID格式如minecraft:iron_ingot直接复制即可用在脚本里。3. 核心操作增、删、改合成配方实战掌握了环境和语法基础我们就可以进入最核心的实操环节如何具体地移除、添加和修改合成配方。我将通过几个典型的例子带你一步步走完流程。3.1 移除配方清理与简化移除配方是最常见的操作之一目的通常是为了禁用过于强大或破坏平衡的原版/模组配方或者为自定义的新配方让路。移除工作台合成配方 假设我觉得原版的“信标”太容易获得想移除它的合成配方。// 移除信标的合成配方 recipes.remove(item:minecraft:beacon);这行代码会移除所有输出物为信标的工作台合成配方。但请注意它不会移除通过村民交易、怪物掉落等其他方式获得信标的途径。移除特定形状的配方 有时一个物品有多个合成配方例如木头可以合成4个木板木板也可以合成回木头我们只想移除其中一个。这时需要指定具体的配方输入。// 移除用4个橡木木板合成橡木工作台的配方即无序合成 recipes.removeShaped(item:minecraft:crafting_table, [[item:minecraft:oak_planks, item:minecraft:oak_planks], [item:minecraft:oak_planks, item:minecraft:oak_planks]]);recipes.removeShaped用于移除有序合成配方。方括号[][]定义了一个2x2的网格每个位置都指定了必须是橡木木板。如果你想移除的是无序合成即材料摆放位置无关需要使用recipes.removeShapeless并且传入一个材料列表。// 移除用任意4个木板合成工作台的配方无序合成 recipes.removeShapeless(item:minecraft:crafting_table, [item:minecraft:oak_planks, item:minecraft:oak_planks, item:minecraft:oak_planks, item:minecraft:oak_planks]);实操心得在移除配方后一定要立刻进入游戏通过JEI查看该物品是否还有合成途径。如果移除失败首先检查物品ID是否拼写正确大小写、下划线其次检查你的脚本文件是否有语法错误游戏启动时控制台会报红字错误。一个稳妥的做法是先只写一条移除命令进游戏测试成功后再添加更多。3.2 添加配方创造与联动添加配方是发挥创意的核心。我们可以创建全新的合成路径将不同模组的物品联系起来。添加有序合成配方 我想添加一个更昂贵的“终极工作台”需要一圈下界合金锭和一个普通工作台。// 添加一个有序合成配方终极工作台 recipes.addShaped(ultimate_crafting_table, item:minecraft:crafting_table.withTag({CustomModelData: 1}), [ [item:minecraft:netherite_ingot, item:minecraft:netherite_ingot, item:minecraft:netherite_ingot], [item:minecraft:netherite_ingot, item:minecraft:crafting_table, item:minecraft:netherite_ingot], [item:minecraft:netherite_ingot, item:minecraft:netherite_ingot, item:minecraft:netherite_ingot] ]);ultimate_crafting_table这是配方的唯一名称标识符可以任意取但最好有意义且不重复。item:minecraft:crafting_table.withTag({CustomModelData: 1})这里用了一个技巧。我们无法直接创建一个名字叫“终极工作台”的新物品但可以利用NBT标签中的CustomModelData配合资源包让同一个工作台物品拥有不同的外观。输出在游戏里看起来还是一个普通工作台但通过资源包可以将其渲染成不同的纹理。如果你想创建真正的新物品需要借助内容添加模组如ContentTweaker。下面的三维数组定义了3x3的合成网格。空位用null表示。添加无序合成配方 我想添加一个配方用1个钻石和8个铁锭无序合成出1个下界合金碎片这显然是个魔改配方。recipes.addShapeless(netherite_scrap_from_diamond, item:minecraft:netherite_scrap, [ item:minecraft:diamond, item:minecraft:iron_ingot, item:minecraft:iron_ingot, item:minecraft:iron_ingot, item:minecraft:iron_ingot, item:minecraft:iron_ingot, item:minecraft:iron_ingot, item:minecraft:iron_ingot, item:minecraft:iron_ingot ]);addShapeless只需要一个一维数组列出所有需要的材料即可顺序无关。3.3 修改配方平衡与整合很多时候我们不想完全移除一个配方而是想调整它的材料。这可以通过“先移除后添加”的组合拳来实现。假设我觉得工业模组Immersive Engineering的“电弧炉”初始造价太高想把其中的“钢块”换成“铁块”。// 首先移除原版电弧炉的配方 recipes.remove(item:immersiveengineering:arc_furnace); // 然后添加我们修改后的配方 recipes.addShaped(cheaper_arc_furnace, item:immersiveengineering:arc_furnace, [ [item:immersiveengineering:steel_scaffolding, item:immersiveengineering:coil_mv, item:immersiveengineering:steel_scaffolding], [item:immersiveengineering:coil_mv, item:immersiveengineering:heavy_engineering, item:immersiveengineering:coil_mv], [item:immersiveengineering:steel_scaffolding, item:immersiveengineering:coil_mv, item:immersiveengineering:steel_scaffolding] ]);在这个修改后的配方里我移除了需要“钢块”的部分用其他更前期的材料钢脚手架、中型线圈替代。你需要根据JEI查看到的原配方精确地规划每个格子的替换物。处理模组机器配方 对于熔炉、切石机等原版设备以及模组添加的各种机器如打粉机、冶炼厂它们的配方不属于工作台合成需要使用专门的接口。以移除和添加熔炉配方为例// 移除铁矿石的熔炉烧炼配方即不能再烧铁矿石得铁锭 furnace.removeRecipe(item:minecraft:iron_ingot); // 通过输出物移除 // 添加一个新的熔炉配方用煤炭块烧制钻石非常魔改 furnace.addRecipe(diamond_from_coal_block, item:minecraft:diamond, item:minecraft:coal_block, 10.0); // 参数说明配方名输出物品输入物品经验值可选每个模组的机器都有自己的接口例如mods.thermal.Smelter.addRecipe热力膨胀的感应炉mods.immersiveengineering.Crusher.addRecipe沉浸工程的粉碎机。你需要查阅CraftTweaker的官方文档或该模组的支持文档来找到正确的接口名和参数格式。4. 高级技巧与模组联动实战当你熟悉了基础操作后就可以尝试一些更高级的技巧来实现复杂的整合包设计逻辑。4.1 使用变量与函数提升效率当你在多个配方中反复使用同一组复杂材料时定义变量可以极大简化脚本也便于后期统一修改。// 定义一些常用的材料组合 val advancedCircuit item:thermal:upgrade_augment_3; // 假设我们定义高级电路 val machineFrame item:industrialforegoing:machine_frame_pity; // 机器框架 // 定义一个函数来添加同一系列机器的配方 function addMachineRecipe(machineName as string, outputItem as IItemStack, middleItem as IItemStack) { recipes.addShaped(machineName, outputItem, [ [advancedCircuit, item:minecraft:redstone, advancedCircuit], [item:minecraft:iron_ingot, middleItem, item:minecraft:iron_ingot], [machineFrame, item:minecraft:gold_ingot, machineFrame] ]); } // 使用函数快速添加多个机器配方 addMachineRecipe(electric_furnace, item:techreborn:electric_furnace, item:minecraft:furnace); addMachineRecipe(grinder, item:techreborn:grinder, item:minecraft:iron_block);这样如果你想调整所有这类机器的合成框架只需要修改advancedCircuit或machineFrame这两个变量的定义或者修改函数体内的合成格局即可无需逐个修改几十个配方。4.2 实现阶段化解锁与合成表替换这是大型整合包的核心设计思想。例如在游戏前期禁用所有高级合金的合成直到玩家解锁了“高炉”科技。// 在游戏开始的脚本中移除高级合金的配方 recipes.remove(item:modern_industrialization:steel_ingot); recipes.remove(item:modern_industrialization:aluminum_ingot); // 然后为高炉添加专属的合金配方这通常需要模组本身支持高炉配方接口 // 假设高炉的接口是 mods.modern_industrialization.BlastFurnace mods.modern_industrialization.BlastFurnace.addRecipe(steel_smelting, item:modern_industrialization:steel_ingot, 100, 1200, [ item:minecraft:iron_ingot * 2, item:minecraft:coal * 1 ]);这样玩家在获得高炉之前无法通过任何途径合成钢锭。他们必须按照你设计的科技树先发展出高炉技术。你还可以配合任务模组如FTB Quests在玩家完成“建造高炉”任务后通过命令或脚本动态加载另一个包含高级合金配方的.zs文件实现真正的阶段化解锁。4.3 跨模组资源统一与替代大型整合包常有功能重复的模组。例如多个模组都添加了铜、锡矿石。为了避免世界生成冗余和玩家困惑通常会统一使用一种矿石并让其他模组的物品能兑换成统一标准的物品。// 假设我们决定以“热力膨胀”的铜锭为标准 val standardCopper item:thermal:copper_ingot; // 移除其他模组铜锭的合成与获取途径这里以“沉浸工程”为例 recipes.remove(item:immersiveengineering:ingot_copper); furnace.removeRecipe(item:immersiveengineering:ingot_copper); // 移除烧炼配方 // 添加兑换配方1个沉浸工程铜锭可以无序合成成1个标准铜锭 recipes.addShapeless(convert_ie_copper, standardCopper, [item:immersiveengineering:ingot_copper]); // 你甚至可以修改矿石的掉落但这通常需要更底层的模组如LootTweaker配合或者使用熔炉配方统一烧炼产物。通过这种方式玩家在探索世界中获得的任何模组的铜资源最终都能汇流到同一个物品上用于你设计的所有合成配方保持了经济系统的一致性。5. 调试、排查与最佳实践实录脚本写完了满怀期待地进入游戏却发现JEI里配方没变或者游戏直接崩溃了。别担心这是每个CraftTweaker使用者都会经历的过程。高效的调试和遵循最佳实践能让你少走弯路。5.1 常见问题与排查技巧问题1脚本加载了但配方没有任何变化。检查点1语法错误。打开游戏目录下的logs/crafttweaker.log文件。这是CraftTweaker的专属日志。如果脚本有错误这里会有明确的错误信息告诉你哪一行、哪个字符出了问题。常见的错误包括括号不匹配、缺少分号、物品ID拼写错误。检查点2配方冲突。你添加的新配方可能与未成功移除的原版配方或其他模组添加的配方冲突。MC通常只显示一个合成途径。尝试在创造模式用你指定的材料摆放一下看是否能合成出物品。检查点3脚本文件未加载。确认你的.zs文件放在了正确的scripts文件夹内在游戏根目录与mods文件夹同级并且没有放在子文件夹里除非你使用了#loader等预处理指令进行了配置。问题2游戏启动时崩溃。检查点1模组版本不兼容。确保CraftTweaker及其依赖的ZenScript模组与你的Forge版本完全匹配。1.18.2的Forge有多个版本如40.2.0, 40.2.10模组通常只兼容一个范围。检查点2脚本中存在致命错误。有时脚本错误太严重会导致加载失败。尝试逐个注释掉脚本文件中的内容在行首加//来定位导致崩溃的特定行。检查点3使用了不存在的物品或方法。如果你引用的模组物品ID错误或者调用的API方法在当前版本不存在也可能导致崩溃。对照模组文档或使用/ct dump命令游戏内输出的物品列表进行核对。问题3配方在JEI中显示但实际无法合成。检查点1NBT标签限制。如果你在配方中使用了带有特定NBT标签的物品如附魔工具那么合成时输入物品必须拥有完全一致的NBT标签。通常在定义配方输入时应尽量避免使用带NBT的物品除非你有特殊需求。使用*通配符可以忽略NBTitem:minecraft:diamond_pickaxe*表示任意耐久的钻石镐。检查点2合成类型错误。你添加的是有序合成 (addShaped)但尝试时摆放成了无序的形状或者反之。仔细检查合成格局数组。5.2 开发流程与最佳实践备份备份备份在开始大规模修改前备份你的saves存档和scripts文件夹。一个错误的脚本可能导致存档物品丢失或损坏。增量开发与测试不要一次性写上千行脚本。写一小段比如移除或添加一个配方就保存文件重启游戏测试。使用print()函数输出调试信息确认脚本段落被正确执行。充分利用/ct命令在游戏中你有权限的情况下可以输入一系列调试命令/ct recipes查看某个物品的所有合成配方。例如/ct recipes minecraft:iron_ingot。/ct hand获取手中物品的完整ID包括NBT直接复制到脚本里使用。/ct syntax检查当前加载的所有脚本是否有语法错误。/ct dump将游戏内所有物品、实体、配方等信息导出为文本文件是编写脚本时最重要的参考资料。代码组织与注释将脚本按功能分文件存放如remove_vanilla.zs,add_machines.zs,tweaks_magic.zs。在每个文件开头和关键段落添加清晰的注释说明这段代码的意图。几个月后当你回头修改时会感谢自己。版本控制如果你使用Git等版本控制工具来管理你的整合包那么scripts文件夹无疑是需要纳入管理的核心部分。每次修改都有记录可以轻松回滚到任何可用的版本。我个人在实际操作中的体会是CraftTweaker最强大的地方不在于它能改变单个配方而在于它能让你像设计师一样从全局视角重构整个模组包的体验。最开始可能会被语法和报错困扰但一旦你成功让第一个自定义配方生效那种“世界规则由我定义”的成就感是无与伦比的。从一个简单的“增加木板合成棍子的数量”开始逐步尝试更复杂的模组联动最终你将能打造出一个拥有独特灵魂、自洽经济系统和引人入胜进程的整合包。记住所有复杂的修改都是由一行行简单的addShaped和remove组成的。动手去试多查文档CraftTweaker的Wiki非常全面多看看热门整合包的脚本是怎么写的你会进步飞快。最后一个小技巧在测试阶段可以把游戏模式设为创造并给自己一个“合成表修改器”之类的模组物品可以随时重载脚本 (/reload命令)而无需重启游戏这会极大提升你的调试效率。
返回列表