본문으로 건너뛰기
cccskills
무료GitHub에 공개

godot-save-system

Godot 4 存档系统设计,包含资源序列化、加密存储、存档管理和数据回滚。

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

설치 방법 보기

포함된 파일(1)

  • SKILL.md5.5 KB

SKILL.md(원문)

설치하기 전에 에이전트에게 전달되는 지시 내용을 확인할 수 있습니다.

Godot 存档系统设计

概述

存档系统是游戏的核心功能之一,负责保存和加载玩家数据。Godot 提供了 FileAccess、ResourceSaver 等工具,结合 JSON 或二进制格式实现存档功能。

1. 存档管理器

1.1 核心实现

# save_manager.gd (Autoload)
extends Node

const SAVE_PATH := "user://savegame.save"
const ENCRYPTION_KEY := "your_secret_key_here"

signal save_completed
signal load_completed
signal save_error(message: String)

func save_game(data: Dictionary) -> void:
    var file := FileAccess.open_encrypted_with_pass(
        SAVE_PATH,
        FileAccess.WRITE,
        ENCRYPTION_KEY
    )

    if file == null:
        save_error.emit("Could not open save file")
        return

    var json := JSON.stringify(data)
    file.store_string(json)
    file.close()

    save_completed.emit()

func load_game() -> Dictionary:
    if not FileAccess.file_exists(SAVE_PATH):
        return {}

    var file := FileAccess.open_encrypted_with_pass(
        SAVE_PATH,
        FileAccess.READ,
        ENCRYPTION_KEY
    )

    if file == null:
        save_error.emit("Could not open save file")
        return {}

    var json := file.get_as_text()
    file.close()

    var parsed := JSON.parse_string(json)
    if parsed == null:
        save_error.emit("Could not parse save data")
        return {}

    load_completed.emit()
    return parsed

func delete_save() -> void:
    if FileAccess.file_exists(SAVE_PATH):
        DirAccess.remove_absolute(SAVE_PATH)

func has_save() -> bool:
    return FileAccess.file_exists(SAVE_PATH)

2. 可存档对象

2.1 Saveable 基类

# saveable.gd
class_name Saveable
extends Node

@export var save_id: String

func _ready() -> void:
    if save_id.is_empty():
        save_id = str(get_path())

func get_save_data() -> Dictionary:
    var parent := get_parent()
    var data := {"id": save_id}

    if parent is Node2D:
        data["position"] = {"x": parent.position.x, "y": parent.position.y}

    if parent.has_method("get_custom_save_data"):
        data.merge(parent.get_custom_save_data())

    return data

func load_save_data(data: Dictionary) -> void:
    var parent := get_parent()

    if data.has("position") and parent is Node2D:
        parent.position = Vector2(data.position.x, data.position.y)

    if parent.has_method("load_custom_save_data"):
        parent.load_custom_save_data(data)

2.2 使用示例

# 玩家自定义存档数据
class_name Player
extends CharacterBody2D

func get_custom_save_data() -> Dictionary:
    return {
        "health": health_component.current_health,
        "inventory": inventory_component.list(),
        "level": level
    }

func load_custom_save_data(data: Dictionary) -> void:
    health_component.current_health = data.health
    level = data.level

3. 存档数据结构

3.1 完整存档格式

{
    "version": "1.0.0",
    "timestamp": 1712236800,
    "player": {
        "id": "player",
        "position": {"x": 100.0, "y": 200.0},
        "health": 80,
        "level": 5,
        "inventory": [...]
    },
    "world": {
        "enemies_killed": 42,
        "time_elapsed": 3600.0
    },
    "settings": {
        "difficulty": "normal",
        "sound_volume": 0.8
    }
}

4. 场景状态管理

# scene_save_manager.gd
class_name SceneSaveManager
extends Node

@export var saveable_groups: Array[String] = ["saveable"]

func capture_scene_state() -> Dictionary:
    var save_data := {}

    for group in saveable_groups:
        for node in get_tree().get_nodes_in_group(group):
            if node is Saveable:
                save_data[node.save_id] = node.get_save_data()

    return save_data

func restore_scene_state(data: Dictionary) -> void:
    for save_id in data.keys():
        var node = get_node_or_null(save_id)
        if node and node is Saveable:
            node.load_save_data(data[save_id])

5. 自动保存机制

# auto_save.gd
class_name AutoSave
extends Node

@export var auto_save_interval: float = 300.0  # 5分钟
@export var save_on_exit: bool = true

var _timer: float = 0.0

func _ready() -> void:
    if save_on_exit:
        get_tree().node_removed.connect(_on_node_removed)

func _process(delta: float) -> void:
    _timer += delta
    if _timer >= auto_save_interval:
        _timer = 0.0
        perform_save()

func perform_save() -> void:
    var scene_state := SceneSaveManager.capture_scene_state()
    var full_data := {
        "version": ProjectSettings.get_setting("application/config/version"),
        "timestamp": Time.get_unix_time_from_system(),
        "scene": saveable_groups,
        "data": scene_state
    }
    SaveManager.save_game(full_data)

func _on_node_removed(node: Node) -> void:
    if node is Player:
        perform_save()

6. 设计模式总结

模式应用场景
备忘录模式保存/恢复对象状态
观察者模式信号通知存档状态变化
外观模式SaveManager 提供统一存档接口
策略模式支持多种存档格式(JSON、二进制)

7. 注意事项

注意事项说明
数据验证加载前验证存档版本和完整性
向后兼容处理旧版本存档的字段缺失
加密存储敏感数据使用加密
异步操作大型存档使用异步读写

리뷰

아직 리뷰가 없습니다. 사용해 본 소감을 남겨 주세요.

댓글

로그인 없이 쓸 수 있습니다. 사용 후기, 질문, 작동하지 않은 환경 등을 편하게 남겨 주세요.

아직 댓글이 없습니다. 첫 댓글을 남겨 보세요.

보내면 바로 공개됩니다. 이메일 주소나 전화번호 같은 개인 정보는 쓰지 마세요. URL은 2개까지입니다.

0 / 1,000자

이 양식은 reCAPTCHA로 보호되며 Google 개인정보처리방침 및 서비스 약관이 적용됩니다.

같은 저장소의 스킬

Godot 4 Autoload单例模式最佳实践,包含全局管理、事件总线、信号通信。

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

925236118/AlphaAgent1032026년 10월 19일 업데이트

Godot 4 Buff系统完整实现,支持状态效果管理、持续时间、循环效果、层叠机制等。使用Resource+Component架构。

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

925236118/AlphaAgent1032026년 10월 19일 업데이트

Godot 4 建造系统实现,包含GridMap方块管理、第一人称视角、射线交互。

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

925236118/AlphaAgent1032026년 10월 19일 업데이트

Godot 4 ECS实体组件系统模式,包含组件化设计、数据与逻辑分离、组件通信。

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

925236118/AlphaAgent1032026년 10월 19일 업데이트

Godot 4 种植系统设计,包含植物数据结构、生长阶段、浇水机制、TileMap应用。

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

925236118/AlphaAgent1032026년 10월 19일 업데이트

Master Godot 4 GDScript patterns including signals, scenes, state machines, and optimization. Use when building Godot games, implementing game systems, or learning GDScript best practices.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

925236118/AlphaAgent1032026년 10월 19일 업데이트

925236118의 스킬 모두 보기

이 스킬의 문제 신고