在大型瓷砖地图以及地牢上“分区”区域


10

我的游戏以伪无限且随机生成的方式具有类似于Minecraft的地图。又大 假设用户浏览了1000x1000区域(此处为2D),那么就是1,000,000个图块。

显然,我将无法将其全部存储在内存中。我也不只是想忽略10个磁贴或任何半径范围之外的所有内容-两者都不会更新(所有NPC,也许是反应性磁贴),我将不得不处理诸如1382,12918之类的笨拙位置。

因此,如果我要将其拆分为块或区域或诸如64x64的瓷砖之类的东西,则必须存储每个瓷砖和对象的位置,例如:

块a,b 位置x,y。

但是,如果我想要在地图中使用地牢之类的东西怎么办?因此,一块瓷砖可能会导致一个40层的地牢,每个区域的面积为40x40。我无法将它们完全存储在同一张地图中。

还有记忆的一面;我可以合理地同时在内存中存储多少?我可以很容易地按ID进行平铺,并在那里有普通的2D阵列。还是再说一次,有没有比包含瓦片类型的数据文件更有效的解决方案?所以对于64x64 ..那只会是20K或其他 我希望尽可能多地加载最真实的更新。但是我不知道在不浪费内存的情况下可以达到什么样的限制。

Answers:


9

尽管我同意这样的观点:“除非它是一个经过验证的问题,否则不要担心”,但我确实值得在早期进行思考:改造解决方案要痛苦得多。是的,只有更新“附近”磁贴才是可行的方法。但是,出于性能方面的考虑,有效地存储游戏世界中物品的位置和寻址能力非常重要。

您实际上在想的是一个稀疏的数据集:潜在索引很大(或无限)但实际上只使用了很小一部分的东西。关键是您不知道确切使用哪个比例。

稀疏数据集问题的标准解决方案是将索引/可寻址性与实际数据存储区分开。因此,如果平铺对象很昂贵,则以紧凑形式(例如,平面阵列)存储它。但允许通过便宜的对象对其进行索引。以其最简单的形式,它可以是2D(或3D)矩阵,您可以轻松地按坐标对其进行索引,但是矩阵中的每个项目都只是一个索引。然后,您可以使用该索引在单独的紧凑数组中查找实际磁贴内容。如果图块内容尚不存在,则将它们添加到数组的末尾,并将索引存储在3D矩阵中。

如果您希望支持内容删除(因为这会导致内容数组碎片),并且如果分片内容便宜,那么索引(32位或64位索引)的额外权重会使解决方案变得更加复杂由于不存储每个潜在的图块,所节省的费用可能会被淹没。这也是一个额外的查询,它将损害您的缓存性能。

通过引入额外的间接层,您可以获得更高的存储效率。假设您将图块组织成块,块的粒度为64x64x64。给定位于125、1、132的图块,您知道它属于块(1,0,2)。因此,您拥有一个由紧凑的块数组和块索引矩阵组成的世界(如果不存在该块,则为-1)。每个块的内容(如果存在)是一个64x64x64的图块索引矩阵(如果该图块尚不存在,则为-1),以及一个紧凑的已用图块数组。这样,您就不会为从未使用过的块刻录大量的切片索引。通过遵循这种方法,并为块粒度选择合适的数字,您可以大规模扩展Universe,并控制内存使用量。实际上,如果您将块的大小设为32x32x32,

您还可以进行一些技巧,例如使用块或图块索引的高阶位来表示特殊的东西。因此,如果图块矩阵中的条目设置了最高位,则低31位并不意味着图块索引,而是表示“扭曲索引”或类似的东西,您可以在单独维护的列表中查找找出导致的坐标。


我警告将来会遇到这个问题的人:尽管这篇文章中没有什么是不正确的,但对于像Minecraft这样的游戏世界来说,这真是太恐怖了。(和MrCranky说那么多。)你的世界只有从这个好处,如果它有几个出头和大量的空话,没有几个出头和大量的空箱

1
我衷心地同意,维护稀疏数据集存储解决方案所涉及的开销非常高,因此,只有在余额明显偏向稀疏的情况下,您才需要这样做。这里的关键因素是:数据项成本和未使用数据项的概率。我的世界有大量潜在的数据集(每个方向上都有大量图块)。使用的潜在游戏世界的实际比例很小。即使您在世界各地旅行时声称拥有大量内容,但它仍然只是潜在数据项的一小部分。
MrCranky 2010年

1
使Minecraft与众不同的是,单位成本很小-也许只有一个字节的存储空间?一个值表示“没有”,其余为块类型,您可以轻松地将其装入一个字节。因此,您将没有单个块的索引,这太疯狂了,该索引比仅存储实际块值大得多。但是,稀疏数据集规则仍然可以在更高级别上使用。每个块(例如64x64x64)的存储成本很高(256K块),因此,如果您可以使用一个较小的值指示其不存在,或者使用其地址(如果存在),那么您已经节省了大容量存储。
MrCranky 2010年

6

为什么不能在内存中存储一​​百万个图块?甚至我的手机都具有256MB RAM;一百万个空瓦片将是什么,4-32MB?


似乎要存储的数量如此之多。不仅如此,更新它们还将花费很长时间。
共产党鸭子

2
忽略一组瓦片进行更新比处理某种磁盘分页解决方案要容易得多。只是..忽略它们。与已知演员相比,更新图块的距离不要超过X距离。

2
@TheCommunistDuck唯一重要的是用于存储切片的内存总量,而不是切片的数量。
贾斯汀2010年

1
同意Kragen和Joe。不必担心听起来很像-进行数学运算并计算出来。这不太可能成为问题。
Kylotan
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.