作者 | Kuber Mehta 編譯 | 蘇宓
出品 | CSDN(ID:CSDNnews)
自 1993 年問世以來,《DOOM》(毀滅戰士)早已超越了一款經典射擊游戲的范疇,而是成為“極限移植”的代名詞。從烤面包機、MacBook Touch Bar、智能冰箱,到我們此前報道過的 、,它幾乎無處不在——“It Runs Doom”(萬物皆可跑 DOOM)也因此成為一代程序員的狂歡梗。
最近,這一狂歡再度升級:一位開發者竟然將一款可玩的《DOOM》風格游戲完整封裝進一個二維碼中,掃碼即可在瀏覽器中直接啟動,無需下載,無需安裝。
整個開發僅耗時一周,旨在突破了二維碼在存儲和壓縮方面的極限,展示了將輕量級 Web 應用完全托管于二維碼內的全新可能。
而更令人驚訝的是——整個游戲大小還不到 3KB。
目前,此項目已在 GitHub 上開源:https://github.com/Kuberwastaken/backdooms。
值得注意的是,iPhone、Android 等智能手機無法直接掃描,其只適配于瀏覽器端,需要借助在線二維碼掃描器(https://scanqr.org/),掃描之后的游戲界面如下:
從荒誕構想到技術落地
這個項目由開發者 Kuber Mehta 發起,挑戰是在不超過 3KB 的數據限制下,盡可能還原《DOOM》的游戲體驗。
為什么是 3KB?
Kuber Mehta 解釋說,這是二維碼所能容納的最大文本或二進制數據量。為了對比,原版《DOOM》中“機槍”(chaingun)貼圖就需要約 1.2KB,而這次項目的總容量預算,僅為其兩倍多一點。時下,Kuber Mehta 要在這個限制內完成整款游戲的邏輯與視覺呈現,可謂是極限挑戰。
之所以會萌生這樣的想法,是由于幾年前Kuber Mehta 偶然刷到一位 YouTube 博主matttkc 發布的一條 YouTube 視頻,其曾提出一個瘋狂問題:“你能把一整個游戲塞進一個二維碼里嗎?”
這個設想從此深埋 Kuber Mehta 心底,但他一直沒付諸實踐——“因為我覺得自己可能不夠聰明。”Kuber Mehta 自嘲道。
直到不久前,這個想法再次浮現,他決定不再猶豫,動手一試。可真正開始后,他很快發現:網上幾乎找不到現成的 HTML 版本的 DOOM 實現可供復用。
資源有限的情況下,他退而求其次:“制作一個可玩的、受《Doom》啟發的游戲,其大小不超過三段純文本。”
正如他自己總結的:
“真的太難了,因為我的條件只有這些—— 沒有游戲引擎,只能寫原生 HTML/JS; 沒有素材資源,所有圖形都得代碼生成; 不能用任何庫,因為每個字節都彌足珍貴。 但也正因如此,我學到了太多。”
所以它其實并不是《Doom》本尊——但 Mehta 的游戲確實很有《Doom》的味道。除了從 1993 年原版射擊游戲中汲取靈感外,他還參考了迷因式的“迷離空間”恐怖故事 The Backrooms,于是他的項目被命名為“the backdooms”。
「這是不是一個愚蠢的決定?也許是。但結果酷不酷?毫無疑問——酷炸了!」,Kuber Mehta 說道。
極限代碼壓縮:每一個字節都算數
游戲是用 HTML 編寫的,Mehta 必須讓每個字符都物盡其用。
現實來看,要在二維碼的 2,953 字節容量(QR Code Version 40)內嵌入一款游戲,他需要用到所謂的“壓縮技術”,更準確說,是極限壓縮。
Kuber Mehta 以一段游戲代碼代碼為例,展示了他具體的做法:
html>
如果你沒看到 ,你可能都不敢相信這居然是 HTML。
再看一個例子,原始代碼:
function drawWall(distance) {
const height = 240 / distance;
context.fillRect(x, 120 - height/2, 1, height);
}
壓縮后:
h.fillRect(i,120-240/d/2,1,240/d)
其中變量名都被壓縮為單個字符,注釋也完全消失。“從最終的代碼看上去,有點像《Doom》里的惡魔挨了爆頭一樣令人震撼。”
地圖生成機制
在游戲設計方面,起初,Kuber Mehta 打算采用 16x16 或 8x8 的固定小地圖設計,這種尺寸在一個超小型游戲中本就算得上“合理”。但他并不滿足于此,更希望玩家能獲得“真正可玩”的體驗。
因此,他決定引入無限地圖生成,并輔以“種子(Seed)”機制。
這一做法與《Minecraft》中世界生成的思路類似:一個看似隨機的字符串,就能決定整個游戲世界的布局。
Kuber Mehta 利用了這一原理,讓玩家理論上可以通過特定種子值生成心儀的地圖,并在代碼中硬編碼,從而每次運行都得到一致的世界:
SEED = Math.random() * 100;
在圖形表現方面,Kuber Mehta 沒有采用 WebGL 或 Canvas 的高級圖形接口,而是回歸原點,用了《DOOM》早期版本(1992 年)使用的光線投射(Raycasting)技術。這種方法以極低的資源消耗,模擬出類似 3D 的視覺效果。
其實現方式是:對屏幕上每一列像素投出一條方向略有偏差的射線,并計算這條射線與墻體的交點距離。墻體越近,繪制的柱狀圖形就越高,最終呈現出縱深感。
簡版代碼如下:
for (let i = 0; i < 320; i++) {
const rayAngle = playerAngle + (i - 160) / 500;
let distance = 0;
while (!isWall(x + distance * cos(rayAngle), y + distance * sin(rayAngle))) {
distance += 0.1;
}
drawColumn(i, distance);
}
雖然這一邏輯只涉及基礎的三角函數,但它在整個代碼體積中占據了相當大的比重。Kuber Mehta 坦言,如果不是為了動態生成地圖,他可能早就選擇直接將 HTML 頁面 Base64 編碼后塞進 URL。但現在看來,這份堅持是值得的。
敵人機制
相比圖形渲染,敵人系統的實現則更加艱難。項目早期版本中,敵人數量固定,分布于地圖初始區域。玩家一旦走遠,地圖就變得空空如也——這在小地圖中還能接受,但在無限生成的大地圖中,問題立刻凸顯。
Kuber Mehta 回憶,這部分開發過程“非常頭痛”。在體積受限的前提下,想做出像樣的射擊反饋與敵人 AI,幾乎是不可能完成的任務。他也坦言自己并不是游戲開發出身:“我……確實不太會做游戲。”
起初,敵人是完全靜止的。后來,他陸續加入了簡單的追蹤機制,并最終實現了一個核心改進:玩家在移動時,系統會在其附近隨機生成敵人,從而讓整個地圖始終保持緊張感和挑戰性。
if ((k.ArrowUp || k.w || k.ArrowDown || k.s || k.ArrowLeft || k.ArrowRight) && e.length < 10 && Math.random() < .01) {
t = Math.random() * 6.283;
Rdist = 1 + Math.random();
X = x + M(t) * Rdist;
Y = y + N(t) * Rdist;
f(~~X, ~~Y) == "0" && e.push({ x: X, y: Y, h: 100 });
}
完成以上版塊之后,Kuber Mehta表示,“制作游戲只是挑戰的一半,因為真正的挑戰是將其放入二維碼中。”
概念與可行性
標準最大的二維碼(Version 40)最多只能容納 2,953 字節,也就是大約2.9KB。這個容量有多小?做個對比:
一個僅 1/15 秒的 Windows 音效文件,就已經11KB
一張傳統軟盤(1.44MB)理論上可以存下將近 500 個這樣的二維碼
面對如此限制,Kuber Mehta 的首個版本大小達到了3.4KB,超標嚴重。他的第一反應是:“完蛋了。”
為了解決這個問題,他連續四天進行瘋狂壓縮與優化,最終將游戲壓縮至2.4KB,雖然過程中做出了一些艱難但必要的取舍。
殊不知,一段折騰之后,更難的還在后面。
要知道二維碼只能存儲文本或二進制數據,而 HTML 并不屬于這兩種類型。直接嵌入 HTML 代碼并不可行。
對此,不少開發者建議采用 Base64 編碼,但這帶來了33% 的體積開銷,幾乎會吃掉本就所剩無幾的存儲空間,意味著實際可用空間不到 1.9KB。
在反復嘗試后,Kuber Mehta 一度陷入絕望,甚至想要放棄。
后來,他連續兩天輪番咨詢 ChatGPT、DeepSeek 和 Claude 等 AI 模型,嘗試上百種提示詞,幾乎每次都得到建議:“干脆托管在網站上會更容易。”直到某次,ChatGPT隨口提到了一句:DecompressionStream。
這成了轉折點。
DecompressionStream 是一個現代瀏覽器支持的 Web API,能夠解壓 gzip 格式的數據流,簡而言之,相當于瀏覽器內置了“WinRAR”。
Kuber Mehta 形容自己當時“仿佛被雷劈中”,豁然開朗。他確信:在嘗試了幾乎所有極限游戲優化技巧后,這是當前環境下唯一可行的解決方案。
整個游戲壓縮嵌入流程如下:
輸入 HTML 內容
進行 Gzip 壓縮(最大壓縮等級)
將壓縮數據進行 Base64 編碼
嵌入一個自解壓的 HTML 包裝器
轉為 data:URI
嘗試生成二維碼(使用最高版本)
如果仍超出體積限制
→ 回頭繼續壓縮優化
成功生成二維碼!
Kuber Mehta 為此還編寫了一個 Python 腳本自動化完成上述流程,期間測試了34 個不同版本,不斷調試壓縮策略,最終,二維碼成功誕生。
未來的可能性
受以上種種限制影響,the backdooms 的畫面非常有限,你只會在灰色墻壁之間躲避紅眼矩形,但它傳達的“感覺”是到位的。
在 Kuber Mehta 看來,這不僅是一個小游戲的誕生,更是一個技術可能性的證明。他將這個項目(現已開源在 GitHub,https://github.com/Kuberwastaken/backdooms)視為一種宣言:
只要壓縮得當,再加上 AI 助力,即便是在二維碼這種極限載體上,也能運行真正的交互式游戲。
盡管不適合開發復雜項目,但這個方向打開了許多令人興奮的應用場景。Kuber Mehta 表示,這種想法也可以在未來應用在更多場景中,如:
離線游戲傳播:可通過海報、傳單分享
極限編程展示(Demoscene):作為編程創意作品展示平臺
低帶寬環境下的教育小游戲:無需聯網即可運行,具備實用性與趣味性
https://github.com/Kuberwastaken/backdooms?tab=readme-ov-file
https://kuber.studio/blog/Projects/How-I-Managed-To-Get-Doom-In-A-QR-Code
https://www.pcgamer.com/hardware/behold-a-single-qr-code-containing-a-miniaturized-take-on-doom-literally-the-entire-game/
https://news.ycombinator.com/item?id=43729683
CSDN創始人蔣濤「對談」 浙大求是特聘教授方興東。作為中國互聯網30年的見證者,從鴻蒙操作系統的艱辛破曉之路,聊聊中國高科技的崛起大時代。華為數百人深度分享的技術傳奇《鴻蒙開物》來了!直播間抽福袋,領「限定簽章版」。
特別聲明:以上內容(如有圖片或視頻亦包括在內)為自媒體平臺“網易號”用戶上傳并發布,本平臺僅提供信息存儲服務。
Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.