当前位置 : 145z游戏站 | 热血传奇 | 技术教程 | 

传奇版本脚本频繁提示脚本死循环原因排查与NPCQuestDiary死循环修复方法

热度:
传奇服务端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测试。
[顶部]