我应该使用文本文件保存数据吗?


22

我的问题是我是否应该使用文本文件保存游戏数据。我对此有一些基本的担忧:

  1. 实际上,没有任何方法可以保护数据,因此,如果用户触摸数据,可能会搞砸一切,而我不希望这种情况发生。

  2. 这可能不是存储数据的最有效方法(将会有很多)

我知道如何有效地解析/写入文本文件,因此对于原型制作来说,它们很棒。我只想着眼于未来,我应该考虑切换到什么地方,这样它就不会在开发快要结束时打我。

如果我不应该使用文本文件,应该使用什么?我需要兼容C ++的东西。


2
压缩文件(带有密码)-有很多可用的库,您可以执行此操作,并且应节省磁盘空间
SeanC 2013年

2
仅使用en.wikipedia.org/wiki/ROT13这样的简单密码就足以防止普通用户编辑文件。其他人可能都知道他们在做什么。
2013年

1
拥有自己的方式,但是我喜欢我的游戏易于修改。
mmyers

Answers:


28

现在,由于您才刚刚开始,因此文本文件可能还可以。我将解决您的问题中的几个问题。

  1. 保护数据并不像您想象的那么重要。如果您的游戏是多人游戏,那么无论如何,您都将数据保存在服务器端。如果您的游戏是单人游戏,那么如果玩家修改数据该怎么办?如果它们损坏了某些东西,那实际上是他们的错,可以重新安装。

  2. 绩效也是我们经常无法正确计划的其他方面。在真正衡量性能问题之前,您不应该真正进行优化。我的猜测是,您可能会拥有不那么大的数据量,并且文本文件就可以了。

话虽这么说,您最好的选择是尽可能地抽象数据保存和加载例程。例如,您可以有一个基类,例如DataWriter,然后提供其不同方法的不同实现。一个非常基本的示例如下所示:

class DataWriter {
  virtual void save(GameState state) = 0;

  virtual ~DataWriter() { }
};

class TextFileDataWriter : public DataWriter {
  virtual void save(GameState state) {
    //write to text file
  }
};

class DatabaseDataWriter : public DataWriter {
  virtual void save(GameState state) {
    //write to database
  }
};

当您最终分析游戏并意识到文件编写例程中存在性能瓶颈时,您可以提供该类的另一种实现(例如,改为写入数据库),而对调用代码的更改最少。


这是一个单人游戏,如果他们想弄乱数据,那正是我的想法。我不知道,关于文本文件的某些知识似乎并不专业,我想知道是否可以防止用户搞砸,我应该这样做。另外,说“数据库”是什么意思?我听过很多话,但是我不知道确切的定义或需要哪种文件。
Althezel

6
@Althezel问题是,无论您如何保存数据,只要有足够的决心进行修改即可。从这种意义上说,尝试实施保护措施通常是浪费您宝贵的开发时间:)
pwny 2013年

@Althezel对于数据库,可以将其视为传递请求以读取或写入数据的引擎。该引擎负责以有效的方式保存/读取它,通常以表的关系形式。在您的用例中,我将看一下SQLite(sqlite.org)。基本上,您将使用C ++库连接到本地SQLite数据库(SQLite使用本地文件),然后以SQL语法传递该库调用以访问您的数据。
pwny

2
当开发人员希望能够将用户锁定在他们存储在其计算机上的信息之外时,这是一个悲惨的世界。
ClassicThunder13年

2
使用文本文件真的感觉很不专业,因为很少有游戏将内容存储为“ save-data.txt”-但是,如果您曾经花时间查看大多数保存的游戏文件,您会发现它们通常只是文本文件而已有时会添加二进制数据。例如,每个《文明与全面战争》系列游戏都使用实际的.txt文件存储各种游戏数据。为此,最常见的“升级”是一个数据库系统,该系统最终将数据存储为平面文件,除了一些二进制blob之外,该文件只是一个文本文件。
BrianH

3

例如,“游戏数据”一词可能有很多含义

  • 游戏状态
  • 配置文件
  • 地图,纹理,声音,脚本,动画数据,...
  • 本土化
  • GUI布局数据
  • 更我没想到

对于每个类别,您可以采用另一种方法。

例如,您可以将SQLite用于本地化,将二进制用于地图,纹理,声音等。

对于配置,您应该使用易于更改的xml文件。

与往常一样,正确的答案是“取决于”。

存在许多具有c ++绑定的xml解析器,并且也存在用于SQLite的c ++绑定。


这可能是出于宗教原因,但我宁愿使用INI文件格式进行配置,而不是XML。在这种情况下,后者感觉像是一种过大的杀伤力。Boost库中有一个INI阅读器。
Artur Czajka

0

您可以将数据另存为二进制Blob,然后在访问该文件时将数据流式传输回去。这将解决您的两个问题。只要确保序列化代码与反序列化完全相同即可。

二进制Blob中的流传输相对较快,并且还防止用户看到数据并进行更改。

您可以使用标准库流来实现所有这些功能。


2
尽管二进制Blob既方便又快捷(无论是开发还是加载/运行),但我对二进制Blob 遇到的最大问题是,一旦您更改有关数据结构组织的任何内容(就像将一个float成员添加到一个单一对象一样)对象),旧的保存游戏就完全无效。在开发过程中很难解决这个问题,但是如果您愿意的话,一定可以。
bobobobo
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.