跳到主要内容
返回全部案例

Luanti 千题代码修复评测

玩游戏时,你可能遇到过“穿模”的情况:角色沿着方块边缘向上攀爬,头顶明明有实心方块阻挡,却直接穿了过去。

修复前:角色沿潜行梯穿过实心天花板

这个 Bug 来自开源体素沙盒游戏引擎 Luanti,同时牵涉玩家移动、碰撞检测和历史玩法兼容。官方修复经历了 26 轮代码评审;若由人工完成,预计需要约 3 人天。

这不是一次孤立的演示。我们把同样的验证方式扩展到 Luanti 的 1,000 个真实开源代码任务:分别还原到对应修改发生前的版本,让 Seed-2.1-pro-0915 在看不到官方答案的情况下独立处理。

【待插入视频】

Seed-2.1-pro-0915 如何修复真实代码仓库中的 Bug?

先从出现问题的代码仓库说起。Luanti(原名 Minetest)是一款开源体素沙盒游戏引擎,已有超过 15 年的维护历史,代码量约 38.7 万行。

开头的案例对应 PR #14332:当玩家开启“潜行穿墙”物理属性后,可以沿潜行梯一路向上,穿过顶端的实心方块。

复现步骤很简单:走到预设的潜行梯前,按住左 Shift 和空格向上爬。正常情况下,角色会被天花板挡住;而在修复前的版本中,角色会逐步进入方块,最终站在天花板上方。

这类问题并不是改掉一处判断就能解决。Luanti 维护超过 15 年,玩家移动同时保留新旧两套路径,又叠加了潜行状态、物理属性和节点碰撞盒等规则。同一个穿模现象,可能来自输入处理、状态切换、位置更新或碰撞检测中的任一环节。

更麻烦的是,“潜行穿墙”本身是为了兼容既有玩法而保留的机制,不能因为出现穿模就直接关闭。修复既要挡住头顶天花板,又要保证原有的潜行攀爬仍可使用,并兼顾台阶和自定义碰撞盒等情况。这要求模型先理解行为边界,再决定应该在哪一层修改。

但复现问题并不等于验证模型能力。为确认模型能否独立找到根因,我们先从环境中移除“答案”:以官方修复提交的父提交为基线,为任务生成独立的代码快照。快照中不包含远程仓库、标签和后续 Git 提交历史,模型也无法访问官方修复提交。

Seed-Evolving 能获取的只有修复前的源码,以及用户视角的故障描述、复现步骤和期望行为。官方补丁、官方新增测试,以及 PR 和 Issue 中关于根因与修复方案的讨论,均不在模型可访问的范围内,以下是一些执行过程的细节:

项目

配置

模型与执行方式

Seed-2.1-pro-0915,thinking high,Agent 自主执行

执行工具

oh-my-pi;每个任务使用独立代码工作区

构建环境

Ubuntu 24.04(luanti-dev:u2404)、g++ 13、CMake Debug

模型可见材料

修复前源码,以及脱敏后的故障描述、复现步骤、期望行为和构建配方

验证方式

项目单元测试、补丁审查,以及同一游戏世界中的修复前后复测

模型工作区不包含 solution.json、meta.json、官方补丁、远程仓库引用或后续提交历史。模型实际读取的 task.json 如下。

{
  "task_id": "e1d578a20143",
  "中文标题": "开启潜行穿墙后可沿潜行梯穿过实心天花板",
  "仓库": "luanti-org/luanti",
  "故障描述": "当玩家的物理属性开启了潜行穿墙(sneak glitch)时,可以顺着潜行梯往上爬并直接穿过头顶的实心方块天花板跑到上面去。在旧移动模式下极其容易触发,在新移动模式下也能做到,只是需要多试几次并晃动视角。正常情况下头顶的实心方块应该把玩家挡住。",
  "复现步骤": [
    "用脚本把玩家物理属性设为开启潜行穿墙(先在旧移动模式下测试,再在新移动模式下测试)",
    "搭一座潜行梯(贴墙的潜行上升结构),并在顶端上方放一层实心方块作为天花板",
    "让玩家走到潜行梯底部",
    "同时按住潜行键和跳跃键,沿潜行梯一路向上",
    "观察玩家是否被天花板挡住"
  ],
  "期望行为": "无论是否开启潜行穿墙,玩家沿潜行梯上升时都应被头顶的实心方块挡住,不能穿过天花板到达上层空间。",
  "影响模块": "物理与碰撞",
  "环境": {
    "镜像": "luanti-dev:u2404",
    "基础系统": "ubuntu-24.04",
    "编译器": "g++-13",
    "构建命令": "cmake -B build -DCMAKE_BUILD_TYPE=Debug -DENABLE_LTO=FALSE -DRUN_IN_PLACE=TRUE -DENABLE_GETTEXT=TRUE -DBUILD_SERVER=TRUE && cmake --build build --parallel $(nproc)",
    "测试命令": [
      "./bin/luanti --run-unittests || ./bin/minetest --run-unittests"
    ],
    "基线可构建": true,
    "基线构建耗时秒": 333,
    "基线测试结果": "fail"
  },
  "交付要求": "在给定的仓库快照上定位并修复上述故障。只改必要的代码;不要修改或删除既有测试;修改后需保证项目能编译通过、既有测试不回归。"
}

这里的 fail 不代表项目不能运行。这个历史版本在修改前就有一项与本次穿模问题无关的测试没有通过,因此验收时比较的是修复前后的测试结果。只要修改后没有增加新的失败,再结合游戏内复测确认穿模消失,就可以判断本次修复是否生效。

将这份内容保存为代码快照根目录下的 task.json,再使用下面的等价提示词即可。

请读取根目录的 task.json 和当前 Luanti 源码,独立定位并修复其中描述的“开启潜行穿墙后,可沿潜行梯穿过实心天花板”问题。

要求:
1. 不访问网络、官方 PR 或后续提交,不猜测官方补丁;
2. 保留 sneak_glitch 以及新旧移动模式的既有行为,只修改必要代码;
3. 不修改或删除已有测试;
4. 完成后按 task.json 的构建配方编译并运行可行测试,说明实际验证结果和未覆盖边界。

基线构建与测试命令如下:

cmake -B build -DCMAKE_BUILD_TYPE=Debug -DENABLE_LTO=FALSE -DRUN_IN_PLACE=TRUE -DENABLE_GETTEXT=TRUE -DBUILD_SERVER=TRUE
cmake --build build --parallel
./bin/luanti --run-unittests || ./bin/minetest --run-unittests

手动验证时,面向由实心方块与空气交替组成的潜行梯,同时按住左 Shift 和空格向上爬;随后重复测试。修复前角色能够穿过顶端天花板;修复后应停在实心方块下方,同时原有潜行攀爬仍然可用。

模型如何一步步找到根因?

这个问题没有错误日志直接指向某个文件或函数,模型需要从玩家操作反推代码路径。整个定位过程可以概括为三步:

  1. 1. 从玩家移动逻辑的入口开始,沿潜行状态、潜行梯判断和纵向位置更新逐层向下追踪;
  2. 2. 分别检查新旧两种移动模式,比较常规碰撞检测和潜行抬升的执行顺序;
  3. 3. 抽取两条路径的共同点,确认问题不在某个特定方块,而在于潜行抬升时没有限制角色碰撞盒可到达的最高位置。
Seed-2.1-pro-0915 分别检查新旧移动路径,定位潜行抬升绕过天花板碰撞约束的根因

两条路径触发问题的时序并不完全相同:在新移动模式中,先完成常规碰撞处理,随后潜行抬升又改写Y轴位置;在旧移动模式中,程序先直接更新纵坐标,再进入常规碰撞处理。两者的共同问题是,抬升前没有限制角色碰撞盒可到达的最高位置,因此角色会被逐步推入,甚至穿过天花板。

直接关闭“潜行穿墙”虽然能让现象消失,却会破坏原有玩法;只针对完整方块增加特判,也可能遗漏台阶、自定义碰撞盒等情况。Seed-2.1-pro-0915 的修复是在抬升前检查角色的上移空间:先计算允许到达的最高位置;如果角色碰撞盒会与头顶节点的碰撞盒相交,就将抬升高度限制在天花板下方。这样既保留了原有的潜行攀爬,也覆盖了新旧两条移动路径。

修复完成后,我们在相同的游戏世界和视角下,按照相同的按键顺序复测:修复前,角色会穿过天花板;修复后,角色停在实心方块下方,原有的潜行攀爬仍然可用。这意味着,它完成的不只是一次代码生成,还包括跨文件检索、状态追踪、根因判断和兼容性处理。

修复后:角色停在天花板下方,原有潜行攀爬仍可用

从 8,000 多条合并记录中筛出 1,000 个任务

单个案例可以说明模型能完成一次复杂修复,却不足以衡量它在不同年份、模块和问题类型上的稳定能力。为此,我们从 Luanti 原始仓库的 8,000 多条合并记录出发,逐层筛选并构建了 1,000 个真实任务。

第一阶段是任务初筛:先排除纯文档、翻译、格式调整等维护类修改,再剔除改动过小、规模过大、提交时间过早或缺少可靠问题描述的记录。候选任务的改动规模既要足以检验模型的判断能力,也不能大到需要长期重构才能完成。

第二阶段是补齐上下文并隔离答案:我们汇集每条记录对应的 PR、Issue、讨论和测试信息,再从任务描述中移除文件名、函数名、根因分析和官方修复方案,只保留用户可观察到的故障现象、复现步骤与期望行为。最后,逐项检查任务是否源于真实问题、描述是否自洽、能否独立解决,以及是否仍存在答案泄漏,并综合可复现性、可验证性、素材完整度、难度和画面表现,选出 1,000 个任务,控制各功能模块的样本占比。

从 8,000 多条合并记录到 1,000 个真实任务

最终,任务分为简单、中等、困难三个难度层级,并覆盖界面、渲染、脚本、网络协议、地图生成、物理碰撞、服务端存档、音频等主要模块。

为了批量并行执行,我们将 1,000 个任务拆分到彼此独立的代码工作区。每个任务都通过 oh-my-pi 运行,模型只能获得当前任务经过脱敏的问题描述(含复现步骤与期望行为)和修复前源码;对于复杂任务,还可增加开发与审核环节,最终交付源码修改。任务结束后,我们再从各工作区统一收集结果。验收时,重点判断修复过程是否合理、修复效果是否与官方方案等价,而非代码文本是否逐字相同;对于附带官方测试的任务,则会在模型完成修改后重新运行测试,检查修复是否生效。

除了潜行穿模,这 1,000 个任务还包括背包物品无法丢出、死亡后无法重生、楼梯接缝缺面、液体源悬空、半透明实体消失、按钮边框拉伸、第三人称视角地形缺失等问题。它们覆盖不同年份和模块,每个任务都是一个全新的代码现场。

任务示例覆盖界面、渲染、物理碰撞、地图生成等多个模块

最终结果

在这 1,000 个任务上,Seed-2.1-pro-0915 的可合并正确率约为 82.8%,相较 Seed-2.1 提升约 31 个百分点,超过八成任务的修改通过了这套验收。

从定位修复一处问题,到批量处理跨越不同年份、不同模块的真实代码任务,Seed-2.1-pro-0915 展现的不只是生成代码的能力,更包括理解复杂仓库、追踪问题根因并交付有效修改的能力。

让每一次修改,都成为可靠的答案。

相关链接