保存游戏数据的良好文件格式是什么?[关闭]


37

我需要保存一些自定义游戏数据。地图,播放器等

它们都将具有“子对象”。例如,地图和地图将具有图块的“阵列”。即分层数据。希望没有二进制文件。

什么是这些的好格式?

到目前为止,我已经考虑过:

序列化:这是快速且容易的,但是当我更改基础类时往往会中断:(

XML:我真的很讨厌解析这个。我的测试用例超过了100多行代码,即使是非常简单的格式,也似乎需要大量的“忙碌工作”。

INI:对于分层数据来说真的很笨拙。

Protobuf:从未使用过它,但请阅读,如果您更改班级,则必须做很多手动修改,然后休息。

还有其他选择吗?这就是为什么我在这里!

编辑:这是Java顺便说一句。

编辑2:

我选择了“受控二进制序列化”(见下文)。

优点:

  • 它很快

  • 它很小(在磁盘上),可以在读/写过程中轻松压缩/解压缩。

  • 从游戏和工具集读取/写入非常容易。

  • 我可以决定要包含/排除对象的内容。

  • 对象/数据可以嵌套。

缺点:

  • 无法手动编辑(例如XML,YAML等)

  • 使用脚本无法轻松读取/修改它

  • 与其他实现相比,默认情况下,Java序列化速度相当慢/膨胀,但它稳定且有效


3
逗号分隔值
Thomas Eding

@trinithis KISS很棒。
Nate

3
不要落入陷阱的思维CSV解析很简单:secretgeek.net/csv_trouble.asp
四联

有趣的是,ProtoBuf旨在支持可升级性。
乔纳森·迪金森

ini用于用户可修改的所有内容,例如设置等;和二进制的其他一切。
维吾尔族Gümüşhan

Answers:


38

要显示层次数据,YAMLJSON是不错的选择。他们是更简单,更容易解析比XML。

另一个选择是“受控”二进制序列化过程。每个对象都以受控方式将其状态写出,即

void player::save(savegame &sgm)
{
    sgm.write(this->position);
    sgm.write(other properties);
    inventory.save(sgm);
}

id Tech 4(Quake 4 / Doom 3引擎)使用了这种方法。


+1用于“受控”二进制序列化。我在工作中使用它,很棒!
NoobsArePeople2 2011年

1
用于“受控”二进制序列化的另一个+1。尽管我以前从未听说过这个名称,但我在一些地方做了类似的事情-正确的做法是,它的优点是能够为数据文件中不存在的新添加字段设置默认值,并忽略“从模型中删除字段时,数据文件中的“垃圾”。
2011年

我在游戏中使用了类似的方法。效果很好!我使用Java。每个对象都有一个写入文件流的ToByteStream方法和一个从文件流读取的构造函数。我不喜欢Java的Serializable实现。
MichaelHouse

4
或者,您可以只使用Boost.Serialize并获得出色的功能,例如版本控制等。
Nicol Bolas

@Izkata我已将其命名,因为我不知道该方法的调用方式。
拉斐尔R.11年

9

精心制作的二进制格式确实具有所有优点,它速度快,相当小,并且具有与您制作时一样灵活的功能。

使二进制格式不受任何规则的束缚,这是一个很大的优势,但是具有讽刺意味的是,这很大程度上是给二进制文件结构起了一个不好的名字。XML,JSON等会为您做出很多决策,虽然它们并非总是最佳选择,但是它们是相当安全的选择,通常可以帮助您避免一些其他常见问题。

找出这些问题,在设计这些格式时要牢记这些,您可以制作出不错的二进制格式。

如果您没有足够的经验/信心来制作二进制格式,并且数据量足够小而对速度的影响可以忽略不计,那么我建议您使用JSON,它很简单,但是可以做到。


6

您选择的文件格式在很大程度上取决于您当前的工具集和您打算制作的游戏。照这样说...

在确定游戏文件格式时,工具集是最重要的因素之一。如果使用二进制格式,则必须始终确保您具有输入游戏数据的工具。这可能像十六进制编辑器一样简单,也可能像虚幻编辑器一样复杂。

我猜想XML,YAML或任何其他语言文件的主要优点是,您可以通过文本编辑器轻松地对其进行编辑。并且使用现有标准,可以确保您不会出错。但是,当您有数千个文件时,这非常繁琐,这使我想到了下一个问题。

游戏。您正在制作哪种游戏?为什么我说这会影响文件格式?因为,如果要制作类似2D bomberman的东西,则可以使用一个简单的文本文件,例如:

*********
*1     2*    1,2,3,4  - start point of players 1, 2, 3, 4
* + + + *    *        - walls
*       *    +        - crates
* + + + *
*3     4*
*********

换句话说,请始终为您的特定数据选择最明显的格式角色扮演游戏是制作最复杂的游戏类型。他们需要大量数据。但这并不意味着您必须为游戏中的所有数据保留特定格式,无论是二进制格式还是基于文本格式

  • 地图,粒子和其他图形素材倾向于使用自定义二进制格式。因为这是实现它的最简单方法。用文字描述地图不是人类的理智。通常通过地图/级别/粒子编辑器进行编辑。
  • 玩家,物品,敌人,技能和任务是影响游戏平衡的统计数据。他们通常需要大量的输入和调整。我喜欢通过将其放在XML文件中来简化实现,但是还拥有一个供设计人员使用的对象编辑器。两全其美

通常,您要用文本格式描述文本,并用二进制格式描述图形。下面应该给你一个例子:

<Skill>
    <Name>Fireball</Name>
    <Animation>fireball.dat</Animation> <!-- Graphics described in another file -->
    <Attack>1.3</Attack>
    <Cooldown>15</Cooldown>
</Skill>

综上所述,我的最大建议是,除非绝对必要否则请不要编写数据脚本。最终用户不在乎格式有多棒,只要游戏可以玩,那就很重要了。

干杯,罗伊=)


5

BSON很好。 http://bsonspec.org/。它比JSON解析起来更容易,并且在包含二进制数据方面也更好,但是仍然具有良好的结构。它有点类似于协议缓冲区。不利的一面是,在mongodb之外似乎有很多工具支持它。

编辑:MsgPack(http://msgpack.org/)也类似于BSON,并且似乎正在获得更大的吸引力。


1
虽然我认为“二进制JSON”的想法很好,但我对BSON却不太信任,但有太多(冗余)数据类型,文档也很烂。
aaaaaaaaaaaaaa

2

您的自定义二进制数据格式发生了什么?如果您担心原始序列化,请编写自己的系统,该系统根据需要写入字段,然后将其读回。不需要xml,在不需要格式提供的透明性的情况下,这确实是非常庞大和复杂的。只需定义一个明确指定的文件格式并坚持下去,就可以通过在每个记录中填充空值(例如您现在有一个100字节的记录,然后将其填充到150以供将来使用)留出一些扩展数据集的空间。
添加一个版本号,或者添加一个校验和,这样您就可以知道应该填写哪些字段并进行有效性检查,这很高兴。


1

您可以将XML或其他格式与Base64插入混合使用以获取某些特定数据,对于需要可读性的字段,可以使用常规的TEXT。

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.