合成系统在传奇服务端里算是个老话题,但每年都有人拿着半截脚本跑来问为什么点了没反应。TVZML这类脚本作者做的其实是同一件事:把"检测材料、扣除材料、判断概率、发放成品、给提示"这五个动作拼成一段能直接扔进NPC文本里的完整代码。网上流传的所谓完整合成脚本,大多缺胳膊少腿,要么没写失败分支,要么物品名和数据库对不上。下面把这件事从头拆一遍,代码按GOM、GEE通用写法给,996三端和翎风的差异单独标注。
合成系统本质上只有两条技术路线
先分清楚你手上是哪一种,两者命令完全不通用,混着写必出错。
第一条是M2自带的铸造系统。它不靠CHECKITEM一条条检测,而是由引擎自己去比对"所需物品列表",你只需要在M2界面里配置好配方,脚本里调用三个命令即可。CheckFoundryItem负责检测背包材料是否足够,GiveFoundryItem负责回收材料同时把成品放进背包,ShowFoundryItem用来给玩家看还差什么。配套的还有合成失败后自动执行的@FoundryFail段,以及两个引擎变量:%FoundryItem是当前要合成的物品名,%Item是失败时正在处理的物品名。这条路线的成功率在M2里配置,不是写在脚本里的,100代表必定成功,99是百分之九十九,1是百分之一;要更低的概率就直接填大于100的数,填1000就是千分之一。失败消失那一项也要留意,填1时材料连成品一起没,填0时失败不销毁。
第二条是手写合成脚本。不依赖M2配置,纯靠CHECKITEM、TAKE、GIVE、RANDOM这些通用命令自己搭逻辑。好处是有多少配方就能写多少,逻辑随便加,坏处是每一步都要自己兜底,漏一条检测就等着赔材料。市面上大多数TVZML风格的合成脚本走的是这条路线,因为改起来方便,换个版本拎着走就行。
M2铸造路线的完整脚本
按下面的格式写,注意[@FoundryItem_]和[@ShowItem_]是固定前缀加物品名,引擎会自己解析后缀。
text
;文件放在Mir200\Envir\Market_Def\下,NPC脚本里
[@Main]
#SAY
合成台已经架好了,配方自己看,材料自己放。\\
<合成求婚戒指/@FoundryItem_求婚戒指><查看所需材料/@ShowItem_求婚戒指>\
<合成护身戒指/@FoundryItem_护身戒指><查看所需材料/@ShowItem_护身戒指>\
<合成负载戒指/@FoundryItem_负载戒指><查看所需材料/@ShowItem_负载戒指>\
<退出/@EXIT>
[@FoundryItem_]
#IF
CheckFoundryItem%FoundryItem
#ACT
GiveFoundryItem%FoundryItem
#ELSEACT
ShowFoundryItem%FoundryItem
[@ShowItem_]
#SAY
<$ShowItem>
[@FoundryFail]
#ACT
SENDMSG5合成<%Item>失败,材料已经消耗掉了。
这套写法的精髓在于[@FoundryItem_]后面那个下划线。物品名放在按钮跳转里,引擎把后缀塞进%FoundryItem,你一段代码就能管住所有配方,新增装备不用再写新段落。很多人写不通用,是因为把物品名硬编码进了脚本,结果一个合成项就占十几行。
手写路线的完整脚本
这是真正意义上的完整版,包含主菜单、多配方、材料检测、元宝扣除、概率判定、成功和失败两套反馈,以及配方查看页。
text
;文件位置:Mir200\Envir\Market_Def\合成师-3.txt
;编码必须是ANSI,用UTF-8保存会出各种诡异问题
[@MAIN]
#SAY
装备合成台\\
材料放进背包,元宝准备好,点下面的按钮就行。\\
<赤血魔剑/@HC_赤血魔剑><配方/@PZ_赤血魔剑>\
<开天剑/@HC_开天剑><配方/@PZ_开天剑>\
<乌木剑/@HC_乌木剑><配方/@PZ_乌木剑>\
<屠龙/@HC_屠龙><配方/@PZ_屠龙>\
<退出/@EXIT>
;-----配方查看页-----
[@PZ_赤血魔剑]
#SAY
赤血魔剑配方:\\
罗刹1把\\
攻击力药水1瓶\\
魔法力药水1瓶\\
道术力药水1瓶\\
金砖1个\\
元宝50000\\
成功率70%。\\
<回去合成/@HC_赤血魔剑>\
<返回菜单/@MAIN>
;-----赤血魔剑:成功率70%-----
[@HC_赤血魔剑]
#IF
CHECKITEM罗刹1
CHECKITEM攻击力药水1
CHECKITEM魔法力药水1
CHECKITEM道术力药水1
CHECKITEM金砖1
CHECKGAMEGOLD>49999
#ACT
TAKE罗刹1
TAKE攻击力药水1
TAKE魔法力药水1
TAKE道术力药水1
TAKE金砖1
GAMEGOLD-50000
RANDOM100
#IF
$RANDOM<70
#ACT
GIVE赤血魔剑1
SENDMSG6合成成功,赤血魔剑已经放进背包。
GOTO@MAIN
#ELSEACT
SENDMSG5合成失败,材料已经消耗。
GOTO@MAIN
#ELSEACT
SENDMSG5材料或者元宝不够,凑齐了再来。
GOTO@MAIN
;-----开天剑:成功率50%-----
[@HC_开天剑]
#IF
CHECKITEM屠龙3
CHECKGAMEGOLD>99999
#ACT
TAKE屠龙3
GAMEGOLD-100000
RANDOM100
#IF
$RANDOM<50
#ACT
GIVE开天1
SENDMSG6合成成功,开天剑已经放进背包。
GOTO@MAIN
#ELSEACT
SENDMSG5合成失败,屠龙三把已经消耗。
GOTO@MAIN
#ELSEACT
SENDMSG5需要三把屠龙和十万以上元宝。
GOTO@MAIN
;-----乌木剑:成功率100%-----
[@HC_乌木剑]
#IF
CHECKITEM木剑3
#ACT
TAKE木剑3
GIVE乌木剑1
SENDMSG6合成成功,乌木剑到手。
GOTO@MAIN
#ELSEACT
SENDMSG5三把木剑才能换一把乌木剑。
GOTO@MAIN
;-----屠龙:成功率30%-----
[@HC_屠龙]
#IF
CHECKITEM圣战之刃1
CHECKITEM天书1
CHECKGAMEGOLD>199999
#ACT
TAKE圣战之刃1
TAKE天书1
GAMEGOLD-200000
RANDOM100
#IF
$RANDOM<30
#ACT
GIVE屠龙1
SENDMSG6合成成功,屠龙出炉。
GOTO@MAIN
#ELSEACT
SENDMSG5合成失败,圣战之刃和天书已经消失。
GOTO@MAIN
#ELSEACT
SENDMSG5圣战之刃、天书、二十万元宝,缺一样都不行。
GOTO@MAIN
这段脚本能跑通的关键有三个。RANDOM100先把随机数生成出来,
𝑅
𝐴
𝑁
𝐷
𝑂
𝑀
的取值范围是
0
到
99
,所以
RANDOM的取值范围是0到99,所以RANDOM<70才代表百分之七十。检测段在前、扣除段在后、发放在最后,顺序不能颠倒,否则就会出现"材料扣了但东西没给"的漏洞。每个成功和失败分支都要GOTO回主菜单,不然玩家点完一次就卡死在对话框里。
引擎之间的差异要单独处理
GOM和GEE对上面这套命令的兼容度最高,基本可以照搬。拿不准的命令名,去引擎自带的帮助文档里搜一遍再写,别凭印象。
翎风的语法跟GEE接近,但部分物品检测命令的参数顺序有微调,导入前先用单条命令测一遍。
996三端支持txt和lua双写。纯txt路线和上面差不多,但涉及复杂逻辑建议用lua,因为txt里做循环和数组很难受。996里回收类批量操作可以直接调TakeBagItem,格式是:TakeBagItem物品名收取数量增加元宝增加金币增加泡点增加泡点经验保存数量的变量聚灵珠经验是否显示提示。物品名支持用竖线把多个物品串起来一次处理,这一条在批量合成和批量兑换的场景里能省掉几十行。
变量这一块各家写法也略有差别。自定义变量通常写成N
前缀存数字、
𝑆
前缀存数字、S前缀存文本,引用时用
𝑆
𝑇
𝑅
或
<
STR或<STR(N$变量名)>。开写之前先用变量查询器查一遍,确认你的版本里这些编号没被占用。变量冲突是合成脚本最常见的隐形故障,表现是别的系统莫名其妙跟着乱。
捡取触发式的自动合成
如果你想要玩家一捡到材料就自动合成,不走NPC对话,可以挂在捡取触发上。GOM和GEE支持PickUpItemEX触发段。
text
[@PickUpItemEX]
#IF
CHECKITEMW屠龙3
#ACT
TAKE屠龙3
GIVE开天1
BREAK
#IF
CHECKITEMW木剑3
#ACT
TAKE木剑3
GIVE乌木剑1
BREAK
这里用的是CHECKITEMW,检测的是背包内物品数量,跟CHECKITEM的区别要弄清楚,写错了检测永远不成立。末尾的BREAK是防止一次捡取触发多组合成,少了它可能一件材料被重复判定。
成功率与返材的设计
成功率不是拍脑袋定的。高阶装备的合成链路越长,每一步的成功率就要越低,否则整套经济系统会很快被材料淹掉。可以按档次给:普通装备80到100,稀有装备40到60,顶级装备20到40。
失败返材是留住玩家的重要手段。完全不给返,玩家失败两次就走人;返太多,材料又失去意义。常见做法是返一到两件基础材料,或者在脚本里加一个累积次数变量,连续失败三次后放开一次保底。这类逻辑放在手写路线里最好实现,失败分支里加个INCN$失败次数1,成功时归零,再和阈值比较即可。
M2铸造路线的失败返材更省事,直接在M2界面把失败消失设成0,失败时材料保留,成功时所有所需物品统一消失,这条规则是引擎写死的,不用自己写。
上线前的自检清单
物品名一个字都不能错。GIVE后面跟的名字必须和数据库Items表里的完全一致,中英文括号、空格、符号都得对上,多一个空格就合不出来。写之前从数据库里复制粘贴,别手打。
每个按钮指向的标签都要真实存在。点了没反应,九成是[@xxx]写成了[@xx]或者压根没定义。整段写完后,把所有合法@段列一遍,逐个核对跳转目标。
多物品检测不能写成一条。CHECKITEM伏魔刀+蜡笔之刃+天书这种写法引擎不认,必须拆成三条独立检测,扣除同理,也要一条一条写。
对话里换行用反斜杠,连续两个是空行。漏了或者多打,界面就会挤成一团或者多出空白。
文件编码统一用ANSI。合成脚本里全是中文物品名,编码一乱,检测条件会变成乱码而静默失效,最难查。
改完脚本要重启M2或者重载NPC才生效,只改文件不重载,看到的永远是旧逻辑。
公式和数据库要同步。你在脚本里GIVE的成品,数据库里必须存在,否则合成后背包里是个空名字的物品。
按这套流程走下来,一套合成脚本基本能稳定上线。真正费时间的从来不是写概率那几行,而是物品名核对和跳转路径的完整性检查,这两项过了,脚本不会出大问题。
合成系统本质上只有两条技术路线
先分清楚你手上是哪一种,两者命令完全不通用,混着写必出错。
第一条是M2自带的铸造系统。它不靠CHECKITEM一条条检测,而是由引擎自己去比对"所需物品列表",你只需要在M2界面里配置好配方,脚本里调用三个命令即可。CheckFoundryItem负责检测背包材料是否足够,GiveFoundryItem负责回收材料同时把成品放进背包,ShowFoundryItem用来给玩家看还差什么。配套的还有合成失败后自动执行的@FoundryFail段,以及两个引擎变量:%FoundryItem是当前要合成的物品名,%Item是失败时正在处理的物品名。这条路线的成功率在M2里配置,不是写在脚本里的,100代表必定成功,99是百分之九十九,1是百分之一;要更低的概率就直接填大于100的数,填1000就是千分之一。失败消失那一项也要留意,填1时材料连成品一起没,填0时失败不销毁。
第二条是手写合成脚本。不依赖M2配置,纯靠CHECKITEM、TAKE、GIVE、RANDOM这些通用命令自己搭逻辑。好处是有多少配方就能写多少,逻辑随便加,坏处是每一步都要自己兜底,漏一条检测就等着赔材料。市面上大多数TVZML风格的合成脚本走的是这条路线,因为改起来方便,换个版本拎着走就行。
M2铸造路线的完整脚本
按下面的格式写,注意[@FoundryItem_]和[@ShowItem_]是固定前缀加物品名,引擎会自己解析后缀。
text
;文件放在Mir200\Envir\Market_Def\下,NPC脚本里
[@Main]
#SAY
合成台已经架好了,配方自己看,材料自己放。\\
<合成求婚戒指/@FoundryItem_求婚戒指><查看所需材料/@ShowItem_求婚戒指>\
<合成护身戒指/@FoundryItem_护身戒指><查看所需材料/@ShowItem_护身戒指>\
<合成负载戒指/@FoundryItem_负载戒指><查看所需材料/@ShowItem_负载戒指>\
<退出/@EXIT>
[@FoundryItem_]
#IF
CheckFoundryItem%FoundryItem
#ACT
GiveFoundryItem%FoundryItem
#ELSEACT
ShowFoundryItem%FoundryItem
[@ShowItem_]
#SAY
<$ShowItem>
[@FoundryFail]
#ACT
SENDMSG5合成<%Item>失败,材料已经消耗掉了。
这套写法的精髓在于[@FoundryItem_]后面那个下划线。物品名放在按钮跳转里,引擎把后缀塞进%FoundryItem,你一段代码就能管住所有配方,新增装备不用再写新段落。很多人写不通用,是因为把物品名硬编码进了脚本,结果一个合成项就占十几行。
手写路线的完整脚本
这是真正意义上的完整版,包含主菜单、多配方、材料检测、元宝扣除、概率判定、成功和失败两套反馈,以及配方查看页。
text
;文件位置:Mir200\Envir\Market_Def\合成师-3.txt
;编码必须是ANSI,用UTF-8保存会出各种诡异问题
[@MAIN]
#SAY
装备合成台\\
材料放进背包,元宝准备好,点下面的按钮就行。\\
<赤血魔剑/@HC_赤血魔剑><配方/@PZ_赤血魔剑>\
<开天剑/@HC_开天剑><配方/@PZ_开天剑>\
<乌木剑/@HC_乌木剑><配方/@PZ_乌木剑>\
<屠龙/@HC_屠龙><配方/@PZ_屠龙>\
<退出/@EXIT>
;-----配方查看页-----
[@PZ_赤血魔剑]
#SAY
赤血魔剑配方:\\
罗刹1把\\
攻击力药水1瓶\\
魔法力药水1瓶\\
道术力药水1瓶\\
金砖1个\\
元宝50000\\
成功率70%。\\
<回去合成/@HC_赤血魔剑>\
<返回菜单/@MAIN>
;-----赤血魔剑:成功率70%-----
[@HC_赤血魔剑]
#IF
CHECKITEM罗刹1
CHECKITEM攻击力药水1
CHECKITEM魔法力药水1
CHECKITEM道术力药水1
CHECKITEM金砖1
CHECKGAMEGOLD>49999
#ACT
TAKE罗刹1
TAKE攻击力药水1
TAKE魔法力药水1
TAKE道术力药水1
TAKE金砖1
GAMEGOLD-50000
RANDOM100
#IF
$RANDOM<70
#ACT
GIVE赤血魔剑1
SENDMSG6合成成功,赤血魔剑已经放进背包。
GOTO@MAIN
#ELSEACT
SENDMSG5合成失败,材料已经消耗。
GOTO@MAIN
#ELSEACT
SENDMSG5材料或者元宝不够,凑齐了再来。
GOTO@MAIN
;-----开天剑:成功率50%-----
[@HC_开天剑]
#IF
CHECKITEM屠龙3
CHECKGAMEGOLD>99999
#ACT
TAKE屠龙3
GAMEGOLD-100000
RANDOM100
#IF
$RANDOM<50
#ACT
GIVE开天1
SENDMSG6合成成功,开天剑已经放进背包。
GOTO@MAIN
#ELSEACT
SENDMSG5合成失败,屠龙三把已经消耗。
GOTO@MAIN
#ELSEACT
SENDMSG5需要三把屠龙和十万以上元宝。
GOTO@MAIN
;-----乌木剑:成功率100%-----
[@HC_乌木剑]
#IF
CHECKITEM木剑3
#ACT
TAKE木剑3
GIVE乌木剑1
SENDMSG6合成成功,乌木剑到手。
GOTO@MAIN
#ELSEACT
SENDMSG5三把木剑才能换一把乌木剑。
GOTO@MAIN
;-----屠龙:成功率30%-----
[@HC_屠龙]
#IF
CHECKITEM圣战之刃1
CHECKITEM天书1
CHECKGAMEGOLD>199999
#ACT
TAKE圣战之刃1
TAKE天书1
GAMEGOLD-200000
RANDOM100
#IF
$RANDOM<30
#ACT
GIVE屠龙1
SENDMSG6合成成功,屠龙出炉。
GOTO@MAIN
#ELSEACT
SENDMSG5合成失败,圣战之刃和天书已经消失。
GOTO@MAIN
#ELSEACT
SENDMSG5圣战之刃、天书、二十万元宝,缺一样都不行。
GOTO@MAIN
这段脚本能跑通的关键有三个。RANDOM100先把随机数生成出来,
𝑅
𝐴
𝑁
𝐷
𝑂
𝑀
的取值范围是
0
到
99
,所以
RANDOM的取值范围是0到99,所以RANDOM<70才代表百分之七十。检测段在前、扣除段在后、发放在最后,顺序不能颠倒,否则就会出现"材料扣了但东西没给"的漏洞。每个成功和失败分支都要GOTO回主菜单,不然玩家点完一次就卡死在对话框里。
引擎之间的差异要单独处理
GOM和GEE对上面这套命令的兼容度最高,基本可以照搬。拿不准的命令名,去引擎自带的帮助文档里搜一遍再写,别凭印象。
翎风的语法跟GEE接近,但部分物品检测命令的参数顺序有微调,导入前先用单条命令测一遍。
996三端支持txt和lua双写。纯txt路线和上面差不多,但涉及复杂逻辑建议用lua,因为txt里做循环和数组很难受。996里回收类批量操作可以直接调TakeBagItem,格式是:TakeBagItem物品名收取数量增加元宝增加金币增加泡点增加泡点经验保存数量的变量聚灵珠经验是否显示提示。物品名支持用竖线把多个物品串起来一次处理,这一条在批量合成和批量兑换的场景里能省掉几十行。
变量这一块各家写法也略有差别。自定义变量通常写成N
前缀存数字、
𝑆
前缀存数字、S前缀存文本,引用时用
𝑆
𝑇
𝑅
或
<
STR或<STR(N$变量名)>。开写之前先用变量查询器查一遍,确认你的版本里这些编号没被占用。变量冲突是合成脚本最常见的隐形故障,表现是别的系统莫名其妙跟着乱。
捡取触发式的自动合成
如果你想要玩家一捡到材料就自动合成,不走NPC对话,可以挂在捡取触发上。GOM和GEE支持PickUpItemEX触发段。
text
[@PickUpItemEX]
#IF
CHECKITEMW屠龙3
#ACT
TAKE屠龙3
GIVE开天1
BREAK
#IF
CHECKITEMW木剑3
#ACT
TAKE木剑3
GIVE乌木剑1
BREAK
这里用的是CHECKITEMW,检测的是背包内物品数量,跟CHECKITEM的区别要弄清楚,写错了检测永远不成立。末尾的BREAK是防止一次捡取触发多组合成,少了它可能一件材料被重复判定。
成功率与返材的设计
成功率不是拍脑袋定的。高阶装备的合成链路越长,每一步的成功率就要越低,否则整套经济系统会很快被材料淹掉。可以按档次给:普通装备80到100,稀有装备40到60,顶级装备20到40。
失败返材是留住玩家的重要手段。完全不给返,玩家失败两次就走人;返太多,材料又失去意义。常见做法是返一到两件基础材料,或者在脚本里加一个累积次数变量,连续失败三次后放开一次保底。这类逻辑放在手写路线里最好实现,失败分支里加个INCN$失败次数1,成功时归零,再和阈值比较即可。
M2铸造路线的失败返材更省事,直接在M2界面把失败消失设成0,失败时材料保留,成功时所有所需物品统一消失,这条规则是引擎写死的,不用自己写。
上线前的自检清单
物品名一个字都不能错。GIVE后面跟的名字必须和数据库Items表里的完全一致,中英文括号、空格、符号都得对上,多一个空格就合不出来。写之前从数据库里复制粘贴,别手打。
每个按钮指向的标签都要真实存在。点了没反应,九成是[@xxx]写成了[@xx]或者压根没定义。整段写完后,把所有合法@段列一遍,逐个核对跳转目标。
多物品检测不能写成一条。CHECKITEM伏魔刀+蜡笔之刃+天书这种写法引擎不认,必须拆成三条独立检测,扣除同理,也要一条一条写。
对话里换行用反斜杠,连续两个是空行。漏了或者多打,界面就会挤成一团或者多出空白。
文件编码统一用ANSI。合成脚本里全是中文物品名,编码一乱,检测条件会变成乱码而静默失效,最难查。
改完脚本要重启M2或者重载NPC才生效,只改文件不重载,看到的永远是旧逻辑。
公式和数据库要同步。你在脚本里GIVE的成品,数据库里必须存在,否则合成后背包里是个空名字的物品。
按这套流程走下来,一套合成脚本基本能稳定上线。真正费时间的从来不是写概率那几行,而是物品名核对和跳转路径的完整性检查,这两项过了,脚本不会出大问题。

