1. 项目概述从玩家到创作者的蜕变如果你和我一样在《我的世界》里摸爬滚打了几年从最初的挖三填一到后来的自动化红石再到尝试各种模组你可能会发现一个瓶颈模组虽好但总有那么些合成配方让你觉得“差点意思”。也许是某个模组的装备太容易获得破坏了生存的挑战性也许是你想将两个不同模组的材料关联起来创造独一无二的物品又或者你作为服务器管理员需要调整经济系统让某些稀有资源成为硬通货。这时候原版游戏和大多数模组提供的固定合成表就成了限制你想象力的枷锁。CraftTweaker这个听起来就充满“工匠”气息的模组正是打破这层枷锁的钥匙。它不是一个给你新方块或新怪物的模组而是一个强大的“规则修改器”。在1.18这个版本中Minecraft的底层代码和模组生态都发生了显著变化许多旧的教程和方法已经不再适用。网上能找到的教程要么过于零散要么还停留在1.12.2的“远古时代”让想入门的玩家望而却步。我当初也是一头雾水踩了无数坑才慢慢摸清了门道。今天我就把自己在1.18版本中折腾CraftTweaker的经验从环境搭建、脚本编写到实战调试毫无保留地分享出来。无论你是想微调平衡的生存玩家还是致力于打造独特体验的整合包作者这篇教程都能让你从“知其然”到“知其所以然”真正掌控你的合成世界。2. 核心思路与工具链全解析在动手写第一行代码之前我们必须先理解CraftTweaker是如何工作的以及它需要哪些“伙伴”模组的支持。这就像木匠干活前得先认清手里的锯子、刨子和尺子分别有什么用。2.1 CraftTweaker的工作原理不是魔法是桥梁CraftTweaker本身并不直接“创造”或“删除”游戏内的合成配方。它的核心角色是一个高权限的中间人。游戏启动时CraftTweaker会加载玩家编写的脚本文件通常是.zs后缀然后通过这些脚本向游戏的合成管理器发送一系列指令“删除原版木剑的合成表”、“添加一个用钻石块合成下界合金锭的新配方”。游戏本身的合成系统在执行时会优先处理这些由CraftTweaker传达的修改指令。因此你的所有修改本质上是在游戏原有逻辑之上打的一套“合规补丁”兼容性和稳定性非常高。2.2 必备模组生态一个都不能少在1.18版本单独安装CraftTweaker是远远不够的你必须构建一个完整的工具链CraftTweaker本体这是核心提供了基础的脚本解析和执行框架。你需要根据你的Forge版本选择对应的CraftTweaker版本。ZenScript语言支持CraftTweaker使用一种名为ZenScript的自定义脚本语言。它语法类似Java但更简单。从CraftTweaker 7.0.0开始对应MC 1.16ZenScript已内置于本体中通常不需要单独安装。内容注册器模组这是最关键、也最容易出错的一环。在1.18Minecraft修改了物品和方块的注册方式。CraftTweaker需要通过一个“目录”来查找所有可被修改的物品。这个“目录”就是由ContentTweaker或Create这样的模组提供的。对于绝大多数不涉及自创全新物品的配方修改我们依赖的是各个模组自带的“兼容库”。模组专属兼容库你想修改哪个模组的物品通常就需要安装哪个模组的CraftTweaker兼容库。例如你想修改“机械动力”的合成就需要安装Create CraftTweaker想修改“应用能源2”就需要安装AE2 CraftTweaker Integration。这些兼容库的命名通常很直观如[ModName] CraftTweaker或[ModName] Tweaker。一个常见的巨坑就是你写了脚本游戏也不报错但修改就是不生效。十有八九是因为你没装对应模组的兼容库CraftTweaker根本找不到你要修改的那个物品。注意并非所有模组都有官方或第三方的兼容库。在规划你的修改方案前最好先去CurseForge或Modrinth上搜索“[模组名] crafttweaker”确认有可用的兼容库再动手。2.3 开发环境与思维准备我强烈建议你不要直接在生存存档或服务器里边写边试。最佳实践是创建一个纯净的测试世界使用创造模式专门用于测试配方。准备好日志查看工具如Notepad、VS Code等能实时监控日志文件的编辑器。CraftTweaker的所有错误信息都会输出到游戏日志latest.log中。保持耐心脚本编写是典型的“写代码-测试-看日志报错-修改-再测试”的循环。第一次出错很正常关键是学会看日志。3. 脚本编写入门从“Hello World”到第一个合成表让我们抛开理论直接进入实战。所有CraftTweaker脚本都放在游戏目录的scripts文件夹下./minecraft/scripts/。你可以创建多个.zs文件游戏会按字母顺序全部加载。3.1 脚本文件结构与基础语法创建一个新文件命名为first_tweak.zs。我们用最经典的“修改木棍合成”作为起点。// 这是一行注释以双斜杠开头不会被程序执行。 // 脚本文件通常以导入语句开始告诉CraftTweaker我们要用哪些扩展功能。 // 对于原版物品我们通常需要导入“物品”和“合成”相关的类。 // 导入原版物品和合成表处理器 import crafttweaker.api.item.IItemStack; // 代表一组物品如“64个石头” import crafttweaker.api.item.IIngredient; // 代表合成材料可以是物品、标签等 import crafttweaker.api.recipes.ICraftingRecipe; // 代表一个合成配方 // 1. 移除原版工作台木棍合成配方 // 格式recipes.remove(输出物品); recipes.remove(item:minecraft:stick); // item:modid:item_name 是获取物品的标准格式 // 2. 添加一个新的木棍合成配方例如用木板竖着合成 // 格式recipes.addShaped(name, 输出物品, [[材料矩阵]], .key(符号, 材料)); recipes.addShaped(my_stick_recipe, // 配方名称必须唯一用于调试 item:minecraft:stick * 2, // 输出2根木棍 [ [item:minecraft:oak_planks], // 第一行一个橡木木板 [item:minecraft:oak_planks] // 第二行一个橡木木板 // 这样就构成了一个竖着的两格材料 ], .key(p, item:minecraft:oak_planks) // 定义材料符号‘p’代表橡木木板 );代码解析与避坑指南item:minecraft:stick这是ZenScript的物品堆叠表示法。尖括号是必须的。minecraft是模组ID原版物品永远是minecraft。stick是物品ID。你可以在游戏中按F3H开启高级提示框查看物品的完整ID。recipes.remove()这是移除配方最直接的方法。但要注意它会把所有输出为该物品的合成配方都移除包括工作台、熔炉、切石机等所有类型的配方。如果你只想移除工作台合成需要用更精确的recipes.removeShaped或recipes.removeShapeless。recipes.addShaped()添加有序合成工作台合成。参数依次是配方名字符串、输出、材料二维数组、符号映射。材料矩阵是一个3x3的二维数组。每一行用一个方括号[]表示空位用null。上面的例子相当于在工作台第一格放木板第二格正下方放木板。符号映射.key(符号, 材料)。用单个字母代表一种材料使矩阵更清晰。可以定义多个.key。配方名务必起一个独一无二、有描述性的名字例如“my_stronger_pickaxe”。当脚本出错时日志会提示是哪个配方出了问题一个好名字能帮你快速定位。3.2 进阶配方类型详解掌握了基础有序合成我们来看看其他几种常见的配方类型。无序合成Shapeless材料任意摆放类似原版的发酵蛛眼、染料混合。// 添加一个无序合成1个红石粉 1个萤石粉 2个荧石粉 recipes.addShapeless(glowstone_dust_mix, item:minecraft:glowstone_dust * 2, [ item:minecraft:redstone, // 材料1 item:minecraft:glowstone_dust // 材料2 ] );熔炉合成Furnace包括熔炉、高炉、烟熏炉等。// 添加一个熔炉配方用燧石烧制获得经验 // 格式furnace.addRecipe(name, 输出, 输入, 经验值, 烹饪时间); furnace.addRecipe(flint_xp, item:minecraft:experience_bottle, // 输出经验瓶这里只是举例实际可能用其他物品 item:minecraft:flint, // 输入燧石 0.5, // 获得0.5点经验浮点数 200 // 燃烧时间原版烧炼为200 tick10秒 ); // 移除原版圆石烧成石头的配方 furnace.remove(item:minecraft:stone);使用物品标签Tags这是1.13之后版本的核心特性也是让脚本更通用、更兼容的关键。标签代表一类物品例如#minecraft:logs代表所有原木。// 添加一个配方用任意原木合成4个木板 recipes.addShaped(planks_from_any_log, item:minecraft:oak_planks * 4, [ [#minecraft:logs] // 使用标签注意前面有#号 ], .key(l, #minecraft:logs) ); // 这个配方意味着在工作台放任何一个属于#minecraft:logs标签的原木都能合成出4个橡木木板。 // 这极大地增加了配方的兼容性和灵活性。4. 实战打造一个自定义矿物处理系统现在我们综合运用以上知识完成一个中等复杂度的实战案例修改并整合“机械动力”和“沉浸工程”两个模组的早期游戏矿物处理流程。目标移除原版熔炉烧炼矿石获得金属锭的配方。添加一个初期手工“破碎”配方在工作台用锤子自定义或模组工具右键矿石获得2个粗矿碎片。添加一个“洗矿”配方在装满水的炼药锅里用粗矿碎片获得小撮矿物尘。添加一个“熔炼”配方在熔炉里将矿物尘烧制成金属锭。假设我们已经安装了CraftTweaker、Create、Immersive Engineering以及它们对应的兼容库。// 文件ore_processing.zs import crafttweaker.api.item.IItemStack; import crafttweaker.api.item.IIngredient; // 第一部分移除原版配方 // 移除所有原版矿石的熔炉烧炼配方 var vanillaOres [ item:minecraft:iron_ore, item:minecraft:gold_ore, item:minecraft:copper_ore, item:create:zinc_ore, // 机械动力的锌矿 item:immersiveengineering:ore_aluminum, // 沉浸工程的铝矿 item:immersiveengineering:ore_lead ]; for ore in vanillaOres { furnace.remove(ore); // 循环移除避免写多行重复代码 print(已移除矿石熔炼配方: ore.commandString); // 打印日志便于调试 } // 第二部分添加手工破碎配方有序合成 // 假设我们用一个“燧石锤”作为工具它由3个燧石竖排合成 recipes.addShaped(flint_hammer, item:minecraft:flint.withTag({display: {Name: {text:燧石锤,italic:false}}}), // 创建一个有自定义名称的燧石 [ [item:minecraft:flint], [item:minecraft:flint], [item:minecraft:stick] ], .key(f, item:minecraft:flint) .key(s, item:minecraft:stick) ); // 破碎铁矿石的配方 recipes.addShaped(crush_iron_ore, item:create:crushed_iron_ore * 2, // 假设Create模组的破碎铁矿石物品ID [ [item:minecraft:iron_ore, item:minecraft:flint.withTag({display: {Name: {text:燧石锤,italic:false}}})], // 第一行矿石锤子 [null, null] // 下面一行空着模拟右键点击的感觉 ], .key(o, item:minecraft:iron_ore) .key(h, item:minecraft:flint.withTag({display: {Name: {text:燧石锤,italic:false}}})) ); // 为其他矿石添加类似的破碎配方... // 第三部分添加洗矿配方无序合成模拟炼药锅 // 这是一个概念性配方实际炼药锅交互可能需要更复杂的脚本或配合其他模组。 // 这里我们用工作台无序合成来模拟水桶 粗矿碎片 湿矿碎片 空桶 recipes.addShapeless(wash_crushed_ore, [item:create:crushed_iron_ore, item:minecraft:bucket], // 输入粗矿碎片水桶 [item:create:washed_iron_ore, item:minecraft:bucket.withTag({Damage: 0})] // 输出洗过的矿石空桶 ); // 注意原版桶在消耗后变为空桶这里用Damage标签模拟但更严谨的做法是使用NBT或专门物品。 // 第四部分添加熔炼配方 // 烧炼洗过的矿石获得锭 furnace.addRecipe(smelt_washed_iron, item:minecraft:iron_ingot, item:create:washed_iron_ore, 1.0, 200 ); // 也可以为沉浸工程的矿物尘添加直接熔炼配方 furnace.addRecipe(smelt_ie_dust, item:immersiveengineering:ingot_steel, item:immersiveengineering:dust_steel, 0.0, 100 // 粉尘熔炼更快 );这个实战案例的要点与心得循环遍历使用for循环批量处理同类物品如所有矿石能让脚本更简洁避免冗余。NBT标签.withTag()方法用于给物品附加NBT数据比如自定义名称、耐久、附魔等。这是实现“同一个物品ID不同状态”的关键。给“燧石锤”加名字就是为了让它和普通燧石区分开。模拟复杂交互游戏内一些复杂交互如炼药锅洗矿可能无法直接用CraftTweaker实现。这时需要发挥创意用工作台合成来“模拟”这个过程或者寻找能提供相应事件支持的模组如KubeJS在某些方面更强大。调试输出print()函数是你的好朋友。把关键信息打印到日志可以确认脚本是否按预期加载和执行。5. 高级技巧与服务器管理应用当你熟悉了基础操作后下面这些高级技巧能让你的修改更强大、更专业。5.1 条件配方与游戏阶段控制你可以让一个配方只在特定条件下生效例如安装了某个模组或者玩家达到了某个游戏阶段利用GameStages模组。// 仅当安装了“机械动力”模组时添加一个高级合成配方 if (loadedMods.has(create)) { // loadedMods是一个内置对象检查模组是否加载 recipes.addShaped(create_mixer_recipe, item:create:mechanical_mixer, // ... 复杂的材料矩阵 ); print(检测到Create模组已添加高级混合器配方。); } else { print(未检测到Create模组跳过高级配方。); } // 配合GameStages模组只有达到“工程师”阶段的玩家才能合成钻石钻头 // 假设有一个名为“engineer”的阶段 // 这通常需要GameStages的CraftTweaker扩展语法可能略有不同 // recipes.addShaped(diamond_drill_staged, ..., .requireStage(engineer));5.2 合成函数与变量对于重复使用的材料或逻辑可以定义为变量或函数提高代码复用性和可读性。// 定义常用材料变量 val compressedIron item:thermal:iron_plate; // 热力膨胀的铁板 val circuitBasic item:thermal:redstone_servo; // 基础电路 // 定义一个添加机器配方的函数 function addMachineRecipe(machineName as string, output as IItemStack, topRow as IIngredient[], middleRow as IIngredient[], bottomRow as IIngredient[]) { recipes.addShaped(machineName _crafting, output, [ topRow, middleRow, bottomRow ], .key(c, circuitBasic) .key(p, compressedIron) // ... 其他通用键位 ); } // 使用函数添加多个机器配方 addMachineRecipe(pulverizer, item:thermal:machine_pulverizer, [compressedIron, compressedIron, compressedIron], [item:minecraft:iron_ingot, circuitBasic, item:minecraft:iron_ingot], [compressedIron, item:thermal:rf_coil, compressedIron] );5.3 服务器整合包配置实战在服务器环境下CraftTweaker是平衡经济、控制进度的神器。统一货币你可以移除所有模组的“金币”合成只保留一种由服务器定义的稀有物品如“下界之星碎片”的合成配方并让它只能通过任务或兑换获得。控制毕业装备大幅提高最终BOSS级装备或工具的合成成本例如将“创造模式飞行器”的合成材料改为需要击败所有维度BOSS掉落的专属材料。制作任务线通过阶段化配方引导玩家按照你设计的路线发展。例如只有用“机械动力”的粉碎轮处理过的矿石才能进入“沉浸工程”的电弧炉进行下一步冶炼强制玩家体验多个模组。配方冲突解决当两个模组对同一种材料如“钢板”有不同的合成路径时你可以移除其中较不合理或过于简单的一个引导玩家使用你希望的那条科技线。服务器管理心得永远先在本地测试在将脚本应用到服务器之前务必在单人测试世界进行完整测试。一个错误的recipes.remove可能会导致整个合成体系崩溃。版本控制使用Git或其他工具管理你的脚本文件。每次修改都做好注释和备份。当模组或CraftTweaker更新时能快速回滚或比对差异。玩家沟通如果服务器应用了大幅度的配方修改一定要有清晰的公告或游戏内指引如任务书、提示牌。突如其来的变化会让玩家感到困惑和沮丧。性能考量虽然CraftTweaker本身很高效但成百上千个高度复杂的配方尤其是那些使用大量NBT检查或标签查询的配方可能会在玩家打开合成指南时造成轻微的卡顿。优化方法是保持配方逻辑简洁并利用/ct recipes命令在游戏内检查注册的配方数量。6. 故障排除与调试指南脚本出错是家常便饭。学会看日志和调试是你从新手成长为熟练工的关键一步。6.1 读懂错误日志游戏加载失败或配方不生效时第一时间查看logs/latest.log文件。搜索[CraftTweaker]或ERROR关键词。典型错误1语法错误ERROR crafttweaker.api.ScriptLoadException: Error parsing crafttweaker scripts: my_script.zs:15: Missing ) at ;这表示第15行缺少一个右括号。仔细检查该行及上一行的括号是否配对。典型错误2物品找不到ERROR crafttweaker.api.CraftTweakerAPI: Could not resolve item with name thermal:iron_plate这表示CraftTweaker找不到thermal:iron_plate这个物品。可能的原因模组ID写错是thermal还是thermalexpansion。物品名写错是iron_plate还是plate_iron。最重要的没有安装该模组的CraftTweaker兼容库。典型错误3配方重复或冲突INFO crafttweaker.api.CraftTweakerAPI: Successfully added recipe named: my_stick_recipe ... INFO crafttweaker.api.CraftTweakerAPI: Recipe with name my_stick_recipe already exists, skipping.配方名重复了。给每个配方起一个独一无二的名字。6.2 游戏内调试命令CraftTweaker提供了一些有用的游戏内命令需要作弊权限/ct recipes列出所有通过CraftTweaker添加的配方。可以加物品名过滤如/ct recipes minecraft:stick。/ct hand或/ct ih获取你手中物品的完整ID和NBT信息直接复制到脚本里用。/ct syntax检查当前所有脚本文件是否有语法错误。/ct reload重新加载scripts文件夹下的所有脚本。注意这不会重新注册物品某些复杂修改可能需要重启游戏。6.3 常见问题速查表问题现象可能原因解决方案脚本加载无错误但配方不生效1. 没装对应模组的兼容库。2. 配方输出物品ID写错。3. 配方被其他模组或更高优先级的脚本覆盖。1. 检查并安装兼容库。2. 用/ct hand确认物品ID。3. 检查加载顺序或尝试用更具体的移除/添加方法。游戏启动崩溃脚本中存在严重语法错误或引用了不存在的类/函数。查看崩溃报告crash-report定位到出错的脚本文件和行数逐行检查。合成表能合成但物品显示异常或无法使用输出物品的NBT数据设置错误如耐久、损坏值。简化脚本先输出无NBT的基础物品测试。使用.withTag()时确保NBT格式正确可用/ct hand查看正确格式。移除配方无效recipes.remove()移除了所有类型配方但你想移除的可能只是工作台合成。使用更精确的recipes.removeShaped(output, input)或recipes.removeShapeless(output)。服务器与客户端配方不一致脚本文件没有同步到服务器或所有客户端。确保scripts文件夹及其内容在服务器和客户端完全一致。这是服务器管理的常见问题。6.4 我的避坑经验从简到繁不要一开始就写几百行的大脚本。先从一个成功的“修改木棍配方”开始确认整个环境是通的再逐步增加复杂度。善用注释在脚本里用//多写注释说明这个配方是干什么的为什么这么设计。一个月后你自己回头看会感谢当时的自己。备份备份备份在修改任何核心配方如木头、工作台、熔炉前先备份你的脚本和世界。一个错误的循环移除可能导致你连基础工具都无法合成。社区是你的后盾遇到无法解决的问题去CraftTweaker的官方Discord、GitHub仓库或相关的Minecraft模组论坛提问。提问时务必附上你的完整错误日志和相关脚本片段。理解“加载阶段”有些修改必须在特定的游戏加载阶段进行。虽然CraftTweaker大部分操作在init阶段模组初始化完成即可但如果你涉及到更早pre-init或更晚post-init的内容可能需要使用事件监听。对于初学者99%的配方修改在init阶段都没问题。折腾CraftTweaker的过程其实就是从一个游戏玩家转变为游戏设计者的过程。你会开始从“系统”的角度去思考资源的流转、科技的树状结构、玩家的体验曲线。当你在自己的世界里看着玩家们按照你精心设计的、独一无二的合成路线去探索和发展时那种成就感是单纯玩游戏无法比拟的。它可能始于一个“这个合成太不合理了”的小小抱怨最终却带你走进了一个充满创造力的全新维度。