tl;以粗体显示
我目前正在开发基于文本的冒险游戏,并且我已经实现了一个基本的保存系统。
该过程利用了'pickle'模块。它生成或附加到具有自定义扩展名的文件(实际上,它是文本文件)。 引擎腌制玩家的位置,他们的库存,以及最后一部分是有点奇怪的地方。
游戏从特殊格式的脚本加载对话框(这里我的意思是在演员的脚本中)。某些对话框会根据某些条件(之前已经说过,新事件等)进行更改。因此,对于引擎保存的第三个对象,它将所有对话树保存在其当前位置。如同,它将文字脚本保存在当前状态。
以下是保存程序:
with open('save.devl','wb') as file:
pickle.dump((current_pos,player_inv,dia_dict),file)
for room in save_map:
pickle.dump(room,file)
file.close()
我的问题是,这个过程是一个非常丑陋,非常冗长的超大文本文件。现在我知道文本文件基本上是我可以生成的最小文件,但我想知道是否有任何方法可以压缩或以其他方式更有效地记录游戏中所有内容的状态。或者,从长远来看,不太优选但更好,只是一种更智能的方式来保存玩家的数据。
请求了对话框的格式。这是一个示例:
[Isaac]
a: Hello.|1. I'm Evan.|b|
b: Nice to meet you.|1. Where are you going?\2.Goodbye.|c,closer|
c: My cousin's wedding.|1. Interesting. Where are you from?\2. What do you know about the ship?\3. Goodbye.|e,closer|
closer: See you later.||break|
e: It's the WPT Magnus. Cruise-class zeppelin. Been in service for about three years, I believe.||c|
standing: Hello, again.|1. What do you know about the ship?\2.Goodbye.|e,closer|
括号中的名称是程序如何识别要调用的树。每个字母都是树中的一个单独分支。这些分支将分支分为三个部分:1。角色说的是什么2.允许的回答3.每个响应发生的地方,或者玩家没有回应,玩家之后被指示的地方。
在此示例中,在玩家与Isaac交谈后,“a”分支将从游戏存储在内存中的树的副本中删除。然后它永久使用“常设”分支。
答案 0 :(得分:0)
Pickle本身有其他协议比默认协议(协议0)更紧凑 - 这是唯一一个基于文本" - 其他是二进制协议。
但他们,你几乎不会超过文件大小的50% - 为了能够提高答案,我们需要更好地了解你正在拯救的 以及是否有更聪明的方法保存数据 - 例如,避免重复相同的子数据结构(如果它存在于您的几个房间中)。 (虽然如果你在游戏中使用对象身份,那么Pickle应该照顾它。)
那就是说,只需更改你的pickle.dump调用以包含协议参数 - GTLRDriveQuery_PermissionsCreate *createPermissionQuery =
[GTLRDriveQuery_PermissionsCreate queryWithObject:permission
fileId:fileId];
...
[driveService executeQuery:createPermissionQuery
completionHandler:^((GTLRServiceTicket *ticket,
GTLRDrive_Permission *permission,
NSError *error) {
if (error == nil) {
// work directly with permission
...
}
}];
值相当于" HIGHEST_PROTOCOL",这通常是效率最高的:
-1
(加载泡菜不需要传递协议)
另外,您可能希望使用Python的zlib接口来压缩pickle数据。这可能会让你再减少20-30%的文件大小 - 你必须将调用链接到file.write,zlib.compress和pickle.dumps,这样你可以通过一些辅助代码更容易 - 你还需要控制文件偏移量,因为zlib不像pickle那样推进文件指针:
pickle.dump(room,file, protocol=-1)