一、NPC脚本死循环原因与修复
传奇脚本死循环(M2提示ScriptDeadLoop或NPC对话卡死)基本都是GOTO无出口、标签互相调用、条件恒真导致。引擎默认ScriptGotoCountLimit=10~50次,超了直接报错。
典型错误写法:
[@Loop]
#ACT
SENDMSG5测试中
GOTO@Loop←无条件跳回自己,必死循环
正确加终止条件(计数器法):
[@Loop]
#IF
CHECKVARHUMANS0<5;小于5次才继续
#ACT
SENDMSG5执行第<S0>次
CALCVARHUMANS0+1
SAVEVARHUMANS0..\QuestDiary\测试\计数.txt
GOTO@Loop
#ELSEACT
SENDMSG5循环结束
CLOSE
登录时在[@Login]或NPC的[@main]先MOVS00再进循环。
常见死循环坑位排查:
•@A跳@B,@B又跳@A形成闭环→任一边加变量判断断环
•#IF条件永远为真(如检测不可丢弃物品、CHECKVAR=常量)且无#ELSEACT跳出→执行后设标记变量
-标签名拼错(GOTO@GetRewrd实际标签是@GetReward)→引擎找不到标签默认重跑当前段,表现为隐式死循环
•QFunction-0.txt里@@OnDie之类事件脚本含GOTO回自身→改成交互式触发或加次数限制
临时放宽限制可改Mir200\!Setup.txt中ScriptGotoCountLimit=5000(改完重启M2),但这只是掩盖问题,脚本本身必须加终止条件。
二、人物两点来回跑脚本(NPC触发型)
放在Mir200\Envir\QuestDiary\功能\来回跑.txt,NPC用#CALL调用或在对话里给按钮触发:
[@main]
#IF
#ACT
MOVS00;跑动次数计数器
MOVS1330;A点X
MOVS2330;A点Y(盟重示例)
MOVS3400;B点X
MOVS4400;B点Y(土城示例)
MOVS50;0=去B1=去A
GOTO@DoRun
[@DoRun]
#IF
EQUALS50
#ACT
MAPMOVE3<$STR(S3)><$STR(S4)>;去B点地图3=盟重如不同地图需分开写
DELAY2000
MOVS51
INCS01
GOTO@CheckCount
#IF
EQUALS51
#ACT
MAPMOVE3<$STR(S1)><$STR(S2)>;去A点
DELAY2000
MOVS50
INCS01
GOTO@CheckCount
[@CheckCount]
#IF
LARGES020;来回跑20次后停
#ACT
SENDMSG6来回跑结束
CLOSE
#ELSEACT
GOTO@DoRun
说明:MAPMOVE是瞬移,想走过去用MOVETO地图IDXY(部分引擎支持),WAIT单位毫秒(部分引擎用DELAYCMD)。跑动中按F12或点NPC"停止跑动"可中断——建议NPC对话加#IFCHECK[停止变量]CLOSE做停止开关。
三、假人/怪物两点来回走(服务端MonGen或假人脚本)
假人配置文件Mir200\Envir\DummyConfig\假人名.txt加移动参数实现范围随机走动(非严格两点但够用):
[Move]
MoveRange=15
MoveIntervalMin=3000
MoveIntervalMax=6000
严格两点来回需Robot脚本定时MAPMOVE假人到A再B,参考第二节写法把MAPMOVE对象换成DUMMYMOVE(GOM用MOVETO假人名地图XY或DUMMY系统自带路径点)。
四、人物随机左右走动(区域内随机坐标)
NPC触发让玩家在本地图随机走(挂机类):
[@RandomWalk]
#ACT
MOVRP710;P7=X偏移-10~+10随机
MOVRP810;P8=Y偏移-10~+10随机
INCP7<$X>;当前X+P7=新X
INCP8<$Y>;当前Y+P8=新Y
MOVETO<$MAP><$STR(P7)><$STR(P8)>
DELAY1500
GOTO@RandomWalk
加计数器限制次数防死循环,如LARGES050→CLOSE否则INCS01GOTO@RandomWalk。
死循环牢记一条——凡是GOTO回自身或形成闭环必加变量计数器+#ELSEACT跳出。来回跑脚本用两点坐标交替MAPMOVE配合次数判断即可正常运行不会卡引擎。
传奇脚本死循环(M2提示ScriptDeadLoop或NPC对话卡死)基本都是GOTO无出口、标签互相调用、条件恒真导致。引擎默认ScriptGotoCountLimit=10~50次,超了直接报错。
典型错误写法:
[@Loop]
#ACT
SENDMSG5测试中
GOTO@Loop←无条件跳回自己,必死循环
正确加终止条件(计数器法):
[@Loop]
#IF
CHECKVARHUMANS0<5;小于5次才继续
#ACT
SENDMSG5执行第<S0>次
CALCVARHUMANS0+1
SAVEVARHUMANS0..\QuestDiary\测试\计数.txt
GOTO@Loop
#ELSEACT
SENDMSG5循环结束
CLOSE
登录时在[@Login]或NPC的[@main]先MOVS00再进循环。
常见死循环坑位排查:
•@A跳@B,@B又跳@A形成闭环→任一边加变量判断断环
•#IF条件永远为真(如检测不可丢弃物品、CHECKVAR=常量)且无#ELSEACT跳出→执行后设标记变量
-标签名拼错(GOTO@GetRewrd实际标签是@GetReward)→引擎找不到标签默认重跑当前段,表现为隐式死循环
•QFunction-0.txt里@@OnDie之类事件脚本含GOTO回自身→改成交互式触发或加次数限制
临时放宽限制可改Mir200\!Setup.txt中ScriptGotoCountLimit=5000(改完重启M2),但这只是掩盖问题,脚本本身必须加终止条件。
二、人物两点来回跑脚本(NPC触发型)
放在Mir200\Envir\QuestDiary\功能\来回跑.txt,NPC用#CALL调用或在对话里给按钮触发:
[@main]
#IF
#ACT
MOVS00;跑动次数计数器
MOVS1330;A点X
MOVS2330;A点Y(盟重示例)
MOVS3400;B点X
MOVS4400;B点Y(土城示例)
MOVS50;0=去B1=去A
GOTO@DoRun
[@DoRun]
#IF
EQUALS50
#ACT
MAPMOVE3<$STR(S3)><$STR(S4)>;去B点地图3=盟重如不同地图需分开写
DELAY2000
MOVS51
INCS01
GOTO@CheckCount
#IF
EQUALS51
#ACT
MAPMOVE3<$STR(S1)><$STR(S2)>;去A点
DELAY2000
MOVS50
INCS01
GOTO@CheckCount
[@CheckCount]
#IF
LARGES020;来回跑20次后停
#ACT
SENDMSG6来回跑结束
CLOSE
#ELSEACT
GOTO@DoRun
说明:MAPMOVE是瞬移,想走过去用MOVETO地图IDXY(部分引擎支持),WAIT单位毫秒(部分引擎用DELAYCMD)。跑动中按F12或点NPC"停止跑动"可中断——建议NPC对话加#IFCHECK[停止变量]CLOSE做停止开关。
三、假人/怪物两点来回走(服务端MonGen或假人脚本)
假人配置文件Mir200\Envir\DummyConfig\假人名.txt加移动参数实现范围随机走动(非严格两点但够用):
[Move]
MoveRange=15
MoveIntervalMin=3000
MoveIntervalMax=6000
严格两点来回需Robot脚本定时MAPMOVE假人到A再B,参考第二节写法把MAPMOVE对象换成DUMMYMOVE(GOM用MOVETO假人名地图XY或DUMMY系统自带路径点)。
四、人物随机左右走动(区域内随机坐标)
NPC触发让玩家在本地图随机走(挂机类):
[@RandomWalk]
#ACT
MOVRP710;P7=X偏移-10~+10随机
MOVRP810;P8=Y偏移-10~+10随机
INCP7<$X>;当前X+P7=新X
INCP8<$Y>;当前Y+P8=新Y
MOVETO<$MAP><$STR(P7)><$STR(P8)>
DELAY1500
GOTO@RandomWalk
加计数器限制次数防死循环,如LARGES050→CLOSE否则INCS01GOTO@RandomWalk。
死循环牢记一条——凡是GOTO回自身或形成闭环必加变量计数器+#ELSEACT跳出。来回跑脚本用两点坐标交替MAPMOVE配合次数判断即可正常运行不会卡引擎。

