Steam 云存储同步游戏存档

在开始开发之前,有两个重要的决定需要做:

  1. 是否使用 Steam Auto-CloudSteam Cloud APISteam Auto-Cloud 相对容易设置,但有一些缺点:它不隔离单独用户的文件,因此如果两个 Steam 帐户在同一台电脑上运行,他们会共享文件;它只在启动/退出时同步,而使用 API 时可以控制何时同步,并且可以利用 Steam Deck 的动态云存储。因为我现在处于测试阶段,需要在下周内完成,因此我选择使用 Steam Auto-Cloud,但我打算在后续更新中使用 API。

  2. 当在 GameMaker 中保存时,应该使用缓冲区以实现跨平台的兼容性。在这里也有两个选项: buffer_savebuffer_save_async。前者适用于轻量级文件,不会降低帧率,而后者适用于保存较大的文件;我将使用后者来保存玩家的游戏进度(此时应该添加一些动画图标并提示玩家不要关闭游戏)。

使用 Steam Auto-Cloud 的步骤非常简单。

  1. 安装 Steamworks 扩展,并完成其设置。详细文档请参见:YoYoGames/GMEXT-Steamworks Wiki
  2. 创建一个类似于 oSteamManager 的对象,并在 step event 中调用 steam_update(),在 game end event 中调用 steam_shutdown()
  3. 在 Steamworks 中设置云存储配置,并选择同步的路径。GameMaker 保存在 % localappdata% 中,因此在根路径中会有如下内容:Root: WinAppDataLocal | 子目录 <Game Name> /cloud | 模式:*.sav | OS:All
  4. 当在 GameMaker 中保存时,保存文件到同一路径。注意:不建议保存所有配置到云存储中;例如,屏幕分辨率在 Steam Deck 上会因为玩家之前在 4K 监视器上玩游戏而出现问题,所以我只保存需要同步的内容到 /cloud 中。

代码示例:

function Save_Audio_Settings(){
    // 保存音频设置
    var _saveAudio = {
        master: round(audio_get_master_gain(0) * 100),
        soundFX: round(audio_group_get_gain(audiogroup_soundEffects) * 100),
        music: round(audio_group_get_gain(audiogroup_music)*100),
    }

    // 将数据转换为 JSON 字符串并通过缓冲区保存
    var _string = json_stringify(_saveAudio);
    var _buffer = buffer_create(string_byte_length(_string) + 1, buffer_fixed, 1);
    buffer_write(_buffer, buffer_string, _string);
    buffer_save(_buffer, SAVE_AUDIO);
    buffer_delete(_buffer);
}

function Load_Audio_Settings(){
    if (file_exists(SAVE_AUDIO)) {
        var _buffer = buffer_load(SAVE_AUDIO);
        var _string = buffer_read(_buffer, buffer_string);
        buffer_delete(_buffer);

        var _loadData = json_parse(_string);
        show_debug_message("Load! " + string(_loadData))
        // 应用音频数据
        audio_master_gain(_loadData.master/100);
        audio_group_set_gain(audiogroup_soundEffects, _loadData.soundFX/100);
        audio_group_set_gain(audiogroup_music, _loadData.music/100);
    }
}

// 为文件位置设置宏
#macro SAVE_AUDIO "cloud/audioSettings.sav"
#macro SAVE_VIDEO "videoSettings.sav"
#macro SAVE_CONTROLS "cloud/controlsSettings.sav"
#macro SAVE_UNLOCK_PROGRESS "cloud/unlockProgress.sav"
#macro SAVE_RUN_PROGRESS "cloud/runProgress.sav"