【问题标题】:Persisting Game Actor Objects持久化游戏 Actor 对象
【发布时间】:2014-02-24 16:45:31
【问题描述】:

这个问题与我一直在开发的一款游戏有关,但我认为这是一个非常笼统的概念,我还没有找到明确的答案。

我一直在尝试弄清楚如何将actor(游戏世界中的对象)在任意时间动态地序列化到一个文件中

上下文

要理解我的问题,您需要了解世界一般是如何构造的。游戏是一个基于单元的世界,具有 3 个维度,分为更小、更易于管理的部分,我将其称为块。地形信息都是固定的已知长度,我可以很好地序列化这些信息,只要需要将块加载到内存中(比如玩家靠近它),只需使用适当的偏移量向世界文件写入/读取。在我必须处理演员并将它们写入单个文件之前,这一切都很好。

问题

我知道 ISerializable 是一种非常有用的资源,可用于实际从参与者那里获取数据,但我遇到的问题是将其动态提交到磁盘。我的意思是从包含所有演员的大文件的中间插入/删除演员。如果我可以序列化整个游戏状态和演员树会容易得多,但我需要能够一次在世界的一小部分上做到这一点。有些部分没有演员,有些会有很多(最多几百个)。当玩家在世界各地移动时,这些部分会被加载和保存。此外,演员的数量和他们的数据大小会随着游戏的进行而变化,所以我不能像处理地形一样处理它。我需要一种快速提交 actor 的方法,以便稍后我可以快速找到它并且不会浪费大量文件空间。可能有用的一件事是,一个块中的所有参与者都被一次序列化/反序列化,而不是单独的。

注意:这些世界可以变得非常大 (16k x 16k x 6),因此很容易拥有数百万演员。

问题

数据库真的是最好的方法吗?我不反对实施一个,但这是一个涉及的过程,我想确保在我继续之前这是一个推荐的行动方案。似乎可能会对性能产生严重影响。

【问题讨论】:

  • 你应该考虑使用 NoSQL 数据库;可能会简化你的生活......
  • 我使用 Protobuf-net 进行类似的活动。这会将单个或多个实例序列化为一个小文件,
  • @rae1 我正在研究 Redis,但能够找到支持可能是个问题。根据 Aron 的回答,我可能会首先尝试使用更厚的数据库,如果我真的遇到了令人心碎的性能问题,即使使用线程,我也会跳到 NoSQL。
  • 查看FoundationDB。它似乎两全其美。
  • @rae 是的!我很想派一个新手用 C API 编写一个互操作层。 FoundationDB 没有 .net 绑定!

标签: xna persistence polyglot-persistance


【解决方案1】:

传统数据库 (RDBMS) 并不总是正确的方法。但是很遗憾,您正在尝试持久化数据。

大多数 IT 专业人员可能会引导您使用传统数据库,这仅仅是因为对我们来说它不涉及。这是面包和黄油。此外,还有数百个图书馆让我们的生活更轻松,其中最新一代的是完整的ORMs。

但是,正如您所指出的,完整的 RDBMS 对您的应用程序来说有点沉重(取决于您的特定扩展需求)。所以我会建议一些替代方案。

  • MongoDB
  • RavenDB
  • 沙发数据库
  • 卡桑德拉
  • Redis

现在,确实,在许多方面,它们都比 RDBMS 轻得多。然而,这些所谓的 NoSQL(我选择了文档存储,因为它们似乎最符合您的要求)有些不成熟。这并不是说它们有缺陷和不可靠(它们比 RDBMS 具有更高的可靠性),但人们并不真正知道如何使用它们。

再次,我需要限定该陈述。 RDBMS 背后有几十年的研究和最佳实践。每个实现的工具链都有大量的插件。 SO 中的每个贡献者都知道如何很好地使用数据库。但是,对于 NoSQL,这些都不是真的。

TLDR

所以它真的归结为这一点。是的,RDBMS(传统数据库)很复杂,就像现代公路车一样。但就像公路车(你买的)一样,这些都有支持它们的基础设施。

替代方案是 NoSQL 数据库,这就像构建小型电动滑板车。是的,它更简单。但你把它带到汽车店,他们仍然不知道。

终于

我的建议。将现成的 ORM 与 RDBMS 一起使用。当前一代的 ORM 几乎可以对您隐藏您的数据库。该设置不会非常高效(您不会使用它进行微秒算法交易),但它应该足以满足您的需求。

【讨论】:

  • 明白。因此,虽然像 Redis(我正在研究的那个)这样的东西可能会快得多,但这就像在没有救生艇的情况下驶入未知水域。我想我要做的是尝试一个更厚的数据库(但仍然很薄,...sqlite?)并将加载/卸载放入一个侧面线程,因为我已经有一个系统来处理各种状态的块。我很欣赏你的回答冗长。
  • 我对 .net 的 SqlLite 体验一直很差。用于 .net 的 Sqlite 的开源驱动程序只不过是原生 api 的 shim。您下拉的每个单独的行/列(单元格)的结果都是互操作,并且存在大量性能问题。
猜你喜欢
  • 2018-09-06
  • 1970-01-01
  • 2020-03-17
  • 2012-09-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-01-21
相关资源
最近更新 更多