-
Notifications
You must be signed in to change notification settings - Fork 78
Restoration
woctordho edited this page Jan 27, 2022
·
36 revisions
这篇文档对应的是master
branch上的旧版的存档系统。我们已经发现了它的设计有一些问题,你可以换成new_checkpoint
branch上的新版。新版的文档在这里。
- 保存和读取各种前端组件(图片、BGM等)的状态
- 在对话中设置变量,用变量控制剧情分支,在读档时恢复变量
- 在小游戏中设置变量,此时变量取决于玩家输入
- 在章节选择界面和文本回顾界面中跳转到一条已经到达过的对话
- 读档时恢复文本回顾界面的内容(这个版本的存档系统会有bug,新版已经修了)
- 在文本回顾界面中回跳时,恢复更早的文本
- 占用的硬盘空间足够小
- 读写文件的速度足够快
- 每个有状态的前端组件实现
IRestorable
,它的状态表示成IRestoreData
- 在
CheckpointManager.WriteSave
中,每个IRestoreData
用BinaryFormatter
序列化成二进制流,再用DeflateStream
压缩,再写到文件- 存档的状态一般是很稀疏的,所以需要压缩
- 我们没有提供存档加密功能,因为代码是开源的,如果需要加密请自行解决
- TODO:
BinaryFormatter
已经被微软官方deprecate了,以后我们可能会换成JSON或者其他格式
- 需要存档的状态(checkpoint)由全局变量(
CheckpointManager.globalSave.data["global_variables"]
)、(局部)变量(GameState.variables
)、节点名称(GameState.currentNode.name
)和对话序号(GameState.currentIndex
)唯一确定- Checkpoint与分支选项无关,如果两个选项从同一个旧节点跳转到同一个新节点,它们不会造成不同的状态
- 每条对话都有一个
GameStateRestoreEntry
,保存这条对话的(default stage的)代码块运行之前所有前端组件的状态,记录在CheckpointManager.globalSave.savedNodes
中- 读档时,先恢复目标对话的状态,再运行目标对话的代码块
- 为了支持持续动画(详见演出系统),并减少存档占用的空间,
GameStateRestoreEntry
分为两类:-
GameStateCheckpoint
完整记录所有前端组件的状态 -
GameStateSimpleEntry
不记录这些状态,只记录上一个GameStateCheckpoint
的相距步数- 读档时先读取上一个
GameStateCheckpoint
,再快进到GameStateSimpleEntry
的位置
- 读档时先读取上一个
- 我们避免使用full/raw/real checkpoint之类的说法
-
- 快进时,如果之前到达过一条对话,无论现在的变量如何,这条对话都视为已读
-
CheckpointManager
有方法GetReachedForAnyVariables(string nodeName, int dialogueIndex)
-
- 存档/读档界面中的每个存档称为书签(
Bookmark
),记录一条对话的变量hash、节点名称和对话序号- 读档时,提供这些信息就能恢复checkpoint
- 自动存档、快速存档与手动存档的格式是一样的
- Log界面中的每个
InitParams
记录一条对话的变量hash、节点名称和对话序号- 回跳时,提供这些信息就能跳转到那条对话
- 为了在读档时恢复log,每个checkpoint中保存上一个checkpoint到它之前的所有
InitParams