Minecraft 的畫面幾乎沒有什麼技術含量的樣子:一格一格的方塊,16×16 畫素的貼圖,沒有複雜的光影,人物也是幾個長方體拼起來的。第一次看到它的人,多半會覺得“這個我上我也行”。
可它偏偏是 2009 年才出現的,而且最早是 Markus Persson(Notch)一個人業餘時間寫的。在它之前,3D 遊戲已經發展了十幾年,《雷神之錘》《半條命》畫面複雜得多,卻沒有一款遊戲讓玩家把整個世界一塊一塊地拆掉、再蓋起來。
另一邊,今天的電腦和手機算力早已過剩,瀏覽器裡也有了 WebGL、WebGPU,但我們開啟網頁玩的 3D 遊戲仍然不多,Minecraft 的完整版也不能直接在瀏覽器裡跑。
於是有了幾個問題:
- Minecraft 的玩法是從哪來的?
- 如果這個玩法這麼好,早期的 3D 遊戲為什麼沒有這麼做?
- 一個幾乎無限大、還能隨便改的世界,記憶體怎麼裝得下?
- 為什麼偏偏是 2009 年、一個人做出來的?
- 算力這麼充沛的今天,瀏覽器為什麼還是很難“原生”地跑這種遊戲?自己寫一個最小版本,難在哪裡?
- 這樣一個方塊世界,為什麼又成了 AI 智慧體研究的考場?
本文就順著這幾個問題往下講。寫到第五個問題時,我們會真的寫一個能在瀏覽器裡玩的最小版 Minecraft,大約 500 行程式碼,就嵌在第五節裡,也可以單獨開啟。
一、玩法的來源
現象:先火的是另一款遊戲
2009 年 4 月 29 日,Zach Barth(後來做了《太空化學》等程式設計解謎遊戲的 Zachtronics)釋出了一款免費遊戲 Infiniminer。它是一個多人方塊遊戲:兩隊礦工在地下挖礦,比誰挖到的礦石更值錢1。
有意思的是,Barth 設計的是競技,玩家卻很快發現了另一種玩法:不挖礦了,拿方塊蓋房子12。
不到一個月,Barth 就放棄了這個遊戲。原因很樸素:它不賺錢;他沒有混淆原始碼,程式碼被反編譯後流傳出去,外掛和魔改版氾濫,他也沒有精力去修12。最後他把原始碼開源,停止了開發。
原因:Minecraft 補上了什麼
同一年 5 月,Notch 開始寫一個叫 Cave Game 的原型,它借鑑了 Infiniminer 的方塊風格、第一人稱視角和建造機制1。他之前做過一個叫 RubyDung 的專案,混合了《地下城守護者》《矮人要塞》和《過山車大亨》的想法3。2009 年 5 月 17 日,第一個公開版本放了出來4。
和 Infiniminer 比,Minecraft 多了兩樣東西。第一樣是玩法上的:後來陸續加入的單人生存、合成,以及一個幾乎無限大的世界,玩家有了自己找事做的理由(這是我的歸納)。第二樣是生意上的:它從一開始就收錢。2009 年 6 月 13 日,還在 Alpha 階段的 Minecraft 就開始以約 10 歐元的價格出售,不到一個月賣出了 1000 多份35。Notch 後來說:“我想,如果我不收錢,我就永遠拿不到錢。”3 到正式版之前,近 200 萬玩家買了 Alpha 和 Beta,收入超過 3300 萬美元5。
所以玩法本身並不是 Notch 憑空發明的,它是 Infiniminer 的玩家先“玩”出來的。可如果這個玩法這麼吸引人,為什麼十幾年的 3D 遊戲史裡,沒有人先做出來?
二、可編輯世界的渲染代價
現象:早期 3D 遊戲的世界是“死”的
回想一下 2000 年前後的 3D 遊戲:門只能在劇情需要時開啟,牆炸不開,地面挖不動。火箭筒打在牆上,最多留一個彈孔貼圖。
原因:顯示卡擅長畫的是“提前做好”的三角形
1990 年代末,3D 加速卡普及,它們加速的是一件事:把大量三角形畫到螢幕上。
顯示卡是怎麼畫一個三角形的?它拿到的是三個頂點的座標,然後分三步走:先把每個頂點的三維座標換算成螢幕上的位置(頂點著色);再算出這三個點圍成的區域蓋住了螢幕上哪些畫素(光柵化);最後給每個被蓋住的畫素算出顏色(片元著色)。為什麼偏偏是三角形?因為三個點一定在同一個平面上,判斷一個畫素在不在它裡面也最簡單。人物、地形、汽車,任何形狀在交給顯示卡之前,都要先拆成一堆三角形。
方塊也不例外。一個方塊有 6 個正方形的面,每個正方形沿對角線切開就是 2 個三角形,所以一個方塊要畫 12 個三角形。具體寫法是:每個面給出 4 個角的座標,再用一串索引告訴顯示卡哪三個點組成一個三角形,比如 0,1,2 和 0,2,3 就是把 v0、v1、v2、v3 這個正方形切成兩半。本文後面寫的演示就是這麼做的。
注意圖裡左下角那句話:顯示卡並不知道“方塊”是什麼,它只看到三角形。“方塊”只存在於遊戲自己的資料裡。遊戲要先把方塊翻譯成三角形交給顯示卡,方塊一變,三角形也得跟著重新生成。
當時的遊戲為了在有限的硬體上跑得動,會把關卡儘量提前算好:哪些區域能互相看見、牆上的光照,都在製作關卡時預先計算並烘焙進資料裡,執行時直接用(例如《雷神之錘》的 BSP 和光照貼圖)。
這套辦法的前提是:世界不會變。一旦玩家能隨手挖掉一塊牆,這些預計算的結果就全部失效,三角形本身也要重新生成,這些都得在執行時完成。對當時的硬體來說,這代價太大了。
第一次嘗試:體素和區域性破壞
其實早就有人想過用“方塊”來表示世界。1992 年,NovaLogic 的 Voxel Space 引擎在直升機遊戲《科曼奇》裡用體素(volume pixel,體積畫素)渲染地形,靠的是 CPU 軟體渲染6。Build 引擎的作者 Ken Silverman 從 2000 年起也寫過體素引擎 Voxlap7。但顯示卡加速的是三角形,不是體素,這條路在主流遊戲裡就邊緣化了。
另一條路是在三角形世界裡做有限的破壞。2001 年的《紅色派系》用 Geo-Mod 引擎讓玩家炸開岩石和建築,被認為是第一款允許玩家非指令碼化地改變關卡的遊戲。但它原本計劃讓一切都能破壞,最後因為技術難度,以及要引導玩家走完線性關卡,範圍被縮小了8。
這兩次嘗試分別說明了兩件事:體素這種資料結構適合表示可以改的世界,但顯示卡不會直接畫它;在三角形世界裡做破壞可以,但做不到“全部”。
解決:把方塊轉成三角形,只畫露在外面的面
Minecraft 的辦法是把兩者接起來:世界用方塊存,畫的時候把方塊轉成三角形。
最直接的轉法是每個方塊畫 6 個面。但仔細想想,兩個相鄰方塊貼在一起的那兩個面,永遠不會被看見。只畫“旁邊是空氣”的面,數量會少得驚人。0fps 的一篇經典文章給過一個例子:一個 8×8×8 的實心方塊堆,每塊畫 6 面是 3072 個四邊形;去掉被擋住的面後只剩 384 個;如果再把同一平面上相鄰的面合併成大矩形(貪心網格,greedy meshing),只需要 6 個9。
更關鍵的是第二點:世界被分成一個個區塊(chunk),每個區塊單獨生成一塊網格。玩家挖掉一個方塊,只需要重建這一個區塊的網格,而不是整個世界。“提前算好”的思路沒有被拋棄,只是從“整個關卡算一次”變成了“每個區塊在它變化時算一次”。
能畫了,但一個幾乎無限大的世界,光是存方塊的資料,記憶體裝得下嗎?
三、無限世界的資料與生成
現象:世界大到不可能存下來
Minecraft 的世界在水平方向上可以走出幾千萬格。如果每個方塊佔 1 個位元組,哪怕只存地面以下幾十層,也是一個天文數字。
第一次嘗試:二維高度圖
最直覺的辦法是不存方塊,只存“每個位置的地面有多高”,用一張二維的噪聲圖(柏林噪聲)算出來。Notch 早期的地形就是這樣生成的。但他很快發現了問題:“這種方法不可能生成任何懸垂的地形”10。一張高度圖上,每個位置只有一個高度,懸崖下面的凹洞、拱橋、洞穴都表示不出來。
解決:區塊、按需生成和確定性
Notch 後來的做法有三個要點10:
- 按區塊生成、儲存、載入和渲染。當時的區塊大小是 16×16×128。
- 用三維噪聲當作“密度”:噪聲值為負的地方是空氣,非負的地方是地面。這樣就能生成懸崖和洞穴。全解析度的三維取樣太慢,還會產生懸空的碎塊,最後是降低取樣解析度再插值解決的。
- 確定性:地形“無論玩家從哪個方向走過來,都必須是一樣的”。同一個種子、同一個座標,永遠算出同樣的方塊。
第三點帶來一個很漂亮的推論:沒去過的地方不用存,去過但沒改過的地方也不用存,因為它們隨時可以從種子重新算出來。真正需要儲存的只有玩家改過的那些方塊。世界的大小和記憶體的大小就這樣脫了鉤,玩家周圍一圈區塊在記憶體裡,其餘的要麼還沒生成,要麼存在硬碟上。它的世界也因此“不是無限的,但也沒有硬性邊界”:走得太遠,浮點精度不夠,物理就開始出錯,這就是玩家口中的“遠境”(Far Lands)10。
技術上的幾塊拼圖到這裡都齊了。那為什麼是 2009 年,而且是一個人做出來的?
四、為什麼是 2009 年
這一節沒有一個確定的答案,下面是我把史料拼起來之後的推斷。
硬體。一個 16×16×128 的區塊有 32768 個方塊,每塊按 1 位元組算就是 32 KB,加上光照等附加資料還要更多。玩家周圍載入幾百個區塊,光方塊資料就是幾十 MB,還沒算網格。1990 年代末的家用電腦記憶體普遍只有幾十到一百多 MB,到 2009 年已經是幾 GB(這裡的記憶體數字是我的估計,沒有找到統一的統計)。同樣的設計放在十年前,大機率跑不起來。
分發和收錢。Minecraft 用 Java 寫,同一份程式碼能在 Windows、Mac、Linux 上跑3,早期版本甚至直接在網頁裡以 Java applet 的形式執行4。玩家用 PayPal 付 10 歐元買一個沒做完的遊戲,這在今天叫“搶先體驗”,Minecraft 正是把這種模式帶火的遊戲之一,Steam 的搶先體驗欄目要到 2013 年才上線5。一個人不需要發行商,也能靠沒做完的遊戲養活自己。
行業。2000 年代的大作賣的是內容:劇情、關卡、畫面。一個可以隨便改的世界和精心設計的線性關卡是衝突的,《紅色派系》就是因為要引導玩家走完關卡才縮小了破壞範圍8。大公司沒有理由去做一個“沒有關卡”的遊戲,這件事只能由一個不需要對發行商負責的獨立開發者來做。
有一個細節很有意思:Minecraft 的 Classic、Indev、Infdev 三個早期階段都是在瀏覽器裡玩的,直到 2010 年 7 月的 Alpha 才有了獨立的客戶端4。Infdev 的名字就來自“infinite”,正是無限世界加入的那個階段。
Minecraft 最早就跑在瀏覽器裡,為什麼今天瀏覽器裡反而很難看到這樣的遊戲?
五、瀏覽器裡的方塊世界
現象:官方只放出了 2009 年的版本
2019 年 Minecraft 十週年時,Mojang 在網頁上重新放出了 Classic 版:只有創造模式,32 種方塊,沒有怪物11。完整的現代版至今不能直接在瀏覽器裡執行。
原因:瀏覽器為安全付出的代價
外掛時代結束了。當年網頁裡的 Minecraft 靠的是 Java 外掛,Flash 遊戲和 Unity 網頁遊戲也都依賴瀏覽器外掛(NPAPI)。出於安全和穩定性的考慮,Chrome 在 2015 年 9 月徹底移除了 NPAPI 支援,Unity 也隨之建議開發者改用 WebGL12。Java 寫的 Minecraft 從此不能在網頁裡直接跑,要跑就得用 JavaScript 或 WebAssembly 重寫。
圖形介面來得晚。WebGL 對應的是手機上的 OpenGL ES,能力比桌面的圖形介面落後一代。更現代的 WebGPU 在 Chrome 113 首發,直到 2025 年 11 月,Chrome、Edge、Firefox、Safari 才都支援了它,而且 Linux、安卓上的 Firefox 等平臺還在路上13。
沙箱的限制。網頁裡的程式碼不能隨意訪問系統,這是瀏覽器的底線,也是遊戲的麻煩:
- 網頁不能直接開 TCP 連線。開源的網頁版客戶端 mcraft.fun 能連上真正的 Minecraft 伺服器,靠的是先用 WebSocket 連到一個代理,再由代理去連伺服器1415。
- WebAssembly 的多執行緒依賴
SharedArrayBuffer,而在 Spectre 漏洞之後,瀏覽器要求頁面設定“跨域隔離”的響應頭才能用它16,這會影響頁面嵌入第三方內容。 - 32 位 WebAssembly 最多用 4 GB 記憶體。64 位記憶體(Memory64)已在 Chrome 133 和 Firefox 134 上線,但因為每次訪存都要額外做邊界檢查,可能慢 10% 到一倍以上17。
- 網頁的儲存有配額,空間緊張時可能被瀏覽器清掉,存檔放在這裡並不踏實。
沒人投錢。Epic 在 2019 年 12 月的虛幻引擎 4.24 裡把 HTML5 平臺移出了引擎,交給社群維護。一家做網頁匯出工具的公司的聯合創始人評價說,Epic 只支援 WebGL 1,“並不想投很多錢讓它變得可用”,而且遊戲動輒幾個 GB,本來就是“頻寬大戶”18。
所以瀏覽器跑不好大型 3D 遊戲,主要不是算力問題,而是安全模型、標準進度和商業動機一起決定的。
第一次嘗試:用現成的方案
想在瀏覽器裡玩 Minecraft,今天有幾條路:
- 官方的 Classic 版,免費,但只是 2009 年的樣子。
- 雲遊戲:遊戲跑在伺服器上,瀏覽器只收畫面。能玩完整版,但它不是在瀏覽器裡“跑”的。
- 開源的 mcraft.fun:用 TypeScript 重寫的相容客戶端,Three.js 渲染,能連 1.8 到 1.21.5 的伺服器1415。它最接近“瀏覽器原生”,但不支援模組,大場景下也會吃力。
這些方案說明瀏覽器能跑方塊世界,但都沒回答我們的問題:如果只要最基礎的玩法,自己從頭寫一個,到底難在哪?
解決:寫一個最小版本
我們寫了一個最小方塊世界,只依賴 Three.js,用 WebGL2 渲染,原始碼約 500 行。它就嵌在下面,點一下畫面就能玩:
接下來看它是怎麼寫的。
整體結構:一個主迴圈,兩個讀寫入口
整個程式圍繞一個 frame() 函式轉。瀏覽器每次準備重新整理螢幕時(通常每秒 60 次)呼叫它一次,它按固定順序做四件事:
function frame(now) { const dt = Math.min((now - last) / 1000, 0.05); // 这一帧过了多少秒,最多按 0.05 算 last = now;
updateChunks(); // 1. 补齐视距内还没建网格的区块 stepPlayer(dt); // 2. 重力、走动、碰撞 camera.position.set(player.pos.x, player.pos.y + EYE, player.pos.z); updateTarget(); // 3. 准星指着哪个方块 renderer.render(scene, camera); // 4. 交给 Three.js 画出来
requestAnimationFrame(frame); // 预约下一帧}(為了好讀,這裡省掉了出生保護、空閒時停畫和 HUD 統計。)
dt 封頂 0.05 秒是個小細節:如果某一幀卡了半秒,玩家不會在這一幀裡一下子掉落好幾格、直接穿過地面。
鍵盤滑鼠這些事件不在主迴圈裡處理,它們只改狀態:按鍵記進 keys 集合,滑鼠移動改視角,點選時呼叫 setBlock 挖或放。主迴圈下一幀讀到新狀態,自然就動起來了。
所有對世界的讀寫都只經過兩個函式:讀用 getBlock,寫用 setBlock。生成網格、碰撞檢測、找準星,讀的都是 getBlock;挖和放,寫的都是 setBlock。
主迴圈之外,main.js 從上到下分成五段,正好對應圖 4 右邊的資料和左邊的四個步驟。把函式體都省掉,整個檔案的骨架是這樣的:
// 1. 世界数据const chunks = new Map(); // "cx,cz" → Uint8Array(16×16×64)function getChunk(cx, cz) {} // 查不到就调用 generateChunk 现算function getBlock(wx, wy, wz) {} // 世界坐标 → 区块 → 数组下标
// 2. 地形生成function heightAt(wx, wz) {} // 四层噪声叠出地面高度function generateChunk(cx, cz) {} // 填草、土、石、沙、树,再叠上 edits
// 3. 网格生成function buildChunkGeometry(cx, cz) {} // 只收集露在外面的面function rebuildChunk(cx, cz) {} // 生成 Mesh,放进 meshesfunction updateChunks() {} // 每帧补建最近的 2 个区块,卸掉远的
// 4. 操作与碰撞function moveAxis(axis, delta) {} // 一次只动一个轴function stepPlayer(dt) {} // 重力、走动、跳跃function raycast(origin, dir, maxDist) {} // 准星找第一个实心方块function setBlock(wx, wy, wz, id) {} // 改数组、记改动、重建网格
// 5. 存档const edits = new Map(); // "cx,cz" → Map(下标 → 方块)function recordEdit(cx, cz, i, id) {} // 停手 500 毫秒后写 localStorage
// 主循环function frame(now) {} // 上面那四步下面按這五段說說每一段要解決的問題,具體實現可以直接看原始碼,每段開頭都有註釋。
世界資料。 每個區塊 16×16×64,用一個 Uint8Array 存,一個方塊一個位元組,三維座標按 x + z*16 + y*256 攤平成陣列下標。關鍵在 getChunk:呼叫方不需要關心區塊有沒有生成過,查到哪裡,哪裡就被生成出來,這正是第三節說的“按需生成”。唯一的坑是負座標,算區塊要用 Math.floor 而不是直接取整,否則 -3 會被算進區塊 0。
地形生成。 heightAt 把四層 Perlin 噪聲疊起來:第一層頻率最低,決定大的山和谷;後面每一層幅度減半、頻率加倍,只加小起伏。種子固定,同一個座標永遠算出同樣的高度。為了簡單,這裡用的是第三節說的二維高度圖,所以沒有懸崖下的凹洞。
網格生成。 這一段就是圖 1 和圖 2 落到程式碼上:遍歷每個實心方塊的六個面,鄰居是實心的就跳過,是空氣就把這個面的 4 個角寫進頂點陣列,切成兩個三角形。視距 6 個區塊時一共約 63 萬個方塊,全畫要 377 萬個面,實際只畫了約 5.7 萬個,佔 1.5%,左上角的 HUD 會實時顯示這幾個數字。建網格是整個程式裡最耗時的一步,一口氣建完 113 個區塊會讓頁面卡住好幾秒,所以 updateChunks 每幀只建離玩家最近的兩個,世界是從腳下一圈圈長出去的。
操作與碰撞。 玩家被看成一個 0.6×1.8×0.6 的盒子。如果三個方向一起移動、撞上了就整體退回,斜著走向牆時人會被“粘”在牆上;moveAxis 改成一次只動一個軸,撞牆的方向停下,另一個方向照樣走,人就貼著牆滑過去了。準星用的是 DDA 演算法:沿視線每次只跨進下一個格子,不漏格也不重複,順帶記下是從哪個面進來的,右鍵放方塊就放在那個面的外側。
存檔。 挖和放都走 setBlock。它最容易漏的是邊界:挖掉區塊邊上的一塊,隔壁區塊裡原本被擋住的面露出來了,不連隔壁一起重建,地上就會出現一個能看穿的洞。存檔本身照搬圖 3 的思路,edits 只記玩家改過的方塊,玩家停手 500 毫秒後寫一次 localStorage;generateChunk 先從種子算出地形,再把改動覆蓋上去。所以無論區塊是第一次生成,還是被卸掉後重新生成,改過的地方都還在。
我在沒有顯示卡的雲伺服器上,用無頭瀏覽器的軟體渲染跑這個演示,約 20 幀;有顯示卡的電腦應該會高得多(這一點我沒有實測)。
寫完之後回頭看,真正難的部分不在算力,而在三個地方:遠處區塊載入時怎麼不卡(我們用了分幀,更好的做法是把網格生成放進 Web Worker);改動多了以後存檔放哪(localStorage 只有幾 MB,下一步該換成 IndexedDB 或 OPFS);以及多人聯機時網頁只能走 WebSocket。這三處,恰好都是上一小節說的瀏覽器限制。
一個能隨便改、規則又很清楚的世界,還有什麼別的用處?
六、方塊世界與智慧體
現象:Minecraft 成了 AI 的考場
過去幾年,Minecraft 幾乎成了 AI 智慧體研究的標準環境。原因和前幾節說的特點直接相關:世界是開放的,沒有固定目標,適合考察“自己找事做”;規則是離散、明確的,方塊就是方塊,合成表就是合成表;世界可以被改,智慧體做了什麼會留下看得見的痕跡;網上還有海量的遊戲影片可以學。
第一種接法:看螢幕,按鍵盤
2022 年,OpenAI 的 VPT 讓模型像人一樣只看畫面、用鍵盤滑鼠操作。他們先用少量帶按鍵記錄的錄影訓練一個模型,給大約 7 萬小時網路影片補上“這一幀按了什麼鍵”的標籤,再拿這些影片預訓練。最後在 2.5% 的 10 分鐘回合裡做出了鑽石鎬,而熟練的人類平均要 20 多分鐘、約 24000 個操作19。
這種接法最通用,但也最難:模型要從畫素裡理解世界。
第二種接法:直接呼叫介面
2023 年的 Voyager 換了一個思路:不讓 GPT-4 去按鍵,而是讓它寫程式碼。遊戲提供一套 JavaScript 介面,GPT-4 自己給自己出任務,寫程式碼完成任務,根據報錯修改,驗證透過的程式碼存進“技能庫”,下次遇到類似任務直接取出來用。和之前的方法比,它收集到的物品種類多了 3.3 倍,解鎖科技樹的關鍵節點快了最多 15.3 倍20。
2024 年,Altera 的 Project Sid 把 10 個到 1000 多個智慧體放進同一個 Minecraft 世界,觀察到了分工、集體規則的制定和修改,以及文化和宗教在智慧體之間的傳播21。
這種接法後來也走到了普通人手裡。有了 MCP(模型上下文協議)之後,社群做了 Minecraft 的 MCP 伺服器,把移動、挖、放、熔鍊、聊天這些動作暴露成工具,在 Claude 這樣的助手裡用一句話就能指揮遊戲裡的角色蓋房子22。
我們的演示裡也有一行類似的東西:
window.voxel = { player, getBlock, setBlock, stats, meshes };它本來是給除錯用的,但你在瀏覽器控制檯裡呼叫 voxel.setBlock(...),和一個智慧體呼叫 MCP 工具,本質上是同一件事:透過介面讀寫世界。網頁遊戲如果把這類介面規範地暴露出來,就能被智慧體直接操作。
第三種接法:讓模型本身成為遊戲
2024 年 10 月,Decart 釋出了 Oasis:沒有遊戲引擎,一個在 Minecraft 影片上訓練出來的模型根據你的鍵盤滑鼠輸入,實時生成下一幀畫面23。它看起來像 Minecraft,但有一個致命問題:模型很快會“忘掉”地形,你轉一圈回來,眼前的景色已經變了23。
這正好回到了本文的主線。Minecraft 的核心不是方塊的樣子,而是一個能被記住、能被持久修改的世界。第三節裡區塊、種子和改動記錄解決的就是這件事,而這恰恰是今天的生成式“世界模型”最欠缺的。
七、回到起點
現在可以回答開頭那個“這個我上我也行”了。Minecraft 看起來簡單,是因為它把複雜度藏在了看不見的地方:畫面上是方塊,底下是一套讓世界可以被隨便修改、又不會撐爆記憶體的資料結構和演算法。方塊的畫風也不只是省事,它讓每個玩家蓋出來的東西和官方的內容一樣“好看”(這是我的理解)。
它來得晚,是因為這件事需要好幾個條件同時成立:顯示卡和記憶體夠用,Java 讓一個人寫的程式能跑在所有電腦上,網路讓一個人能直接把沒做完的遊戲賣給玩家。而當年它能直接在瀏覽器裡執行,今天卻要重寫才能回去,這中間隔著的是瀏覽器十幾年的安全收緊。
小結
- Minecraft 的玩法從哪來? 來自 Infiniminer 的玩家。Infiniminer 設計的是競技,玩家卻拿它蓋房子;作者因為不賺錢、程式碼失控而放棄,Minecraft 補上了生存、無限世界和收費。
- 早期 3D 遊戲為什麼不這麼做? 當時的效能來自“提前算好”的靜態關卡,可修改的世界會讓預計算全部失效。體素渲染輸給了顯示卡的三角形路線,區域性破壞也做不到“全部”。Minecraft 把方塊轉成三角形、只畫露在外面的面、按區塊重建網格,才讓兩者接上。
- 這麼大的世界怎麼裝得下? 按區塊、按需、確定性地生成,沒去過和沒改過的地方都不用存,存檔只記改動。
- 為什麼是 2009 年? 記憶體夠了,Java 能跨平臺甚至跑在網頁裡,預售讓一個人能養活自己,而大公司沒有動機去做沒有關卡的遊戲(推斷)。
- 為什麼今天瀏覽器很難跑這種遊戲? 不是算力,而是外掛被移除、WebGPU 剛剛普及、沙箱對網路執行緒記憶體儲存的限制,以及引擎廠商不投入。但只要最基礎的玩法,500 行程式碼就夠了,可以直接試試。
- 為什麼它成了 AI 的考場? 開放、規則清楚、可修改。智慧體可以看螢幕操作,也可以呼叫介面操作;用模型直接生成遊戲畫面的嘗試,卡在了“記住世界”這件 Minecraft 早就解決了的事情上。
參考資料
參考資料
-
Infiniminer收藏en.wikipedia.orghttps://en.wikipedia.org/wiki/Infiniminer ↩ ↩2 ↩3 ↩4
-
The local origins of Minecraft: A conversation with indie gamer Zachary Barthcrosscut.com ↗https://crosscut.com/2015/08/the-godfather-of-minecraft-a-conversation-with-indie-gamer-zachary-barth ↩ ↩2
-
The history of Minecraft收藏techradar.comhttps://www.techradar.com/news/the-history-of-minecraft ↩ ↩2 ↩3 ↩4
-
Minecraft (lost early builds of Java game; 2009-2013)lostmediawiki.com ↗https://www.lostmediawiki.com/Minecraft_(lost_early_builds_of_Java_game;_2009-2013) ↩ ↩2 ↩3
-
Early access收藏en.wikipedia.orghttps://en.wikipedia.org/wiki/Early_access ↩ ↩2 ↩3
-
Voxel Space收藏en.wikipedia.orghttps://en.wikipedia.org/wiki/Voxel_Space ↩
-
Ken Silverman收藏en.wikipedia.orghttps://en.wikipedia.org/wiki/Ken_Silverman ↩
-
Red Faction (video game)收藏en.wikipedia.orghttps://en.wikipedia.org/wiki/Red_Faction_(video_game) ↩ ↩2
-
Meshing in a Minecraft Game收藏0fps.nethttps://0fps.net/2012/06/30/meshing-in-a-minecraft-game/ ↩
-
Terrain generation, Part 1moddb.com ↗ModDB 轉載https://www.moddb.com/news/terrain-generation-part-1 ↩ ↩2 ↩3
-
Minecraft Classic browser收藏engadget.comhttps://engadget.com/2019/05/09/minecraft-classic-browser ↩
-
Web publishing following Chrome NPAPI deprecationblog.unity.com ↗https://blog.unity.com/cn/technology/web-publishing-following-chrome-npapi-deprecation ↩
-
WebGPU is now supported in major browsers收藏web.devhttps://web.dev/blog/webgpu-supported-major-browsers ↩
-
Introduction收藏mintlify.wikihttps://mintlify.wiki/zardoy/minecraft-web-client/introduction ↩ ↩2
-
zardoy/minecraft-web-client收藏github.com原始碼https://github.com/zardoy/minecraft-web-client ↩ ↩2
-
Making your website "cross-origin isolated" using COOP and COEP收藏web.devhttps://web.dev/articles/coop-coep ↩
-
Is Memory64 actually worth using?收藏spidermonkey.devhttps://spidermonkey.dev/blog/2025/01/15/is-memory64-actually-worth-using.html ↩
-
A New Tool for Unreal Engine Developers to Export to the Web收藏thenewstack.iohttps://thenewstack.io/a-new-tool-for-unreal-engine-developers-to-export-to-the-web/ ↩
-
Learning to play Minecraft with Video PreTrainingopenai.com ↗https://openai.com/index/vpt ↩
-
Voyager: An Open-Ended Embodied Agent with Large Language Models收藏arxiv.orgarXiv:2305.16291https://arxiv.org/abs/2305.16291 ↩
-
Project Sid: Many-agent simulations toward AI civilization收藏arxiv.orgarXiv:2411.00114https://arxiv.org/abs/2411.00114 ↩
-
yuniko-software/minecraft-mcp-server收藏github.comhttps://github.com/yuniko-software/minecraft-mcp-server ↩
-
Decart's AI simulates a real-time, playable version of Minecraft收藏techcrunch.comhttps://techcrunch.com/2024/10/31/decarts-ai-simulates-a-real-time-playable-version-of-minecraft ↩ ↩2