微软的 Mark Russinovich 打造了 DoomPaint,在 MS Paint 中运行真正的 DOOM 没错,你已经看过这些头条了。DOOM 现在也能在 MS Paint 里运行了。但和那个“DOOM 无处不在”的流行梗不同,Paint 并不是在运行游戏。Windows 11 内置的绘图应用只是游戏恰好显示出来的那个画面。
Microsoft Azure 的 CTO Mark Russinovich 在 GitHub 上开发并发布了这个名为 DoomPaint 的项目。他说:“Paint 渲染游戏,但不计算它。Paint 什么也不计算。Paint 从来没有计算过任何东西。这就是这个梗。”
Russinovich 的项目运行的是真正的 ViZDoom 引擎,以无窗口方式渲染每一帧,并通过 Windows 剪贴板把每一帧贴到 Paint 的画布上。
更有意思的是,它还支持完整键盘控制、可用的音效,以及真实的 MIDI 配乐,帧率最高接近 Doom 原生的 35 FPS,最低则到了 Russinovich 所说的“表格级别”。
在 MS Paint 中运行 DOOM。图片来源:WindowsLatest.com我们查看了这个 GitHub 仓库,看看 Windows 剪贴板究竟是如何扛起一个实时游戏引擎而不崩掉的。
默认控制:
与过去两天头条暗示的不同,DoomPaint 并不是第一个把 Doom 画面搬到 Paint 画布上的项目,但早期尝试通常是在单独窗口里运行游戏,再把那个窗口镜像或截屏到 Paint 里,这意味着你其实还是在正常玩 Doom,只是看着它的复制画面出现在别处。
https://www.windowslatest.com/wp-content/uploads/2026/08/Earlier-attempt-of-running-DOOM-in-Paint.mp4DoomPaint 的工作方式不同。它没有第二个 Doom 窗口可看。Paint 的画布就是游戏唯一的显示画面,而且你按下的每个输入都会经过 Paint。
这个引擎是 ViZDoom,一个基于 ZDoom 的分支,专为 AI 和强化学习研究而构建,所以它可以在不开窗口的情况下渲染。Russinovich 的封装会在窗口刚创建时就把它隐藏起来,避免它闪到屏幕上。共享软件版的 DOOM1.WAD 提供第一章内容,包括关卡和原版 Bobby Prince 配乐;之后的地图则回退到 Freedoom,这是一个 BSD 许可的替代 WAD,因为 id Software 并没有把游戏剩余部分免费再分发(即使这么多年过去了也是如此!)
默认分辨率是 640×400,最高 35 帧每秒。如果降到 320×200(Doom 1993 年的真实原生分辨率),帧率就会提升。
https://www.windowslatest.com/wp-content/uploads/2026/08/DoomPaint.mp4在我们查看的一段项目运行视频里,悬浮的已粘贴画面位于 Paint 的常规选区手柄内,底部画布上还能看到经典的 Doom HUD、生命值、弹药、护甲和玩家状态脸,顶部的 Paint 功能区里连 Copilot 按钮也依然可见。
是的,“每一帧都送到剪贴板再粘贴出来”听起来很简单,直到你尝试每秒几十次还不让 Paint 报错为止。

Paint 以异步方式、按自己的节奏读取剪贴板。最直接的方法本应是清空剪贴板,然后用 Windows 标准的 EmptyClipboard 和 SetClipboardData 写入新的图像数据。
但如果每秒做几十次,你最终会在 Paint 还在读取上一帧时就把剪贴板清空。字节会在它读到一半时消失,Paint 于是弹出一个模态“无法完成操作”对话框,导致粘贴失败并让游戏卡住。
我们在项目的 clipserve.py 中看到,Russinovich 的修复方法是停止反复重写剪贴板。Windows 允许应用程序将剪贴板作为带引用计数的 OLE 数据对象来持有,使用 OleSetClipboard 和自定义 IDataObject,并在有人请求时通过 GetData 调用返回数据字节。
https://www.windowslatest.com/wp-content/uploads/2026/08/DoomPaint-is-pasting-overlapping-screenshots-continuously-into-Paint.mp4DoomPaint 在整个会话期间发布一个这样的对象,并在原位更新它发出的帧字节,而不是清空或重写剪贴板。由于该对象带引用计数,已经开始的读取会继续有效,因此竞争条件不再可能发生。每次 GetData 调用还会作为“这一帧已被消耗”的信号供游戏调节节奏,只有在 Paint 确认读完上一帧后才发布下一帧。
DoomPaint 在启动时会自检两种触发粘贴的方式,并选择在当前版本的 Paint 上可用的那一种。首选方法是直接发送一个合成的 Ctrl+V 按键,它不会打开菜单,也不会冒着被其他程序拦截游戏按键的风险。
不过,有些版本的 Paint 会悄悄吞掉合成的 Ctrl+V 按下,因此如果失败,项目就改为通过 Paint 的 UI Automation 菜单触发粘贴;这条路更慢,但更可靠,而且会短暂打开“编辑”菜单。
https://www.windowslatest.com/wp-content/uploads/2026/08/DoomPaint-in-action.-Credit-WindowsLatest.com_.mp4粘贴后的画面会以浮动选区的形式进入 Paint,这也正是项目运行片段里看到的样子。
下一帧粘贴时,会在它到来后自动提交上一帧的浮动选区,这就让每一帧都成为 Paint 撤销历史中的一个永久步骤,而不需要 Russinovich 额外添加任何单独的提交或扁平化操作。
为了防止游戏按键误触 Paint 界面,还需要一个底层 Windows 键盘钩子 WH_KEYBOARD_LL,它会在 Paint 获得焦点时拦截所有游戏按键,并阻止它们传给 Paint。没有这个钩子时,一个误按的方向键就可能关闭已打开的粘贴菜单,并让帧传递冻结几秒。
音效通过 OpenAL 从 ViZDoom 输出,Russinovich 还替换成了更新的 OpenAL-Soft 1.24 版本,因为 ViZDoom 自带的旧版本在你中途切换输出设备时不会跟随默认音频设备,比如插上耳机时。
https://www.windowslatest.com/wp-content/uploads/2026/08/Sound-in-DoomPaint.mp4至于音乐,由于 ViZDoom 移除了 ZDoom 内置的音乐播放功能,另一个模块会从 WAD 文件中提取原始音乐数据,必要时将其从 Doom 的 MUS 格式转换为 MIDI,然后通过 Windows MIDI 音序器循环播放。
这个项目还会自我修复一个非确定性的 Windows 音频 bug:某个设备可能已经打开、看似正常工作,但却悄无声息地根本没有声音。DoomPaint 会在启动时重置一次声音系统以防范这个问题,然后在游玩过程中监测输出,如果你开枪时仍然死一般寂静,就会在几秒内触发第二次重置。
在宣布该项目的 LinkedIn 帖子中,Russinovich 写道,他一直在用 Claude Fable 5 做严肃的研究工作,并觉得它相比 Opus 4.8 有明显提升,还补充说,这个 Doom-in-Paint 项目就是同一天早上“图个乐”用它做出来的。DoomPaint 的 GitHub 提交历史也显示,确实有 AI 编程工具参与了贡献。
虽然是个有趣的项目,DoomPaint 还是解决了 Windows 里的一个真实竞争条件,逆向了 Paint 未公开的剪贴板行为,并绕过了一个音频驱动 bug,而这一切都来自于一位微软员工把 AI 模型当作足够快的原型工具,在业余时间做出的真实系统工作。
DoomPaint 是一个小而刻意搞笑的例子,体现了微软在 Windows 其他部分也在押注的 AI 趋势,尤其是 AI 智能体正越来越多地承担严肃工程工作;这也是 Yusuf Mehdi 在离开微软前最后一年里承诺要继续推进的方向。