15

例如,在辐射 3 中,保存游戏存储游戏中每个对象和 NPC 的状态和位置,并且只占用几 MB。他们是怎么做到的!?!?

然后,在玩游戏的过程中,如何在内存中/从内存中添加/检索这些数据,以便实时显示给玩家?

更新:(我会让你为你的答案工作:P)

根据凯文克劳威尔的回答......所以我想你会有一个适用于对象和 NPC 的渲染距离,你会在给定范围内“选择”对象和 NPC。但是,您将使用什么类型的数据存储来获取这些对象?

换句话说,你会拥有一个包含游戏中每个对象的巨大数组,并不断更新一个较小的列表来保存要渲染的可见对象吗?

另外,根据 Chaos 的回答……如果您最终触摸了游戏中的每个对象,会发生这种情况吗?你的存档游戏会越来越大吗?在辐射 3 的情况下,我很确定没有“阶段”,过去的数据可能会被丢弃。当您离开/返回某个位置时,一切都会保留。那么您认为这个具体案例是如何实现的呢?

4

9 回答 9

12

现在有了所有的大硬盘,即使是开发人员似乎也忘记了每兆字节有多少字节。所以回答标题中的问题:游戏通过创建几兆字节的存档来存储大量数据。

为了说明一兆字节有多大,它是 800 万位。这足以编码 2^8000000 = 10^2666666 个状态。相比之下,宇宙中只有 10^80 个原子。现在在(保存)游戏中,有多个具有不同状态的子系统;例如,在 RPG 中,每个 NPC 都有自己的状态。但是,真正的状态有多少?他们在城镇中的位置可能会保存为 16 位(如果他们四处走动,你还记得他们的确切位置吗?)。他们的情绪/性格/等是另外 8 位,这允许比某些人拥有更多的情绪。

在游戏中存储此类数据时,典型的数据结构是四叉树。这是一个数据结构,允许您在 O(log N) 中确定某个 XY 区域中的对象。在某些情况下,游戏开发人员发现将世界预先划分为区域更容易。这减少了运行时计算量。一个很好的例子是毁灭战士。它的地图具有预先计算的能见度;对于每个点,人们可以快速确定它属于哪个区域,并且对于每个区域,可见对象的数量都是预先计算的。这减少了需要运行时可见性检查的对象数量。

于 2009-03-31T07:55:39.587 回答
9

它可以简单地将对象或 NPC 映射到 X、Y、Z 坐标平面。廉价存储的信息。

在游戏过程中,所有这些对象仍然始终映射到坐标系。他们只需要读入保存信息并从那里开始。

于 2009-03-30T18:47:38.767 回答
8

我认为您高估了存储/检索内容的复杂性。您不需要存储对象的 3D 模型、它们的纹理或构成游戏磁盘大小的大部分内容的任何东西。

首先,正如混乱所提到的,只需要存储有关已移动事物的信息。即便如此,您可能只需要为每一个存储新的位置和方向(假设不涉及其他变量,例如“损坏”)。这是每个对象的两个向量,每个对象总共大约有 24 个字节。这意味着您可以为每兆字节存储 40,000 个对象的信息。移动的物体太多了。

恢复这些数据并不比首先放置对象更复杂。每个对象都必须为游戏定义一个默认位置/方向才能将其放置在某个位置,因此您所做的就是用保存文件中存储的值替换默认值。这并不复杂,也不需要任何重要的额外处理。

于 2009-03-30T19:07:52.553 回答
4

特别是在辐射 3 中,地图以网格方式划分。您只能看到您当前的方格和紧随其后的方格。数据存储的类型并不重要——可以是 SQLite 数据库,可以是序列化到磁盘的树,或者完全是其他东西。

...您是否会拥有游戏中每个对象的巨大数组,并不断更新一个较小的列表来保存要渲染的可见对象?

通常是的,但是“巨大的数组”不需要在内存中。还有更多的列表 - 当前和相邻网格中的对象(你可以从后面受到攻击 - 不在可见列表中),可见列表,计时器列表......

如果你最终触摸了游戏中的每一个物体,会发生什么?你的存档游戏会越来越大吗?

可以 - 如果所有内容都有默认状态表,则保存只能包含差异。然后保存将随着您的进步而增长。

当您离开/返回某个位置时,一切都会保留。

没有。您丢在屋外的物品最终会消失。身体也可能。随机怪物每隔一段时间就会重生一次。这对游戏设计师来说既方便又符合现实世界。

于 2009-03-31T08:28:42.160 回答
3

如果您考虑一下您需要保存的信息,实际上并没有那么多。

例如

  • 位置
  • 方向
  • 存货
  • 健康
  • 客观状态

当然还有更多,其中许多取决于游戏类型和保存结构的组织方式。

某些游戏(例如生化危机)仅在您进入新区域时才允许保存,这意味着您不必存储两个区域中实体的所有信息。当您“加载”保存时,它们的属性来自光盘。

至于这是如何检索/修改数据的,我不太确定我是否理解。它只是控制台内存中的数据。当播放器保存时,它被写入保存设备,当他们加载时,它被恢复。

于 2009-03-30T18:56:01.460 回答
2

一种主要技术是差异保存:仅保存不是默认值的状态。将“保存游戏世界中每个对象的状态和位置”与“保存游戏世界中玩家移动或改变的每个对象的状态和位置”进行比较和对比。

于 2009-03-30T18:58:08.240 回答
1

与其他答案相呼应,最大的节省来自消除所有不必要的状态数据。

如果您查看 8 位横向卷轴游戏,它们会在画面离开后立即开始丢弃状态,并且通常什么都不保留,因为它们的资源太紧而无法保持超过最小实例数。

在宏观层面上为《辐射 3》这样的游戏做这件事只是扩大问题的范围。您开始通过网格或其他几何方法划分景观,并在玩家从一个部分移动到下一个部分时产生/消失东西。理想情况下,您可以将每个区域的大小保持在较小的范围内,以使内存中的状态不高。您计算出保留 NPC 和项目实例所需的最低限度的状态,并在布局数据中尽可能多地标记为自动重生,以便它不需要保存任何状态。

如果您想指向特定的数据结构,示例序列化格式可能是由指针树索引的线性流,其中树的组织对应于地图布局。

于 2009-03-31T07:15:43.710 回答
1

与此相关的是,游戏引擎通常使用 Zip 压缩,以减小所有内容的大小并加快某些操作。

于 2009-03-31T08:14:59.807 回答
1

除了其他人所说的之外,我想补充一点,状态并不一定意味着位置和运动,还包括各个状态的属性。通常一个游戏引擎有一个功能可以让你保存某个类的数据。

假设您有一个 Player 类并且您对故事很了解,当您单击保存时,可以存储的可能数据是:

  • 玩家在 关卡/地图中的位置
  • 他的属性是什么:健康,法力,力量,智力等
  • 他有什么技能。
  • 他什么水平。

在全球范围内,我们还可以拥有:

  • 有多少对对象的引用(允许引擎从列表中提取对象的名称)存储在该特定级别中,换句话说,当您加载应该与它一起加载的对象时。
  • 我们是否在使用物理学,如果是,谁在使用它。

还有很多。辐射 3 有一种保存类型,另一款游戏会有另一种。这真的取决于流派和使用的引擎。

于 2009-03-31T08:21:16.127 回答