淺談?dòng)螒騇inecraft中的數(shù)據(jù)結(jié)構(gòu)

前言

??《我的世界》(英文名Minecraft, 簡(jiǎn)稱: MC) 相信大多數(shù)人并不陌生糠睡,它是一款沙盒游戲,最初由瑞典游戲設(shè)計(jì)師馬庫(kù)斯·阿列克謝·泊松(別名Notch)單獨(dú)開發(fā)含友,隨后由2009年成立的瑞典公司Mojang開發(fā)并發(fā)行凳谦。玩家可以在一個(gè)隨機(jī)生成的3D(世界內(nèi),以帶材質(zhì)貼圖的立方體為基礎(chǔ)進(jìn)行游戲挎扰。游戲中的其他特色包括探索世界囚霸、采集資源腰根、合成物品及生存冒險(xiǎn)等。(來(lái)自維基百科)

圖1 玩家在Minecraft中建造的豪宅(侵刪)

??方塊是MC的靈魂拓型。玩家的創(chuàng)意通過(guò)方塊的形式表現(xiàn)出來(lái)额嘿,游戲內(nèi)容通過(guò)方塊進(jìn)行呈現(xiàn),方塊是組成這個(gè)世界的最小單位劣挫。玩家通過(guò)多樣化的方塊可以構(gòu)建出任何自己想構(gòu)建出的東西册养,甚至有大神已經(jīng)嘗試在MC中構(gòu)建計(jì)算機(jī),這充分地體現(xiàn)出《我的世界》高自由度压固、高真實(shí)性的特點(diǎn)球拦。本文主要就MC中方塊存儲(chǔ)的數(shù)據(jù)結(jié)構(gòu)進(jìn)行簡(jiǎn)要介紹,并討論其設(shè)計(jì)上的值得學(xué)習(xí)的思想和精妙之處帐我。

方塊的存儲(chǔ)

重要結(jié)構(gòu)

??方塊的存儲(chǔ)中有兩個(gè)重要的結(jié)構(gòu)坎炼,即分區(qū) (Section, 又名Chunk Section)區(qū)塊 (Chunk, 又名Chunk Column)。一個(gè)分區(qū)是由16*16*16個(gè)方塊構(gòu)成的大立方體拦键,而一個(gè)區(qū)塊由16個(gè)分區(qū)堆疊而成谣光,方塊、分區(qū)和區(qū)塊三者的關(guān)系如圖2所示芬为√呀穑可以看到蟀悦,一個(gè)區(qū)塊共包含16*256*16個(gè) (共65536個(gè))方塊。(Chunk其實(shí)有兩重含義氧敢,MC玩家所說(shuō)的Chunk一般指的是Chunk Column日戈,也就是本文中所說(shuō)的區(qū)塊,而Mojang公司所說(shuō)的Chunk一般指的是Chunk Section).

圖2 方塊福稳、分區(qū)和區(qū)塊的關(guān)系

分區(qū)

??分區(qū)中的4096個(gè)方塊每個(gè)都可能為空。如果一個(gè)分區(qū)中所有方塊都為空瑞侮,那么這個(gè)分區(qū)將被視為空分區(qū)的圆,這個(gè)分區(qū)的數(shù)據(jù)將不會(huì)被發(fā)送到客戶端。如果這個(gè)分區(qū)至少有一個(gè)方塊不為空半火,則該分區(qū)將被視為活躍分區(qū)越妈,分區(qū)的所有數(shù)據(jù)都會(huì)被發(fā)送到客戶端。分區(qū)在數(shù)據(jù)傳輸中具有不可分割的性質(zhì)钮糖。
??分區(qū)中存儲(chǔ)了4096個(gè)方塊的數(shù)據(jù)梅掠,按照方塊在分區(qū)中的相對(duì)位置存儲(chǔ)在數(shù)組中。分區(qū)的絕對(duì)位置由其所在的區(qū)塊來(lái)確定店归,也就是說(shuō)分區(qū)本身不包含該分區(qū)的絕對(duì)位置阎抒。

區(qū)塊

??分區(qū)的數(shù)據(jù)被封裝在區(qū)塊中進(jìn)行傳輸。區(qū)塊的頭部包含了區(qū)塊的xz坐標(biāo)消痛,但沒有y坐標(biāo)且叁。舉一個(gè)例子,一個(gè)區(qū)塊可以看作一棟高為256秩伞,長(zhǎng)和寬均為1的大樓逞带,xz確定了大樓所在的地址,不存在y數(shù)據(jù)是因?yàn)榇髽潜仨毥ㄔ诘孛嫔希?img class="math-inline" src="https://math.jianshu.com/math?formula=y" alt="y" mathimg="1">默認(rèn)為0纱新,且不允許從y不為0的地方開始“建造”這棟大樓展氓,這也就解釋了為什么早期版本的MC的高度限制為256。確定了區(qū)塊的xz也就確定了區(qū)塊中所有方塊的xz.

??區(qū)塊需要對(duì)分區(qū)進(jìn)行組織脸爱,使分區(qū)在區(qū)塊內(nèi)的位置是可以確定的遇汞,即確定區(qū)塊中所有方塊的y. 一種最簡(jiǎn)單的方案就是參考分區(qū)對(duì)方塊的做法,使用長(zhǎng)度為16的數(shù)組來(lái)存儲(chǔ)分區(qū)簿废,然而這種做法有一個(gè)缺陷勺疼,空分區(qū)也需要占用存儲(chǔ)空間。以圖3為例捏鱼,但如果直接去掉這6個(gè)空分區(qū)执庐,將所有活躍分區(qū)連續(xù)地存儲(chǔ)在長(zhǎng)度為10的數(shù)組中,那么每個(gè)活躍分區(qū)的y就被改變了导梆,雖然節(jié)約了空間轨淌,但數(shù)據(jù)都被篡改了迂烁,顯然不可行。

圖3 區(qū)塊中的活躍分區(qū)和空分區(qū)

??開發(fā)者在區(qū)塊中增加了一個(gè)位掩碼 (bitmask)來(lái)解決這個(gè)問(wèn)題递鹉。以圖3為例盟步,首先將空分區(qū)去掉,將所有活躍分區(qū)存儲(chǔ)在長(zhǎng)度為10的數(shù)組中躏结,然后按照該區(qū)塊中分區(qū)是否為空來(lái)設(shè)置16位掩碼却盘,第i個(gè)區(qū)塊為空則將掩碼的第i為置為0,反之則置為1媳拴,則圖三所示區(qū)塊的位掩碼應(yīng)為 1001101101110101. 通過(guò)位掩碼可以還原各分區(qū)在分區(qū)中的y位置黄橘,例如,掩碼中的第3個(gè)1位于掩碼的第5位屈溉,因此數(shù)組中第3個(gè)分區(qū)的真實(shí)y值為5. 這樣一來(lái)既節(jié)省了存儲(chǔ)空間塞关,又防止了數(shù)據(jù)的丟失。

圖4 去除空分區(qū)

調(diào)色板機(jī)制

??對(duì)于MC中的場(chǎng)景子巾,通常存在大量相同的方塊帆赢。圖1所示的場(chǎng)景便是一個(gè)最好的例子,大量的樹葉使用的是同一種方塊线梗。試想椰于,如果每個(gè)樹葉方塊都包含材質(zhì)、光線仪搔、功能等信息廉羔,這些信息就會(huì)被重復(fù)存儲(chǔ)多次。最簡(jiǎn)單的解決方案就是只存儲(chǔ)方塊的ID僻造,并將ID與方塊建立一對(duì)一的關(guān)系表憋他,這個(gè)關(guān)系表就被稱為調(diào)色板 (palette)。好比涂色游戲髓削,將一幅圖劃分為多個(gè)區(qū)域竹挡,每個(gè)區(qū)域標(biāo)記上一個(gè)數(shù)字代表該區(qū)域應(yīng)該涂上什么顏色,玩家根據(jù)數(shù)字和顏色的對(duì)應(yīng)關(guān)系完成上色立膛,其中數(shù)字和顏色的對(duì)應(yīng)關(guān)系就是調(diào)色板揪罕。

調(diào)色板

??假設(shè)樹葉方塊的大小為nbytes,圖中共有m個(gè)樹葉方塊宝泵,不使用調(diào)色板進(jìn)行存儲(chǔ)需要mnbytes的存儲(chǔ)空間好啰。方塊ID為long類型整數(shù),所占空間為8 bytes儿奶,調(diào)色板中的一條記錄包含ID和方塊框往,共需n+8bytes,因此存儲(chǔ)m個(gè)樹葉方塊需要n+8(m+1)bytes的存儲(chǔ)空間闯捎。使用調(diào)色板能節(jié)省的存儲(chǔ)空間為n(m-1)-8(m+1)椰弊,m\rightarrow \infty時(shí)為m(n-8). 一個(gè)方塊所占的存儲(chǔ)空間遠(yuǎn)大于一個(gè)long類型整數(shù)许溅。

對(duì)比實(shí)驗(yàn)

??選用線性存儲(chǔ)哈希存儲(chǔ)的方式與上述區(qū)塊存儲(chǔ)進(jìn)行對(duì)比。線性存儲(chǔ)即最簡(jiǎn)單粗暴的方法秉版,將每個(gè)方塊直接存儲(chǔ)在列表中贤重,方塊中包含了該方塊的位置信息x, y, z. 哈希存儲(chǔ)是根據(jù)哈希函數(shù)h(x, y, z)計(jì)算出位置的哈希值,然后將方塊存儲(chǔ)到哈希表的指定位置清焕。對(duì)比了三種存儲(chǔ)方式插入方塊并蝗、查找方塊、從磁盤讀取方塊和將方塊寫入磁盤的時(shí)間秸妥,實(shí)驗(yàn)結(jié)果如圖6所示滚停。實(shí)驗(yàn)源代碼在作者的GitHub倉(cāng)庫(kù)

圖6 三種存儲(chǔ)方式的性能對(duì)比實(shí)驗(yàn)結(jié)果

參考文獻(xiàn)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末筛峭,一起剝皮案震驚了整個(gè)濱河市铐刘,隨后出現(xiàn)的幾起案子陪每,更是在濱河造成了極大的恐慌影晓,老刑警劉巖,帶你破解...
    沈念sama閱讀 210,914評(píng)論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件檩禾,死亡現(xiàn)場(chǎng)離奇詭異挂签,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)盼产,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 89,935評(píng)論 2 383
  • 文/潘曉璐 我一進(jìn)店門饵婆,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人戏售,你說(shuō)我怎么就攤上這事侨核。” “怎么了灌灾?”我有些...
    開封第一講書人閱讀 156,531評(píng)論 0 345
  • 文/不壞的土叔 我叫張陵搓译,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我锋喜,道長(zhǎng)些己,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,309評(píng)論 1 282
  • 正文 為了忘掉前任嘿般,我火速辦了婚禮段标,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘炉奴。我一直安慰自己逼庞,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,381評(píng)論 5 384
  • 文/花漫 我一把揭開白布瞻赶。 她就那樣靜靜地躺著往堡,像睡著了一般械荷。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上虑灰,一...
    開封第一講書人閱讀 49,730評(píng)論 1 289
  • 那天吨瞎,我揣著相機(jī)與錄音,去河邊找鬼穆咐。 笑死颤诀,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的对湃。 我是一名探鬼主播崖叫,決...
    沈念sama閱讀 38,882評(píng)論 3 404
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼拍柒!你這毒婦竟也來(lái)了心傀?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,643評(píng)論 0 266
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤拆讯,失蹤者是張志新(化名)和其女友劉穎脂男,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體种呐,經(jīng)...
    沈念sama閱讀 44,095評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡宰翅,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,448評(píng)論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了爽室。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片汁讼。...
    茶點(diǎn)故事閱讀 38,566評(píng)論 1 339
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖阔墩,靈堂內(nèi)的尸體忽然破棺而出嘿架,到底是詐尸還是另有隱情,我是刑警寧澤啸箫,帶...
    沈念sama閱讀 34,253評(píng)論 4 328
  • 正文 年R本政府宣布耸彪,位于F島的核電站,受9級(jí)特大地震影響筐高,放射性物質(zhì)發(fā)生泄漏搜囱。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,829評(píng)論 3 312
  • 文/蒙蒙 一柑土、第九天 我趴在偏房一處隱蔽的房頂上張望蜀肘。 院中可真熱鬧,春花似錦稽屏、人聲如沸扮宠。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,715評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)坛增。三九已至获雕,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間收捣,已是汗流浹背届案。 一陣腳步聲響...
    開封第一講書人閱讀 31,945評(píng)論 1 264
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留罢艾,地道東北人楣颠。 一個(gè)月前我還...
    沈念sama閱讀 46,248評(píng)論 2 360
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像咐蚯,于是被迫代替她去往敵國(guó)和親童漩。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,440評(píng)論 2 348

推薦閱讀更多精彩內(nèi)容