![]()
核心亮點
微軟 Azure CTO Mark Russinovich 開發併發布了一個名爲 DoomPaint 的開源項目,能夠在 Windows 11 的 MS Paint 中運行真正的 DOOM 遊戲。與常見的"DOOM 可以在任何地方運行"的梗不同,這次 Paint 並不是在"運行"遊戲,而是作爲遊戲畫面的顯示器——通過劫持 Windows 剪貼板實現。
項目背景
Russinovich 表示:"Paint 渲染遊戲,但不計算遊戲。Paint 什麼都不計算。Paint 從未計算過任何東西。這就是這個玩笑的精髓。"
該項目在 GitHub 上開源,使用真正的 ViZDoom 引擎(基於 ZDoom 的分支,專爲 AI 和強化學習研究構建),以無頭模式渲染每一幀,然後通過 Windows 剪貼板將畫面粘貼到 Paint 的畫布上。
更令人驚訝的是,項目具備:
完整的鍵盤控制
工作正常的音效
真正的 MIDI 配樂
幀率最高可達 DOOM 原生 35 FPS,最低則降至"電子表格級別"
如何運行 DoomPaint
安裝步驟
訪問 github.com/markrussinovich/DoomPaint 下載項目 ZIP 文件,或使用 Git 克隆
確保 PC 上已安裝 Python
解壓文件夾,雙擊運行 run.bat
首次啓動時會自動創建虛擬環境並安裝依賴,等待完成
安裝完成後 MS Paint 會自動打開
保持 Paint 窗口處於焦點狀態,即可開始遊戲
默認控制鍵位
![]()
技術原理深度解析
與早期"Paint 中的 DOOM"嘗試的區別
過去兩天 headlines 暗示這是首次實現,但實際上 早期的嘗試通常是在單獨窗口運行遊戲,然後通過鏡像或屏幕捕獲將畫面投射到 Paint 中——本質上還是在正常玩 DOOM,只是同時在別處顯示一份拷貝。

DoomPaint 的工作方式完全不同:
沒有第二個 DOOM 窗口
Paint 的畫布是遊戲唯一的顯示器
每個按鍵輸入都通過 Paint 傳遞
![]()
引擎與資源
引擎:ViZDoom(可渲染而不打開窗口)
默認分辨率:640×400,最高 35 FPS
低分辨率模式:320×200(DOOM 1993 年原生分辨率),幀率更高
第一關資源:shareware DOOM1.WAD(包含關卡和 Bobby Prince 原創配樂)
後續地圖:回退到 Freedoom(BSD 許可的替代 WAD)
核心技術挑戰與解決方案
1. 剪貼板競態條件
問題:Paint 異步讀取剪貼板。如果每秒清空並寫入新數據數十次,可能在 Paint 還在讀取上一幀時清空剪貼板,導致 Paint 拋出"無法完成操作"的模態對話框,中斷粘貼並卡住遊戲。

解決方案:在 clipserve.py 中,Russinovich 停止使用重寫剪貼板的方式。Windows 允許應用程序將剪貼板作爲引用計數的 OLE 數據對象擁有,使用 OleSetClipboard 配合自定義 IDataObject,通過 GetData 調用來提供字節數據。
DoomPaint 爲整個會話發佈一個這樣的對象,並原地更新它提供的幀字節,無需清空或重寫剪貼板。由於對象是引用計數的,正在進行的讀取會繼續有效,競態條件不再發生。每個 GetData 調用還兼作"幀已被消費"的信號,遊戲用它來調節節奏——僅在 Paint 確認讀取了上一幀後才發佈下一幀。
2. 不竊取鍵盤輸入的粘貼觸發
DoomPaint 在啓動時自測兩種觸發粘貼的方式,選擇在該 Paint 構建上有效的方式:
首選方法:直接發送合成的 Ctrl+V 按鍵,不打開菜單,不會攔截遊戲鍵。
備選方法:如果某些 Paint 構建靜默吞掉合成 Ctrl+V,則通過 Paint 的 UI Automation 菜單觸發粘貼——較慢但更可靠,會短暫打開 Edit 菜單。
3. 浮動選擇與撤銷歷史
粘貼的幀以浮動選擇的形式來到 Paint,這就是運行片段中顯示的效果。
下一幀的粘貼會自動提交上一幀的浮動選擇,無需 Russinovich 添加任何單獨的提交或扁平化操作——這就是每幀都成爲 Paint 撤銷歷史中永久步驟的原因。
有趣副作用:Ctrl+Z(撤銷)兼作倒帶按鈕,因爲每幀粘貼都是 Paint 歷史中的獨立撤銷步驟,所以死亡後按幾次 Ctrl+Z 可以"撤銷死亡"。
4. 防止遊戲鍵與 Paint UI 交互
需要低級別的 Windows 鍵盤鉤子 WH_KEYBOARD_LL,在 Paint 處於焦點時攔截每個遊戲鍵,阻止其到達 Paint。沒有這個鉤子, stray 的箭頭鍵可能關閉打開的粘貼菜單,使幀傳輸凍結數秒。
5. 聲音系統
音效:通過 OpenAL 從 ViZDoom 輸出。Russinovich 換用了更新的 OpenAL-Soft 1.24 版本,因爲 ViZDoom 自帶的老版本在會話中途切換音頻輸出設備(如插入耳機)時不會跟隨默認音頻設備。
音樂:由於 ViZDoom 剝離了 ZDoom 內置的音樂播放,單獨的模塊從 WAD 文件中提取原始音樂數據,在需要時從 Doom 的 MUS 格式轉換爲 MIDI,然後通過 Windows MIDI 音序器循環播放。
自修複音頻 bug:項目還自我修復了一個非確定性的 Windows 音頻 bug——設備可以打開並看似正常工作,但實際上靜默輸出完全靜音。DoomPaint 在啓動時重置一次聲音系統以防萬一,然後在遊戲過程中監控輸出,如果檢測到開火卻沒有聲音,會在數秒內觸發第二次重置。
保存與文件
隨時保存文件會生成當前幀的 PNG 圖像,因爲 Paint 無法知道它正在渲染的是 1993 年的視頻遊戲!
運行需要 Python,run.bat 會自動構建虛擬環境並安裝依賴
第一關無需單獨購買 DOOM,但將完整的 doom.wad 或 doom2.wad 放入項目的 wad 文件夾可解鎖後續地圖的完整配樂
AI 輔助開發:Fable 5 的功勞
Russinovich 在 LinkedIn 帖子中宣佈該項目時寫道,他一直在使用 Claude Fable 5 進行嚴肅的研究工作,發現它比 Opus 4.8 有明顯改進,並補充說這個 Doom-in-Paint 項目是他在同一天早上"爲了好玩"用它構建的。DoomPaint 的 GitHub 提交歷史顯示了 AI 編碼工具的真實貢獻。
雖然是一個有趣的項目,但 DoomPaint 必須解決:
Windows 中的真實競態條件
逆向工程 Paint 的未文檔化剪貼板行爲
繞過音頻驅動 bug
這體現了微軟員工將 AI 模型視爲足夠快的原型工具,可以在業餘時間進行真正的系統工作——這也是微軟一直在押注的 AI 趨勢,特別是 AI 代理執行越來越嚴肅的工程工作。
總結
DoomPaint 是一個看似荒誕但技術精湛的項目,它展示了:
Windows 剪貼板的強大能力 — 可以承載實時遊戲引擎數據
系統級編程的複雜性 — 競態條件、鉤子、COM 對象引用計數
AI 輔助開發的潛力 — 從概念到可運行原型的時間大幅縮短
經典遊戲的永恆魅力 — DOOM 誕生 30 多年後仍在激發創新
正如 Russinovich 所說:Paint 什麼都不計算,但它可以顯示一切。
更多遊戲資訊請關註:電玩幫遊戲資訊專區
電玩幫圖文攻略 www.vgover.com
