跳到主要内容

存档与持久化

相关源文件

概览

存档与持久化系统管理所有需要长期保存的游戏状态:包括玩家成长、装备、技能、世界状态以及设置项。系统实现了“双存储”架构:以本地 SQLite 数据库作为主存储、JSON 文件作为备份,并结合内存中的运行时缓存,以实现零延迟的场景切换。云同步通过 CloudSyncService 集成提供支持。

关于 UI 层的存档菜单交互,请参见 User Interface。关于会消费运行时缓存数据的场景切换机制,请参见 Scene Transitions


系统架构

持久化层采用三层架构:存储层、序列化层、运行时缓存层。

架构:存档与持久化系统

该系统把关注点拆分为明确的层:

  • 客户端层(Client Layer):场景与 UI 通过 SaveManager 单例交互
  • 运行时缓存(Runtime Cache):在内存中缓存玩家/世界/会话数据,供无缝切场景使用
  • 序列化(Serialization)JsonSerializer 负责 JSON 双向序列化/反序列化
  • 存储层(Storage Layer):主存为本地 SQLite KV(localStorage),JSON 文件作为备份
  • 云层(Cloud Layer)CloudSyncService 上传/下载/同步所有槽位

SaveMenuLayer 模式

SaveMenuLayer 用统一的 UI 覆盖“存档/读档/开局/云操作”等多种入口场景,模式决定显示哪些按钮以及按钮行为。

架构:SaveMenuLayer 模式系统

模式决定显示哪些按钮及其行为。所有模式都共享“云同步”按钮,用于手动进行双向同步。

槽位 UI 布局

布局:单个槽位节点

每个槽位展示来自 SaveSlotData 的元信息(空槽位则显示“空槽位”),并根据上下文显示对应的操作按钮。

回调集成

回调设置者触发时机用途
LoadSuccessCallback外部调用者读档成功把加载数据回传给调用方
StartSlotCallback外部调用者START 模式选择槽位开始新游戏或加载
CloseCallback外部调用者菜单关闭GameScene 中恢复暂停状态

模式位于 Adventure-King/Classes/Scenes/Layers/SaveMenuLayer.h L45-L57

云端状态显示

逻辑:云端状态标签

状态标签由 refreshCloudStatusLabel() 更新,该函数会查询 CloudSyncService 的状态。

来源:Adventure-King/Classes/Scenes/Layers/SaveMenuLayer.cpp L1-L768

Adventure-King/Classes/Scenes/Layers/SaveMenuLayer.h L1-L122


汇总表

关键类

文件主要职责
SaveManagerSaveManager.h L20-L335负责统筹所有持久化的单例
JsonSerializerJsonSerializer.h
/ JsonSerializer.cpp
JSON 双向序列化
SaveMenuLayerSaveMenuLayer.h L14-L122存/读档 UI 模态层
CloudSyncServiceCloud/CloudSyncService.h云备份协调

存储位置

实体SQLite KeyJSON 文件备注
存档槽位 Nak_save_slot_Nsaves/save_N.jsonN ∈ [0, 4]
设置项ak_settingssettings.json音频/控制配置
数据库N/Asaves/adventure_king_save.dbSQLite 文件

运行时缓存键

缓存标记GetterSetterClearer
玩家数据_hasRuntimePlayerDatagetRuntimePlayerData()setRuntimePlayerData()clearRuntimePlayerData()
玩家位置_hasRuntimePlayerPositiongetRuntimePlayerPosition()setRuntimePlayerPosition()clearRuntimePlayerPosition()
进度数据_hasRuntimeProgressDatagetRuntimeProgressData()setRuntimeProgressData()clearRuntimeProgressData()
会话职业_hasSessionSelectedRolegetSessionSelectedRole()setSessionSelectedRole()clearSessionSelectedRole()
活跃槽位_hasActiveSaveSlotgetActiveSaveSlot()setActiveSaveSlot()clearActiveSaveSlot()