GAMELOGICBENCH · PAPER WALKTHROUGH
游戏最后没出错,
不代表中途没违反规则
在给定 Godot 项目里补好玩法,怎样确认每一步都守规则?先认识引擎、节点与物理更新,再看任务、案例与隐藏判分。
72Godot 任务
403手工测试场景
1,451参数化测试用例
52.78%最佳单次结果

GameLogicBench · arXiv:2609.21562v2 · 2026-09-21
02 · PART 0 / GODOTScene 是 Node tree
先把 Godot 想成一棵会运行的组件树
Level.tscn
├─ Player · CharacterBody2D
│ ├─ Sprite2D
│ ├─ CollisionShape2D
│ └─ Camera2D
├─ Enemy · CharacterBody2D
└─ HUD · Control
Node渲染、碰撞、相机、声音和输入等职责由不同节点承担。
Scene保存后的节点树可以像一种新节点那样被重复实例化。
Script脚本挂在节点上,通过回调和 signal 与整个 scene tree 协作。
Godot 4.4 官方文档:Nodes and Scenes。
03 · PART 0 / GDSCRIPT本文 Godot 4.4 示例,非 benchmark 代码
每个物理步读取输入;生命变化时发出事件
extends CharacterBody2D signal health_changed(value: int) @export var speed := 220.0 var health := 3 func _physics_process(_delta: float): var d := Input.get_vector( "left", "right", "up", "down") velocity = d * speed move_and_slide() func take_damage(amount: int): health = max(health - amount, 0) health_changed.emit(health)
每个物理更新步读取输入、更新 velocity,再让引擎处理碰撞与移动。
Signal角色发出 health_changed,UI 可以订阅,而不用被写死在角色逻辑里。
为什么难测节点、回调与物理模拟会共同改变状态,不能只看最后数值。
Godot 4.4 背景示例,需 CharacterBody2D + 碰撞体,并在 Input Map 配 left/right/up/down 动作;不是论文任务。
04 · PART 0 / TICK一次物理更新就是一个可检查时刻
只看终局,会把错误轨迹压成一个正确数字
只看最后一帧
t0
10
10
t1
0
0
t2
10
10
END
10
10
资源先被错误扣空,又被补回。终点与正确实现相同,过程已经违反规则。
→
逐 tick 断言
t0
✓
✓
t1
✕
✕
t2
—
—
END
—
—
在第一次破坏守恒或事件顺序时就失败,不让后续状态掩盖它。
tick = 一次离散仿真更新。数字轨迹为本文解释性示例,不是论文模型日志;依据 §1、§3.1。
05 · MOTIVATIONjudge 是检查运行状态与事件的判分程序
评测需要检查不同场景、全过程,并给出可重复的判定
固定示例不够
一条 preview 能通过,不代表换布局、输入顺序或数值后仍然正确。
最终状态不够
跨帧规则可能中途被破坏,最后又回到看似合法的状态。
录像不够
资源守恒、内部时序和状态继承问题未必直接出现在画面里。
模型 judge 不够稳定
交互选择和打分都含模型判断,重复运行可能给出不同 verdict,成本也高。
论文 §1。作者的目标不是评价美术与体验,而是确定性验证 gameplay logic。
06 · RELATED WORK比较单位:运行中产物的判定方法
最近对照 GameDevBench:由单场景变成多场景过程检查
Benchmark
给定项目 / 提交
判分依据
多 tick
手工场景
GameDevBench
Godot patch
测试脚本
部分
1
JAMER
Godot 生成或修改
引擎验证
否
1
GameCraft-Bench
完整 Godot 游戏
视觉语言模型判断
否
1
GameEngineBench
UE5 patch
测试 + 模型判断
部分
1
GameLogicBench
Godot 两类项目内 patch
引擎状态与事件断言
全部
2–12
按 Table 1 重排:多 tick 表示至少两个运行步,不必每步检查。GameLogicBench 自身协议声明逐步检查;全部任务是给定项目内 patch。
07 · ORIGINAL FIGURE 2任务 → 求解 → 判分 → 结果
Agent 在公开 preview 中调试,judge 在隐藏 scenario 中验收

Figure 2。求解时只准模型 API 出网,judge 完全断网;评分不调用模型。scaffold 是 Claude Code 等提供模型读写与执行工具的框架。
原论文 Figure 2。
08 · TASK TIERStier 表示需要接入多少现有系统
从一个机制,到多个机制,再到真实项目
ATOM
隔离一个机制
在为基准新做的最小游戏中实现寻路、冷却、碰撞等一个功能。
21
COMBO
机制相互作用
时间、空间或同帧请求互相影响;只把每个部件单独做对仍可能失败。
28
REPO
项目规模集成
补未完成系统、移去实现后重写,或在现有约束下新增机制;要读懂调用方、资源与共享状态。
23
论文 §2、Table 2、Appendix G。Repo 共 23 题;伦理说明明确其中 20 题源自开源项目。
09 · INFORMATION BOUNDARYbrief 是任务规则说明;preview 是公开可运行示例
规则和接口公开;具体计分场景与断言代码隐藏
Agent 可见
- 任务 brief 与可修改文件
- 项目代码和接口
- 一个公开场景结构
- 可换随机种子的公开示例
→
Agent 交付
- 指定 GDScript 文件
- 允许范围内的辅助脚本
- 只提交允许修改的文件
- 调试改动不替代冻结 judge
→
Judge 隐藏
- 具体场景与随机种子
- 断言实现
- 调用顺序变化
- 失败归因逻辑
论文 §2.1、§3.1;官方 harness README。
10 · ORIGINAL FIGURE 3人类把关两端,Agent 完成中间工程
一个候选机制要经过筛选、试验、构建、校准和复审

原论文 Figure 3。约 200 个想法 → 122 个完成构建、校准和独立复跑 → 三名标注者录取 72 个。论文未报告标注一致率。
原论文 Figure 3、§2.2–2.3。
11 · CRITERION VALIDATION先验证 judge,再拿 judge 评模型
既要放过不同的正确实现,也要抓住缺一项能力的错误实现
POSITIVE
正确实现
所有 scenario 与 seed 都通过,并远离容差边界。
MUST PASS
NEUTRALITY
等价正确实现
内部写法不同,但可观察行为相同。
MUST PASS
COMMON ERROR
常见错误实现
包含常见逻辑错误,用来证明测试不是只看能否运行。
MUST FAIL
TARGETED ERROR
单能力 mutant
刻意删掉一项能力的代码,至少一个目标场景要抓住它。
MUST FAIL
论文 §2.3。
12 · WHY MUTANTS MATTER正确解通过,不代表 judge 没有漏洞
原检查放过 127/666 个错误实现;修补改变了三份提交判定

127 / 666修补前检查放过的错误实现,暴露 19/36 题中的 24 个缺失检查。
Terminal-only只看终局:236/666 个错误实现漏过;64/488 原失败提交变 PASS,整题通过率增加 64/720 = 8.89 个百分点。
Preview-only只看公开场景:508/666 个错误实现漏过;418/488 原失败提交变 PASS,整题通过率增加 418/720 = 58.06 个百分点。
§4.6、Table 5:720 = 20 配置 × 36 题;488 是完整 judge 下失败提交,uplift 按全部提交计算。
13 · EVALUATION PROTOCOL求解只允许模型 API 出网;判分容器完全断网
Agent 能运行公开示例,不能接触冻结的检查程序
SOLVE container
- 项目、brief、一个公开 scenario
- 可以启动 Godot、换 seed、读调试输出
- 模型 API 可用;其他出网访问被封
- 最终只提交允许的脚本
公开项目 + 允许文件的提交→
JUDGE container
- Agent 工作区的副本
- 冻结的隐藏 judge
- 固定仿真时间步
- 每个场景 × 随机种子逐步断言
同一提交 + 场景 + 随机种子
= 同一判定§3.1;README:game → solution → frozen judge,后者最后覆盖。Task repo 在 2026-09-22 历史核查为 404,不代表今天状态。
14 · TICK-LEVEL ASSERTIONS示意代码,不是官方 judge 源码
同一组规则要在每个隐藏 scenario 和 seed 上保持成立
for scenario in hidden_scenarios: for seed in scenario.seeds: var run = launch_fixed_timestep( scenario, seed) while not run.finished: run.advance_one_tick() assert(resources_are_conserved(run)) assert(event_order_is_legal(run)) assert(no_collision_violation(run)) assert(run.completed_required_goal())
Scenario作者手工定义测试结构,例如接近方向、地图与输入计划。
Seed给场景的数值参数取值;scenario × seed 是一个 case。
Tick在错误刚发生时失败,不让后续状态掩盖它。
按 §3.1 写的不可运行协议伪代码,不是每题官方 checker;未取得具体隐藏断言和容差。
15 · CASE / ATOMEnemy Navigation
到终点还不够:整条轨迹不能碰墙
decide(state)
→ Vector2
Agent 每个物理帧只返回一个移动方向。地图、门洞、起点和终点会随 scenario 与 seed 改变。
来源Appendix F.2 的公开完整任务 brief。
场景程序生成带墙与门洞的地图,结构与参数会变。
动作每个物理步调用提交的
decide,非零方向归一化。观察角色全身是否触墙、是否在时间预算内到达。
PASS:所有 seed 都在时限内到达且从未触墙。先穿墙再到终点仍然 FAIL。
Appendix F.2。中心点能过、身体擦墙的 FAIL 是本文规则推演,非模型日志;brief 未给具体秒数。
16 · CASE / COMBOPlatform Guard
名单包含所有真实坐标;控制器仍必须判断目标是否可见
Platform Guard
每帧返回 move、jump、chasing;intruders 是完整坐标名单,不能直接当作可见目标。
巡逻安静期覆盖 home platform 至少 34%。
可见性距离够近且视线无阻挡;不能追墙后的目标。
地面接近着地接近至 130 世界单位,空中掠过不算。
返回安静后离家不超过 6 秒,再恢复巡逻。
FAIL 推演:塔后访客仍在名单里,直接返回 chasing=id 却不可见,构成 ghost chase(声称追不可见目标)。隐藏 checker 未取得。
Appendix F.3:watch 1,800 帧 = 30 秒、60 Hz;34%、130 世界单位、6 秒均为公开要求。FAIL 为规则示意,非实测日志。
17 · CASE / REPOAMSG Character Movement
补运动组件时,要保持周围动画、相机与控制器所依赖的行为
CharacterMovement
Component.gd
本例移去已有方法体后重写;类、属性、状态字段与签名冻结,动画、相机和控制器依赖它们。
公开示例从 +X 方向走上一个合法高度的台阶。
计分场景从 −X 接近,远处再放一堵超过限制的高墙。
运动行为爬合法台阶,不能把高墙也当成台阶。
其他运动状态步态即时切换、蹲伏、跳跃与减速都要正确;离地 0.1 秒确认前不标为空中状态(airborne)、不施重力。
FAIL 推演:探测固定 +X,公开示例能过;计分改 -X 时卡在台阶。方向与高墙来自论文,错误代码原因是本文示意。
论文 §2.1、Appendix F.4。
18 · ORIGINAL FIGURE 472 题、七类能力与 token 规模
能力按具体规则分类,一个场景可以有多个标签

原论文 Figure 4。一个 scenario 可以属于多个能力类别,所以中间柱状图不能直接相加成 403。
原论文 Figure 4、§2.4。
19 · ORIGINAL TABLE 320 个 model + scaffold 组合
所有 case 通过才算 solved:38/72 = 52.78%

Claude-Opus-5 + Claude Code:38/72;无可判提交也留在分母。每配置一次,Godot 4.4、effort=high、3,600 秒;非稳定排名。
原论文 Table 3、§4.1。
20 · ORIGINAL FIGURE 1更贵不稳定对应更高成功率
相同 solve rate 的配置,总成本最多相差 25 倍

原论文 Figure 1。标线表示成本与解题率的观察关系(cost–performance frontier),不是新评分标准。
原论文 Figure 1、§4.1。
21 · ORIGINAL FIGURE 5Atom → Combo → Repo
范围扩大后,Agent 做了更多运行实验,成功率仍持续下降

Claude Code 下汇总解题率:45.2% → 31.5% → 21.7%;Repo 的代码检查调用明显增加。
原论文 Figure 5、§4.2。
22 · ORIGINAL FIGURE 6工具界面改变调用模式
交互更少不等于一定更好或更差

Codex 的调用量较少,并把检查与执行主要放在 Bash;Claude Code 与 OpenCode 有专用读写工具。
原论文 Figure 6、§4.3。
23 · ORIGINAL FIGURE 8多数失败项目能运行,只是行为不对
引擎基础通常能过,持续决定、空间与时间规则更难

20 配置合并:Engine contract(引擎时钟/求解器)88.75%;持续决定、空间、时间规则 53.4%–58.57%。分母是严格通过全部 seed 的场景。
原论文 Figure 8、§4.5。
24 · ORIGINAL FIGURE 7开放网络后,Repo 题可能退化成检索
四个配置找到并直接复用了上游源码,成绩全部上升

最大变化:Kimi-K3 + Claude Code 从 3 个 Repo 题增至 12 个(+9)。
原论文 Figure 7、§4.7。
25 · ORIGINAL FIGURE 9同一总分背后,解出的题可能完全不同
Repo 不只是平均更难,很多具体任务几乎没人解出

每列是一道任务,每行是一个 model + scaffold 配置,绿色表示该次运行通过整题。
原论文 Figure 9、Appendix C。
26 · TAKEAWAYS把 leaderboard 放回测量方法里理解
可信的 runtime benchmark,要同时验证提交和 judge
judge 选择多个未展示的场景,检查不同输入;逐更新步断言,保留过程错误;刻意错误的实现反查测试,发现检查程序漏判。
74.3%失败场景中,项目能运行但违反玩法规则
21.7%Claude Code 下 Repo 汇总解题率
它不测什么美术、内容深度、整体玩家体验。
当前范围Godot 4.4、GDScript、单容器,无网络同步。
统计边界主表每个配置只有一次完整运行。
公开性边界统一 harness 可见;独立任务库在 2026-09-22 的历史核查返回 404,完整隐藏代码未取得。
论文 · 官方 harness · 图表按 CC BY 4.0 引用