传奇服务端M2提示"脚本死循环"或"ScriptDeadLoop",本质是某段NPC/触发脚本陷入了无终止条件的GOTO跳转或WHILE恒真循环,导致引擎反复执行同一代码块无法退出。表现为点NPC没反应、M2Server.exeCPU飙高、角色掉线。按以下步骤定位并修。
一、从M2日志和报错信息锁定问题脚本
出现死循环后第一时间看M2控制台窗口或MirServer\Mir200\Log目录下的Script.log/Error.log,报错行会写明触发死循环的脚本路径和行号,例如:
脚本执行超时:D:\MirServer\Mir200\Envir\QuestDiary\元宝捐献\捐献.txt第38行GOTO@Loop
直接按路径用Notepad++打开对应文件。若日志只提示NPC名无路径,去Mir200\Envir\Market_Def找同名NPC的调用脚本,其CALL引用的QuestDiary文件即为目标。
若无明确日志,死循环多出现在你最近新增或修改过的脚本文件里,优先查这几个目录:
•Mir200\Envir\QuestDiary\——任务和功能分支脚本(最常见)
•Mir200\Envir\Market_Def\——NPC交互脚本(看里面#CALL引向哪个QuestDiary)
-Mir200\Envir\MapQuest_Def\——地图进入/离开触发脚本
•Mir200\Envir\QManage.txt、QFunction-0.txt——登录/攻击/死亡等全局触发
二、脚本里四种典型的死循环写法及修正
①无条件的GOTO跳转回自身(最常见)
错误写法:
[@Main]
#ACT
SENDMSG5欢迎来到游戏!
GOTO@Main←无限跳回自己,必死循环
修正——去掉无意义GOTO,或加条件跳出:
[@Main]
#IFCHECKVARHUMANLoopCnt<3
#ACTSENDMSG5欢迎来到游戏!
INCHUMANLoopCnt1
GOTO@Main
#ELSEACTRETURN
NPC主菜单[@Main]本来就不该写GOTO跳自己,主菜单让引擎自然等待玩家点按钮即可。
②装备回收/物品检测无终止条件的循环
错误写法(未检测背包是否还有该物品):
[@Recycle]
#IFCHECKITEM祖玛戒指1
#ACTTAKE祖玛戒指1
GIVE金币50000
GOTO@Recycle←若玩家一直有这件装备就无限循环
修正——检测剩余数量或用计数上限:
[@Recycle]
#IFCHECKITEM祖玛戒指1
#ACTTAKE祖玛戒指1
GIVE金币50000
INCD01
#IFSMALLD050←最多循环50次
#ACTGOTO@Recycle
#ELSEACTRETURN
③WHILE/WEND条件恒真
错误写法:
WHILE1=1
#ACTMOVMAP0330268
WEND
修正——用变量控制退出或在合适时机BREAK:
SETD00
WHILED0<5
#ACTSENDMSG5测试中…
INCD01
WEND
④标签名拼写错误导致隐式循环
脚本写GOTO@GetRewrd但定义的是[@GetReward],引擎找不到目标标签会默认从头再执行当前段,形成隐式无限重复。逐行核对CALL和GOTO指向的标签名、大小写、有无多余空格。
另外QManage.txt或QFunction-0.txt中若A标签CALLB标签、B标签又CALL回A标签(相互递归),且无Human变量做开关判断也会死循环,需加"是否已处理"的标志位变量阻断二次触发。
三、引擎参数临时缓解与辅助排查
部分版本循环逻辑本身没问题但引擎默认ScriptGotoCountLimit=10太小会误报死循环(如正常的批量回收循环超10次)。可打开Mir200\!Setup.txt找到:
ScriptGotoCountLimit=10
改为:
ScriptGotoCountLimit=5000
保存重启M2Server。这只能消除"假死循环"报错,若脚本真有无条件GOTO跳自己,改再大也没用只是延后崩溃,必须回去改脚本逻辑。
开启脚本调试——在!Setup.txt或Mir.ini设ScriptDebug=1,重启后在Log\ScriptLog.txt能看到每段脚本执行记录,反复刷同标签名就是死循环位置。
四、快速自检口诀
NPC主菜单[@Main]不准写GOTO@Main;所有GOTO跳转必须有#IF条件或计数器限制跳出;回收/遍历类循环必须先检测物品数量或设最大循环次数;相互CALL的两个标签必须靠Human/Global变量做一次性开关;标签名GOTO目标和定义必须完全一致。改完删除D:\MirServer\Mir200\Envir\QuestDiary下对应的.bak备份文件再重启M2测试。
一、从M2日志和报错信息锁定问题脚本
出现死循环后第一时间看M2控制台窗口或MirServer\Mir200\Log目录下的Script.log/Error.log,报错行会写明触发死循环的脚本路径和行号,例如:
脚本执行超时:D:\MirServer\Mir200\Envir\QuestDiary\元宝捐献\捐献.txt第38行GOTO@Loop
直接按路径用Notepad++打开对应文件。若日志只提示NPC名无路径,去Mir200\Envir\Market_Def找同名NPC的调用脚本,其CALL引用的QuestDiary文件即为目标。
若无明确日志,死循环多出现在你最近新增或修改过的脚本文件里,优先查这几个目录:
•Mir200\Envir\QuestDiary\——任务和功能分支脚本(最常见)
•Mir200\Envir\Market_Def\——NPC交互脚本(看里面#CALL引向哪个QuestDiary)
-Mir200\Envir\MapQuest_Def\——地图进入/离开触发脚本
•Mir200\Envir\QManage.txt、QFunction-0.txt——登录/攻击/死亡等全局触发
二、脚本里四种典型的死循环写法及修正
①无条件的GOTO跳转回自身(最常见)
错误写法:
[@Main]
#ACT
SENDMSG5欢迎来到游戏!
GOTO@Main←无限跳回自己,必死循环
修正——去掉无意义GOTO,或加条件跳出:
[@Main]
#IFCHECKVARHUMANLoopCnt<3
#ACTSENDMSG5欢迎来到游戏!
INCHUMANLoopCnt1
GOTO@Main
#ELSEACTRETURN
NPC主菜单[@Main]本来就不该写GOTO跳自己,主菜单让引擎自然等待玩家点按钮即可。
②装备回收/物品检测无终止条件的循环
错误写法(未检测背包是否还有该物品):
[@Recycle]
#IFCHECKITEM祖玛戒指1
#ACTTAKE祖玛戒指1
GIVE金币50000
GOTO@Recycle←若玩家一直有这件装备就无限循环
修正——检测剩余数量或用计数上限:
[@Recycle]
#IFCHECKITEM祖玛戒指1
#ACTTAKE祖玛戒指1
GIVE金币50000
INCD01
#IFSMALLD050←最多循环50次
#ACTGOTO@Recycle
#ELSEACTRETURN
③WHILE/WEND条件恒真
错误写法:
WHILE1=1
#ACTMOVMAP0330268
WEND
修正——用变量控制退出或在合适时机BREAK:
SETD00
WHILED0<5
#ACTSENDMSG5测试中…
INCD01
WEND
④标签名拼写错误导致隐式循环
脚本写GOTO@GetRewrd但定义的是[@GetReward],引擎找不到目标标签会默认从头再执行当前段,形成隐式无限重复。逐行核对CALL和GOTO指向的标签名、大小写、有无多余空格。
另外QManage.txt或QFunction-0.txt中若A标签CALLB标签、B标签又CALL回A标签(相互递归),且无Human变量做开关判断也会死循环,需加"是否已处理"的标志位变量阻断二次触发。
三、引擎参数临时缓解与辅助排查
部分版本循环逻辑本身没问题但引擎默认ScriptGotoCountLimit=10太小会误报死循环(如正常的批量回收循环超10次)。可打开Mir200\!Setup.txt找到:
ScriptGotoCountLimit=10
改为:
ScriptGotoCountLimit=5000
保存重启M2Server。这只能消除"假死循环"报错,若脚本真有无条件GOTO跳自己,改再大也没用只是延后崩溃,必须回去改脚本逻辑。
开启脚本调试——在!Setup.txt或Mir.ini设ScriptDebug=1,重启后在Log\ScriptLog.txt能看到每段脚本执行记录,反复刷同标签名就是死循环位置。
四、快速自检口诀
NPC主菜单[@Main]不准写GOTO@Main;所有GOTO跳转必须有#IF条件或计数器限制跳出;回收/遍历类循环必须先检测物品数量或设最大循环次数;相互CALL的两个标签必须靠Human/Global变量做一次性开关;标签名GOTO目标和定义必须完全一致。改完删除D:\MirServer\Mir200\Envir\QuestDiary下对应的.bak备份文件再重启M2测试。

