Microverse Save System
Overview
GameSaveManager 实现游戏内完整存档/读档。所有角色状态、位置、任务、AI 状态全部持久化为 JSON 文件。
核心架构
GameSaveManager (Autoload 单例)
├── SAVE_DIR = "user://saves/" # Godot 跨平台用户目录
├── collect_game_data() # 序列化所有数据
├── apply_game_data() # 反序列化恢复状态
├── save_game() / load_game() # 读写 .json 文件
└── get_save_files() / delete_save() # 存档管理
保存数据结构
{
"version": "1.0",
"timestamp": 1744000000.0,
"scene_name": "Office",
"characters": [
{
"name": "Alice",
"position": {"x": 512.0, "y": 384.0},
"facing_direction": "down",
"is_sitting": false,
"current_chair": null,
"is_player_controlled": false,
"ai_state": {"current_state": 0},
"tasks": [
{"description": "检查邮件", "priority": 7, "completed": false}
],
"personality": {...} // CharacterPersonality 配置快照
}
],
"rooms": {...},
"global_state": {
"game_time": 1744000000.0,
"settings": {...}
}
}
保存流程
save_game(save_name?)
↓
collect_game_data()
├── collect_character_data() × N (遍历 group:"character")
│ ├── position / facing_direction / is_sitting / current_chair
│ ├── AIAgent: is_player_controlled / current_state / tasks
│ └── personality (快照)
├── collect_room_data() (RoomManager)
└── collect_global_state() (SettingsManager)
↓
JSON.stringify(save_data)
↓
FileAccess.open(SAVE_DIR + name + ".json", WRITE)
加载流程
load_game(save_name)
↓
FileAccess.open(SAVE_DIR + name + ".json", READ)
↓
JSON.parse_string(content)
↓
apply_game_data(data)
├── apply_character_data() × N
│ ├── global_position = Vector2(x, y)
│ ├── toggle_player_control()
│ ├── current_state 恢复
│ └── tasks[] 恢复
└── apply_global_state()
└── SettingsManager.update_settings()
关键设计
节点查询策略
# 通过 group 找到所有角色
var characters = get_tree().get_nodes_in_group("character")
# 按名称精确查找
func find_character_by_name(name: String) -> Node:
for character in get_tree().get_nodes_in_group("character"):
if character.name == name: return character
func find_chair_by_name(name: String) -> Node:
for chair in get_tree().get_nodes_in_group("chairs"):
if chair.name == name: return chair
Property 检查防崩溃
if controller.has_property("is_sitting"):
character_data["is_sitting"] = controller.is_sitting
if ai_agent.has_method("toggle_player_control"):
ai_agent.toggle_player_control(data["is_player_controlled"])
存档目录
const SAVE_DIR = "user://saves/"
# Godot user:// 是跨平台的用户文档目录
# Windows: %APPDATA%/Microverse/user://saves/
# macOS: ~/Library/Application Support/Microverse/user://saves/
自动存档
if save_name.is_empty():
save_name = "autosave_" + Time.get_datetime_string_from_system().replace(":", "-")
# 例: autosave_2026-04-08 10-53-22.json
与 ChatHistory 的持久化对比
| 系统 | 存储路径 | 格式 | 触发时机 |
|---|---|---|---|
| GameSaveManager | user://saves/ |
JSON (结构化) | 手动/自动存档 |
| ChatHistory | user://chat_history/ |
JSON (消息流) | 每次 add_message |
相关
microverse-code-structure — GameSaveManager 位于 script/