乍一看,这简直像某种行为艺术。微软Azure首席技术官Mark Russinovich用Windows画图软件,玩起了1993年的经典射击游戏《毁灭战士》。不是把画图当成开发工具,也不是用它来画游戏素材——画图窗口本身就是那块“屏幕”,游戏画面一帧一帧地出现在画布上。

这个项目叫DoomPaint。它并没有真正让画图去执行游戏代码。实际跑游戏的是ViZDoom,一个基于ZDoom、主要为AI研究设计的平台。引擎在后台无界面运行,加载的是初代《毁灭战士》共享版的第一章文件DOOM1.WAD,其他地图则使用BSD许可的Freedoom素材包。

打开网易新闻 查看精彩图片

真正的巧思在于“显示”环节。每一帧渲染完成后,画面被转换成位图放进Windows剪贴板,然后粘贴到画图窗口里,从画布视角看,这是一次合法的文档编辑操作。同时,一个低层级键盘钩子会捕捉玩家的移动、转向、射击、开门等按键指令,确保这些输入只发送给游戏引擎,而不会误触发画图自身的快捷键,即使画图窗口处于激活状态。

让整个过程顺畅跑起来,远比连续狂按Ctrl+V要复杂。Russinovich写道,早期版本反复覆盖剪贴板数据,有时会在画图还没读完当前帧的时候就把下一帧的内容塞了进去,导致画面撕裂或丢失。DoomPaint最终的解决方案是发布一个OLE数据对象,持续更新其中携带的图像字节。画图完成一次读取后,会发信号告知可以准备下一帧画面,从而避开了读写竞态的问题。

画质和流畅度取决于你的电脑配置和选择的渲染分辨率。可选范围从《毁灭战士》原生的320×200一直拉到640×480。引擎在自己的线程里以游戏原生的35Hz频率运行,这意味着显示帧率理论上限是35帧,实际表现还要看机器处理画图合成粘贴图像的快慢。

这种实现方式附带了一些意外好玩的“功能”。因为每一帧都是一次实实在在的画图编辑操作,按下Ctrl+Z可以一帧一帧地倒退浏览刚才的游戏画面。想截图的话,在画图里点“文件→保存”就能得到一张PNG格式的游戏瞬间。项目还包含了初代第一章的背景音乐,从《毁灭战士》的MUS格式实时转成MIDI播放,音效也一并由引擎提供。

Russinovich自己对整个项目的定位说得异常直白:“画图负责渲染游戏,但并不执行计算。画图什么都不计算。画图从来就没计算过什么。这才是这个玩笑的核心。”换句话说,画图在这个链条里扮演的角色,更像是一台被动接收画面的外接显示器,连“播放器”都算不上。

DoomPaint已经以MIT许可证发布在GitHub上。运行它的批处理脚本会自动创建一个Python虚拟环境并安装所有依赖项。因为ViZDoom是直接载入地图,所以没有标题画面、通关演示和游戏内菜单。性能方面,Russinovich坦言有时会跌落到他自己形容的“电子表格级别”。

能让《毁灭战士》跑起来的东西,这些年人们已经折腾出了一个长得离谱的清单。它出现在麦当劳的收银机上,出现在麦当劳的自助点餐屏上,出现在一个15美元的宜家智能灯泡里,出现在Playdate掌机上,出现在《我的世界》里,甚至出现在人机验证验证码里。已故的John McAfee曾宣称“无法破解”的那款加密钱包,也没逃过被塞进《毁灭战士》的命运。更离谱的,还有人让它在一块键盘的单一按键上跑了起来。

从量子计算机到验孕棒的迷你屏幕,从ATM到汽车中控,这台诞生于1993年的游戏机厅怪兽被移植到了当代电子世界的几乎每一个角落。但DoomPaint的有趣之处在于,它不再执着于“让某某设备运行游戏”这条老路,而是把操作系统里一个三十多年来几乎没怎么变过的老牌附件,变成了一个毫无计算能力的画框。你看着那些像素怪物在画图窗口里向你扑来,而画图对自己正在“播放”的游戏毫不知情。