浅谈游戏Minecraft中的数据结构

前言

  《我的世界》(英文名Minecraft, 简称: MC) 相信大多数人并不陌生,它是一款沙盒游戏,最初由瑞典游戏设计师马库斯·阿列克谢·泊松(别名Notch)单独开发,随后由2009年成立的瑞典公司Mojang开发并发行。玩家可以在一个随机生成的3D(世界内,以带材质贴图的立方体为基础进行游戏。游戏中的其他特色包括探索世界、采集资源、合成物品及生存冒险等。(来自维基百科)

图1 玩家在Minecraft中建造的豪宅(侵删)

  方块是MC的灵魂。玩家的创意通过方块的形式表现出来,游戏内容通过方块进行呈现,方块是组成这个世界的最小单位。玩家通过多样化的方块可以构建出任何自己想构建出的东西,甚至有大神已经尝试在MC中构建计算机,这充分地体现出《我的世界》高自由度、高真实性的特点。本文主要就MC中方块存储的数据结构进行简要介绍,并讨论其设计上的值得学习的思想和精妙之处。

方块的存储

重要结构

  方块的存储中有两个重要的结构,即分区 (Section, 又名Chunk Section)区块 (Chunk, 又名Chunk Column)。一个分区是由16*16*16个方块构成的大立方体,而一个区块由16个分区堆叠而成,方块、分区和区块三者的关系如图2所示。可以看到,一个区块共包含16*256*16个 (共65536个)方块。(Chunk其实有两重含义,MC玩家所说的Chunk一般指的是Chunk Column,也就是本文中所说的区块,而Mojang公司所说的Chunk一般指的是Chunk Section).

图2 方块、分区和区块的关系

分区

  分区中的4096个方块每个都可能为空。如果一个分区中所有方块都为空,那么这个分区将被视为空分区,这个分区的数据将不会被发送到客户端。如果这个分区至少有一个方块不为空,则该分区将被视为活跃分区,分区的所有数据都会被发送到客户端。分区在数据传输中具有不可分割的性质。
  分区中存储了4096个方块的数据,按照方块在分区中的相对位置存储在数组中。分区的绝对位置由其所在的区块来确定,也就是说分区本身不包含该分区的绝对位置。

区块

  分区的数据被封装在区块中进行传输。区块的头部包含了区块的xz坐标,但没有y坐标。举一个例子,一个区块可以看作一栋高为256,长和宽均为1的大楼,xz确定了大楼所在的地址,不存在y数据是因为大楼必须建在地面上,y默认为0,且不允许从y不为0的地方开始“建造”这栋大楼,这也就解释了为什么早期版本的MC的高度限制为256。确定了区块的xz也就确定了区块中所有方块的xz.

  区块需要对分区进行组织,使分区在区块内的位置是可以确定的,即确定区块中所有方块的y. 一种最简单的方案就是参考分区对方块的做法,使用长度为16的数组来存储分区,然而这种做法有一个缺陷,空分区也需要占用存储空间。以图3为例,但如果直接去掉这6个空分区,将所有活跃分区连续地存储在长度为10的数组中,那么每个活跃分区的y就被改变了,虽然节约了空间,但数据都被篡改了,显然不可行。

图3 区块中的活跃分区和空分区

  开发者在区块中增加了一个位掩码 (bitmask)来解决这个问题。以图3为例,首先将空分区去掉,将所有活跃分区存储在长度为10的数组中,然后按照该区块中分区是否为空来设置16位掩码,第i个区块为空则将掩码的第i为置为0,反之则置为1,则图三所示区块的位掩码应为 1001101101110101. 通过位掩码可以还原各分区在分区中的y位置,例如,掩码中的第3个1位于掩码的第5位,因此数组中第3个分区的真实y值为5. 这样一来既节省了存储空间,又防止了数据的丢失。

图4 去除空分区

调色板机制

  对于MC中的场景,通常存在大量相同的方块。图1所示的场景便是一个最好的例子,大量的树叶使用的是同一种方块。试想,如果每个树叶方块都包含材质、光线、功能等信息,这些信息就会被重复存储多次。最简单的解决方案就是只存储方块的ID,并将ID与方块建立一对一的关系表,这个关系表就被称为调色板 (palette)。好比涂色游戏,将一幅图划分为多个区域,每个区域标记上一个数字代表该区域应该涂上什么颜色,玩家根据数字和颜色的对应关系完成上色,其中数字和颜色的对应关系就是调色板。

调色板

  假设树叶方块的大小为nbytes,图中共有m个树叶方块,不使用调色板进行存储需要mnbytes的存储空间。方块ID为long类型整数,所占空间为8 bytes,调色板中的一条记录包含ID和方块,共需n+8bytes,因此存储m个树叶方块需要n+8(m+1)bytes的存储空间。使用调色板能节省的存储空间为n(m-1)-8(m+1)m\rightarrow \infty时为m(n-8). 一个方块所占的存储空间远大于一个long类型整数。

对比实验

  选用线性存储哈希存储的方式与上述区块存储进行对比。线性存储即最简单粗暴的方法,将每个方块直接存储在列表中,方块中包含了该方块的位置信息x, y, z. 哈希存储是根据哈希函数h(x, y, z)计算出位置的哈希值,然后将方块存储到哈希表的指定位置。对比了三种存储方式插入方块、查找方块、从磁盘读取方块和将方块写入磁盘的时间,实验结果如图6所示。实验源代码在作者的GitHub仓库

图6 三种存储方式的性能对比实验结果

参考文献

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,651评论 6 501
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,468评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,931评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,218评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,234评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,198评论 1 299
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,084评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,926评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,341评论 1 311
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,563评论 2 333
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,731评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,430评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,036评论 3 326
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,676评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,829评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,743评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,629评论 2 354

推荐阅读更多精彩内容