调试与常见问题
任务不按预期运行时,按下面的顺序排查,绝大多数问题都能定位。
日志看哪里
用 GoPrint(...) 就够了:它会把日志同时输出到服务器调试日志和前端日志面板。
GoPrint("enabled =", settings.enabled, "items =", #(settings.items or {}))
它支持任意多个参数,会拼成一行;在前端日志面板中还会带上时间、客户端与级别。
「任务已启动,但 Main 一直不执行」
几乎都是 Check() 一直返回 0。按顺序检查:
-
在
Check()里打印判断依据,一次就能看出卡在哪:function Check()local settings = CurrentSettingsGoPrint("enabled =", settings.enabled, "items =", #(settings.items or {}))if not settings.enabled thenreturn 0endreturn 1end -
CurrentSettings是「启动时的快照」(最常见坑)。它只在任务启动那一刻读取一次: 如果你先启动任务、之后再点「提交」改配置,运行中的任务永远看不到新配置,于是条件一直不满足。-
简单做法:改完配置后停止再重新启动任务。
-
需要运行中实时生效:用
GetRoleSettings实时读取(界面保存的配置与任务读取的是同一份, 键名就是任务全名):local TASK_NAME = "作者@任务名" -- 与目录名、.hm.json 保持一致local function loadSettings()local fresh = GetRoleSettings(TASK_NAME) -- 实时值if type(fresh) == "table" and next(fresh) ~= nil thenreturn freshendreturn CurrentSettings -- 兜底:启动快照end配合
GetRoleSettingsVersion(TASK_NAME)判断是否需要刷新缓存,见 VM 全局函数。
-
-
字段名 / 类型不一致:界面里
field = "enabled",代码里就要读settings.enabled;数字字段 可能是字符串,稳妥写法是tonumber(settings.count)。 -
没写
return 1(或其它非 0 值):Check必须显式返回数字。注意返回1会抢占其它任务, 若只是自己干活、不想打扰挂机任务,请返回2之类的其它非 0 值(见运行机制)。
常见报错
| 报错 | 原因 / 解决 |
|---|---|
not found global variable 'CheckTime' | index.lua 顶层没有定义数字类型的 CheckTime |
uiSchema for 'xxx' not found | 已用 RegisterForm 注册,但表单名拼错,或 ui/index.lua 的 Init() 没注册它 |
Undefined global 'xxx'(仅编辑器提示) | lua_types/global.lua 缺少该全局函数签名,同步一次即可,不影响运行 |
attempt to index a nil value | 访问了不存在的字段,用 settings.x or {} / #(list or {}) 兜底 |
界面相关
- 改了
ui/下的 Lua 但界面没变化:在任务面板点「重载」重新加载界面环境,再点「刷新」。 - 主表单的
submitForm不会在「提交」时调用:提交只做「校验 + 保存」;submitForm只有子表单 确认时才会被调用(见表单模块与生命周期)。 - 校验不生效:
validateForm返回非空字符串才会拦截,返回nil表示通过;字段级校验靠字段的validate函数。
运行相关
CheckTime改了没反应:它只在任务启动时读取一次,需要停止后重新启动。- 任务莫名停止:
Delay期间任务被停止会直接结束;Exit()会主动结束任务。 - 函数 / 对象提示未定义:确认它属于当前环境——
Player/Talk等必须在DoLuaString里用 (见游戏原生接口)。
下一步:完整示例。