Changes between Version 3 and Version 4 of Ticket #14737


Ignore:
Timestamp:
Apr 1, 2024, 11:00:53 AM (5 weeks ago)
Author:
fusefib
Comment:

Here are some additional thoughts on this matter:

    if ((_game.id == GID_BIRTHDAYYELLOW || _game.id == GID_BIRTHDAYRED) && _targetName.find("BluesBirthday") != 0) {
        // Prepend generic name for shared game profile between targets
        // for Yellow CD and Red CD of Blue's Birthday Adventure,
        // but only if target name begins with "BluesBirthday" (default).
        filePath = "BluesBirthday-" + filePath;
    } else {
        // Prepend the target name
        filePath = _targetName + '-' + filePath;
    }

This adds a placeholder condition that the target name must start with "BluesBirthday" - this allow the user to manually change target's name (ID: in the GUI) to revert back to the old ways of per-target savegames, if that's ever desired.

However, for a better UX solution and one that allows using old savegames, this condition should probably be changed to a GUI-accessible game configuration key that's disabled by default (e.g. boolean "avoidSharedBirthdaySaves").

Sev suggested a mass-rename, so below is a partial solution. It's pretty seamless and doesn't bother the user with a GUI prompt.

void processBirthdaySaveFiles() {
    // Condition 1: Check game ID and that target name begins with "BluesBirthday"
    if ((_game.id != GID_BIRTHDAYYELLOW && _game.id != GID_BIRTHDAYRED) || _targetName.find("BluesBirthday") != 0) {
        return;
    }

    // Condition 2: Check for existing shared savegame files
    if (!_saveFileMan->listSavefiles("BluesBirthday-Blues1.nam").empty()) {
        if (!_saveFileMan->listSavefiles(_targetName + "-Blues1.nam").empty() && _targetName != "BluesBirthday") {
            debug("Old savegame files for target/ID '%s' detected, but ScummVM is using shared savegame files instead.", _targetName.c_str());
            return;
        } else {
            return;
        }
    }

    // Condition 3: Check if target name matches BluesBirthday or no existing target save files
    if (_targetName == "BluesBirthday" || _saveFileMan->listSavefiles(_targetName + "-Blues1.nam").empty()) {
        return;
    }

    // Rename save files
    Common::StringArray targetFilenames = _saveFileMan->listSavefiles(_targetName + "-Blues1.nam");
    targetFilenames.append(_saveFileMan->listSavefiles(_targetName + "-*.bca"));
    targetFilenames.append(_saveFileMan->listSavefiles(_targetName + "-*.sg?"));

    Common::String oldName, newName;

    for (uint i = 0; i < targetFilenames.size(); ++i) {
        oldName = targetFilenames[i];

        newName = oldName;
        newName.replace(_targetName, "BluesBirthday");

        if (_saveFileMan->renameSavefile(oldName, newName)) {
            debug("Renamed %s to %s.", oldName.c_str(), newName.c_str());
        } else {
            warning("Error %i (%s) occurred while renaming %s to %s", _saveFileMan->getError().getCode(),
                _saveFileMan->getErrorDesc().c_str(), oldName.c_str(), newName.c_str());
            return;
        }
    }
}

Basically:

  • if non-gameID-target savegames exist and shared savegames exist: warn in console, but don't do anything (i.e. run shared savegames);
  • if non-gameID-target savegames exist and shared savegames don't exist: rename target savegames to shared savegames;
  • otherwise, don't do anything.

It's in untested doodled form, and I'm not sure where it's best wired in. It should be done once every time the target starts.

As suggested with the filePath part, the _targetName.find("BluesBirthday") != 0 condition should probably be changed to checking some avoidSharedBirthdaySaves bool thing, and this should become a disabled-by-default option in the GUI. This way, users can choose to utilize their target's existing savegames by checking 'Avoid shared savegames (not recommended)' in the Game Options or something like that.

Legend:

Unmodified
Added
Removed
Modified
  • Ticket #14737 – Description

    v3 v4  
    1414...
    1515}}}
    16 ''Blues1.nam'' and ''[PlayerName1].bca'' are shared between the CDs and contain the game profile, i.e. sign-in information and overall game progress across e.g. minigames from all four pathways. The first has name/color/birthday in INI-format (when uncompressed); the other is a light, player-specific game progress file. When you create a sign-in profile and proceed, both get generated. ''[PlayerName1]'' is whatever gets chosen.
     16''Blues1.nam'' and ''[PlayerName1].bca'' are shared between the CDs and contain the game profile, i.e. sign-in information and overall game progress across e.g. minigames from all four pathways. The .sga to .sgd files are pathway-specific savefiles that get generated once you enter a pathway and the game saves progress. [PlayerName1] is whatever gets chosen.
    1717
    18 The ''.sga'' to ''.sgd'' files are pathway-specific savefiles that get generated once you enter a pathway and the game saves progress.
    19 
    20 ScummVM generates the same type of savefiles, albeit compressed, though its behavior is to prefix the files with the game entry's **target**. Targets get incremented if one adds, ID-wise, the same detected game again. With the Yellow CD and Red CD being considered separate games with one default `gameID`, in a typical scenario we get "**BluesBirthday-**" and "**BluesBirthday-1-**" as default savegame prefixes, thus:
     18ScummVM generates the same type of savefiles, but its behavior is to add "[gameID]-" as a prefix to these savefiles, and to increment gameIDs (or targets) when adding what is considered ID-wise the same game. With the Yellow CD and Red CD being considered separate games with one default gameID, we get "**BluesBirthday-**" and "**BluesBirthday-1-**" as default savegame prefixes, thus:
    2119{{{
    2220BluesBirthday-Blues1.nam
     
    5250Per MD5s and detection entries, there is only one known Red version and Yellow version of the full game and demos don't create these files, so probably zero compatibility issues on that account.
    5351
    54 The gameID-based prefix remains useful so users can distinguish these savegames among other ScummVM saves as well as partial overlap with the existing default naming.
     52The prefix remains useful so users can distinguish these savegames among other ScummVM saves as well as partial overlap with the existing default naming.
    5553
    56 A minor drawback is the other target's (e.g. "BluesBirthday-1") progress gets reset to zero, unless the user manually swaps the savesets which would still exist. But the inconvenience is minor.
     54A minor drawback is the "BluesBirthday-1-" progress gets reset to zero, unless the user manually swaps the savesets which would still exist. I would say the drawback is minimal and the possibility of restoring game profiles by renaming can simply be documented in the game's Wiki entry.
     55
     56A seamless user experience fix might be to newly add a game configuration key by default (e.g. boolean "sharedsaves") when adding these games going forward, and to add a check for that configuration key in the code above. This way, (the other half of the) existing entries will continue to work with the current savegame naming convention and newer entries will have shared game sign-in and progress by default. However, this needlessly clutters the code.