ErrRuntime_InfiniteLoop 深挖:运行时如何判定「死循环」
第 11 课警告过:忘了装出口的 loop 会触发 ErrRuntime_InfiniteLoop。这一页深挖三个问题:这个错误到底怎么判定、为什么「明明没写死循环」也会中招、以及事故发生后去哪里查案。
一、官方定义:一次错误,全设备停摆
官方的运行时错误文档给 ErrRuntime_InfiniteLoop 的定义是:Verse 代码陷入无限循环,导致运行时提前终止。真正让它「贵」的是紧随其后的那条通则:任何运行时错误发生后,该设备之后的所有 Verse 执行都会停止。
注意这里的因果链:不是「那个循环停了」,而是「那台设备的一切 Verse 逻辑从此罢工」。如果你把整张岛的核心玩法都写在一台管理设备里(很多项目正是这么组织的),一个写错的循环就等于全岛的按钮、门、计分、UI 集体失灵——玩家看到的是「游戏坏了」,而不是「某个循环坏了」。这就是第 11 课说「本课的坑比前几课都贵」的原因:编译错误在你机器上炸,运行时错误在玩家面前炸。
判定的直观模型可以这样理解:同步执行的 Verse 代码必须在当前帧内让出控制权——要么跑完,要么在挂起点(Sleep / Await)睡过去。一个既不 break 也没有任何挂起点的 loop,试图在一帧之内转无穷圈,运行时的看门狗数圈数到超限,直接掐断并记账为 ErrRuntime_InfiniteLoop。
判定的直观模型可以这样理解:每一帧里,不等待的那部分 Verse 必须在这一帧内「让路」——要么整段跑完,要么在一个「喘气点」(Sleep 的 Delay、或 Await 等事件)上睡过去。一个既不 Break 跳出、也没有任何喘气点的 loop,想在一帧之内转无穷圈,运行时那条「看门狗」数圈数到超限,就直接掐断、记账为 ErrRuntime_InfiniteLoop。
二、离奇案例:我真的没写死循环!
论坛上有一类著名的申冤帖:「Verse infinite loop runtime error without infinite loop」——代码里明明每圈都有异步等待,照样中招。明明每圈都在等一个动作慢慢做完,照样中招。其中一个被剖析得很透的案例是这样的:开发者写了一个循环,让道具用 MoveTo() 缓慢移动,循环的节奏靠「等移动完成」来控制。正常情况下每圈要花好几秒,天衣无缝。
事故发生在另一段代码中途销毁/隐藏了这个道具:道具一失效,MoveTo() 不再是「花几秒慢慢挪」,而是瞬时完成(无处可动,立刻返回)。于是这个循环的「天然节拍器」消失了——每圈耗时从几秒骤降到几乎为零,循环在一帧之内转满了看门狗的上限,ErrRuntime_InfiniteLoop 应声而至。你没写死循环,但你写了一个节拍依赖外部条件的循环,而外部条件被人抽走了。
社区总结的对策有三条,本质都是「别让循环的节拍寄托在别人身上」:
- 操作前先校验:移动、显隐之前确认道具仍然有效,失效就 break 或跳过;
- 别在移动进行中改可见性/销毁道具:成对操作(开始移动/结束移动)之间不要插入会让前者瞬时完成的动作;
- 给循环上「保底节拍」:在循环里加一个明确的
Sleep,哪怕外部等待失效,每圈也至少歇一口气,把工作摊到多帧。
(案例中的 MoveTo() 为道具移动 API,具体签名此处不展开是道具移动用的官方节点/函数,具体用法这里不展开——# TODO: 以 Verse API Reference 为准。)
循环里每圈都在等一个「要花几秒才完成」的异步操作动作,为什么还可能触发 ErrRuntime_InfiniteLoop?
三、事故之后:去 Creator Portal 查案
线上项目出了运行时错误,不用靠玩家口述复现。Creator Portal(内容服务门户)里,你的项目有一个专门的 Verse 标签页:它把线上发生的运行时错误按类别列出(ErrRuntime_InfiniteLoop 就是类别之一),每条错误附带发生时的 Verse 调用栈——从栈里能直接读出是哪台设备、哪个函数、哪一个循环出的事。
线上项目出了运行时错误,不用靠玩家口述复现。Creator Portal(内容服务门户)里,你的项目有一个专门的 Verse 标签页:它把线上发生的运行时错误按类别列出(ErrRuntime_InfiniteLoop 就是类别之一),每条错误还附带出事时的 Verse 调用栈——那是一串「谁调用了谁」的清单,顺着它能直接看出是哪台设备、哪个函数、哪一个循环出的事。
实用工作流:发布后定期看一眼 Verse 标签页 → 按类别筛出死循环类错误 → 顺着调用栈定位到具体循环 → 对照本页第二节检查它的「节拍」依赖什么。比起在编辑器里瞎猜,这是官方给的正规破案通道。
四、来源
本文整理自官方文档与 Epic 开发者论坛: