为游戏保存大量数据 我设计了一个C++游戏,有大量的数据——基本上,它的特点是随机生成的、块状的地形(以一个非常大的字节数组的形式),大部分都是Terraria风格的,而且还需要为怪物(其他游戏对象)保存状态。当玩家四处奔跑时,游戏世界的各个部分将被加载/保存到磁盘中,从而形成一个无限扩展的游戏世界(类似于Minecraft)

为游戏保存大量数据 我设计了一个C++游戏,有大量的数据——基本上,它的特点是随机生成的、块状的地形(以一个非常大的字节数组的形式),大部分都是Terraria风格的,而且还需要为怪物(其他游戏对象)保存状态。当玩家四处奔跑时,游戏世界的各个部分将被加载/保存到磁盘中,从而形成一个无限扩展的游戏世界(类似于Minecraft),c++,database,file-io,C++,Database,File Io,将所有内容保存到磁盘的最佳选项是什么?我最关心的是效率(因此用户不必等待内容加载),但易用性和可维护性紧随其后。我非常熟悉Minecraft的保存方法,每个“块”都有一个单独的文件,但我想知道——我应该像Minecraft那样指定自己的文件,还是使用数据库?还有什么其他的可能性?如果我使用一个文件,我会通过向操作系统请求原始访问并自己处理(就像数据库一样)来获得显著的性能提升吗 此外,我还希望能够将项目从PC移植到Mac和控制台——各个平台的替代方案都可以,我只需要根据平台交换方法 谢谢 数据库

将所有内容保存到磁盘的最佳选项是什么?我最关心的是效率(因此用户不必等待内容加载),但易用性和可维护性紧随其后。我非常熟悉Minecraft的保存方法,每个“块”都有一个单独的文件,但我想知道——我应该像Minecraft那样指定自己的文件,还是使用数据库?还有什么其他的可能性?如果我使用一个文件,我会通过向操作系统请求原始访问并自己处理(就像数据库一样)来获得显著的性能提升吗

此外,我还希望能够将项目从PC移植到Mac和控制台——各个平台的替代方案都可以,我只需要根据平台交换方法


谢谢

数据库的目的是加速复杂的搜索。你没有任何正在进行的搜索;您需要将一块数据放入内存。对于此任务,数据库将对您毫无价值

您真正需要什么取决于您所谈论的数据量以及您希望的平台特定性。你似乎在谈论2D游戏,所以块不会那么大。常规的C或C++文件IO函数可能是足够好的。最糟糕的情况是,您可能必须将它们固定在一个线程中,以进行异步文件IO和处理


真的,开始做显而易见的事情吧。如果出现问题,请尝试使用简单的线程构造使其异步。您可能不需要走得太远。

数据库的目的是加速复杂的搜索。你没有任何正在进行的搜索;您需要将一块数据放入内存。对于此任务,数据库将对您毫无价值

您真正需要什么取决于您所谈论的数据量以及您希望的平台特定性。你似乎在谈论2D游戏,所以块不会那么大。常规的C或C++文件IO函数可能是足够好的。最糟糕的情况是,您可能必须将它们固定在一个线程中,以进行异步文件IO和处理


真的,开始做显而易见的事情吧。如果出现问题,请尝试使用简单的线程构造使其异步。你可能不需要走得太远。

根据我的经验,这确实取决于很多因素。我的团队有一个将数百甚至数千个文件保存到数据库的系统,性能得到了提高。这些文件很小,因此与等待磁盘驱动器启动或操作系统将文件系统导航到每个单独文件的等待时间相比,读写时间很短


如果你有数千个小于4KB页面的文件,我会选择数据库。如果文件大于此值,则使用文件。数据库对吞吐量没有帮助,只能帮助延迟。

根据我的经验,它确实取决于很多因素。我的团队有一个将数百甚至数千个文件保存到数据库的系统,性能得到了提高。这些文件很小,因此与等待磁盘驱动器启动或操作系统将文件系统导航到每个单独文件的等待时间相比,读写时间很短


如果你有数千个小于4KB页面的文件,我会选择数据库。如果文件大于此值,则使用文件。数据库不会提高吞吐量,只会降低延迟。

与依靠文件系统进行组织相比,单个文件更干净,占用的物理磁盘空间更少。只需在文件的开头维护一个偏移量表,以链接到每个块

就压缩而言,应用游程编码肯定会缩小文件大小,如果它像Minecraft一样,您将有许多相同的块按顺序排列。作为奖励,它将在使用平板驱动器的计算机上更快地加载,因为两个字节可以相当于数千个块,而不必为每个块读取一个字节。这里有一个关于有效运行长度编码的快速提示:使用命令字节,比如0x00。所有其他字节都与一个块相关联,但命令字节表示一个非块信息位。传统的运行长度编码如下所示:

Source: AAAABBBBBBBCDDDEFA
Destination: 0x0441074201430344014501460161
Plaintext: .A.B.C.D.E.F.A
使用命令字节,省略会增加大小的序列:

Source: AAAABBBBBBBCDDDEFA
Destination: 0x00044100074243444444454641.
Plaintext: ..A..BCDDDEFA
这在数据的“大理石”部分具有明显的优势

还有一件事,我建议您使用一个类似于midi格式的系统来存储数字,尽管它是little-endian格式。为了省去谷歌搜索的麻烦,它真正的意思是,为了存储数字,每个字节都要牺牲一点。如果设置了第8位,则表示数字中还有另一个字节,并进行级联。例如:

Storing: 65
Stored as: 0x41 (01000001) //The eighth bit is not set, so this number only occupies 7 bits.

Storing: 192
Stored as: 0xC081 (11000000 10000001) //The eighth bit of the first byte is set, so the following byte is part of the number. The second byte doesn't have the eighth bit set, so the number ends there.

Storing: 612453
Stored as: 0x72D825 (11100101 1011000 00100101) //The eighth bit of the first two bytes are set, and the third is not, so this number occupies 3 bytes.

我希望我能提供一些见解。

与依靠文件系统进行组织相比,单个文件会更干净,占用更少的物理磁盘空间。只需在文件的开头维护一个偏移量表,以链接到每个块

就压缩而言,应用游程编码肯定会缩小文件大小,如果它像Minecraft一样,您将有许多相同的块按顺序排列。作为奖励,它将在使用平板驱动器的计算机上更快地加载,因为两个字节可以相当于数千个块,而不必为每个块读取一个字节。这里有一个关于有效运行长度编码的快速提示:使用命令字节,比如0x00。所有其他字节都是一个