[控场AI]
· 5 分钟阅读· 2,508 字

用Claude Code打造激光射击游戏:摄像头给屏幕打分

用Claude Code打造激光射击游戏:摄像头给屏幕打分

开发者用 Claude Code 两周做出激光射击训练游戏,靠 MCP 暴露原始测量值让 AI 调试物理世界程序。

ScreenPlink 是一款开源激光射击训练游戏,把显示器变成靶子,侧面摄像头识别激光命中像素并打出弹孔,支持九种科目、双枪模式与同屏对战,硬件要求雾面屏、60fps 摄像头和红色激光训练器。整个项目几乎全部由 Claude Code 编写,作者只负责设计、试玩和裁定。真正的难点在于让看不见物理世界的 AI 调试测量程序,为此作者构建进程内 MCP 服务器,只向 AI 返回摄像头帧、检测算术过程等原始测量值而非应用结论,将单次诊断从数小时压缩到约 90 秒。变异测试还揭穿了启动框架从未真正验证的缺陷,326 次变异全部被捕获。核心指标由独立麦克风通道给出:84%-89% 的扳机扣动被检测为射击。

一位开发者用Claude Code在两周内完成了一款名为ScreenPlink的开源激光射击训练游戏:把显示器变成靶子,用激光训练手枪射击,摄像头从侧面拍摄屏幕,实时识别命中像素并打出弹孔。整个项目代码几乎全部由AI代理编写,作者只负责设计、试玩和裁定。这可能是"AI编程"从玩具走向测量物理世界的一次硬核实验。

reddit原帖截图

ScreenPlink的核心思路很直接:你朝屏幕开枪(激光训练枪或装有激光弹壳的真枪),架在显示器旁边的摄像头看着屏幕而非你,应用算出激光点落在哪个像素,在该处"打出"一个弹孔,靶子应声倒下。游戏内置九种训练科目、十五个带计分环的靶形、17发弹匣容量,还支持同屏双人对战。

更花哨的是双枪模式:双手各持一把激光枪,两束激光同时出现在摄像头画面中会被识别为两次独立射击。校准也不需要实弹——程序拍摄自己在显示器上贴的标记点进行自学习,摄像头不必正对屏幕,斜角放置是支持的正常场景。

硬件门槛明确:Windows系统、雾面(防眩光)显示器、60fps摄像头、红色激光训练器。作者特别提醒,镜面屏和电视无法工作。

AI写代码的难点不在游戏逻辑,而在"看不见物理世界"

项目最值得玩味的部分是Claude Code的使用方式。作者的设计原则很清晰:他设计游戏、指挥Claude、朝屏幕开枪、裁定什么算可接受,但没有手写任何代码。真正的挑战并非游戏逻辑,而是让一个看不见显示器、也扣不动扳机的AI代理去开发和调试一个测量物理世界的程序。

为此作者构建了一个进程内的MCP服务器,让Claude能向运行中的应用提问"你测到了什么"。它暴露最新摄像头帧、检测器对每个候选光斑的算术过程(包括被拒绝的候选及原因)、屏幕坐标与摄像头坐标下绘制的内容,以及不抢占全屏窗口焦点的按键和点击注入能力。

关键设计决定是:MCP只返回测量值,绝不返回应用自己的结论——因为应用的结论反复出错。作者提到,程序曾在一行里同时打印"100%的测量射击达到标准"和自己测试点低于阈值的测量数据。这套机制把单次诊断时间从数小时压缩到约90秒。

MCP(Model Context Protocol) 是 Anthropic 于 2024 年底推出的开放协议,用于让 AI 模型以标准化方式访问外部工具和数据源。它采用客户端-服务器架构:AI 代理作为客户端,通过 JSON-RPC 与本地或远程的 MCP 服务器通信,服务器则暴露资源(可读取的数据)、工具(可调用的函数)和提示模板三类能力。相比让模型直接调用硬编码的函数,MCP 的价值在于解耦——同一个服务器可以被不同 AI 客户端复用,且工具描述对模型是自描述的。本文中的"进程内 MCP 服务器"指服务器与应用运行在同一进程空间,因此能直接读取内存中的摄像头帧、检测器中间变量等运行时状态,无需序列化到磁盘或网络,延迟极低。这种设计让 AI 代理得以"窥视"一个它无法物理感知的实时系统。

一个异常逃逸引发的"摄像头背锅"事件

文中记录了一个典型调试案例:某次构建持续提示"请拔掉摄像头"。通过MCP,Claude读取了数秒前0.91毫米的校准结果,重跑自检得到12/12通过,最终把故障定位到一个缺失的美术资源文件——它在绘制处理器内抛出异常。由于异常在"本帧已上屏"信号发出前逃逸,所有等待绘制的超时都被触发,摄像头成了替罪羊。单次启动中出现1722条堆栈回溯,而应用日志里一条都没有。

这个案例说明,当AI代理无法直接观察物理输出时,让它拿到原始测量数据而非结论,是排查跨软硬件问题的有效路径。

让测试真的会失败:变异测试与"就绪"闸门

作者对测试可信度的处理同样值得关注。整个启动测试框架此前一直存在一个缺陷:它在第一次启动后就退出并报告成功,所谓"8/8冷启动"的数字从未被真正测量过。修复方式是变异测试——故意重新引入每个已知故障,并要求对应检查变红。首次运行放入7个故障,3个存活;项目现在在6个运行器上执行326次变异,全部被捕获。

此外,单次成功运行在这里极具误导性:一次校准的留出误差为0.4毫米,下一次在代码未变的情况下变成273毫米。因此项目规定,连续五次干净的冷启动才算"可用",并对"ready"一词设了闸门。

作者给出的"诚实头条数字"也不是测试结果:一个独立麦克风通道单独统计扳机扣动次数,与摄像头检测结果对比,84%到89%的听到扣动被转化为检测到的射击。

变异测试(Mutation Testing) 是一种评估测试套件有效性的技术。其做法是向源代码注入微小的人工缺陷(称为"变异体",如把 > 改成 >=、删除一行、取反条件),然后运行测试:如果测试失败,说明该变异体被"杀死",测试有效;如果测试仍然通过,说明变异体"存活",意味着测试没有覆盖到该缺陷。存活率越高,测试套件的可信度越低。本文中作者首次注入 7 个已知故障,3 个存活,直接暴露了启动测试框架的盲区。变异测试与常规覆盖率指标的区别在于:覆盖率只说明代码被执行过,变异测试才检验断言是否真的能区分对错。代价是计算量大——每个变异体都要完整跑一遍测试,326 次变异在 6 个运行器上并行执行正是为此。

开源与上手方式

ScreenPlink以Apache-2.0协议开源,提供源码和Windows发布版。两种上手方式:下载发布包解压后运行Play.cmd;或用Claude Code打开解压文件夹,让它代为安装配置——发布包内置CLAUDE.md和.mcp.json正是为此准备,Claude会执行摄像头检查、挑出真正对准显示器的那个摄像头、启动应用,然后告诉你是该开枪还是该修哪个物理问题。

项目仓库还详细记录了全部二十条经验教训,对想用AI代理开发软硬件结合项目的开发者来说,这些踩坑记录可能比游戏本身更有参考价值。

#Claude Code#ScreenPlink#激光射击游戏#AI编程#MCP服务器#开源项目#变异测试
分享:

相关推荐