Xbox/GDK XPA cross platform save roaming not working

Hi, I’ve seen several questions related to this but not one that solves my issue.

We have XSX and Windows (GDK/MS store) versions of our game.
Both are shipped/live, and both versions play properly.
They are both built/cooked/packaged using the in-editor tools.
Both versions are using the same product/title/service config IDs.
They both support save/load and cloud saves, using identical Blueprint logic.
They use a single slot named “Settings” to store global game options, and a single (currently) slot for game progress storage called “SaveSlot1”.
Saving and reloading games works between sessions on both platforms.
We are testing in one of our sandboxes, and have installed both versions using the store.
We have simple sign-in and achievements working on both too.
I have triggered an achievement on xbox and seen the notification pop up on windows.
Saving the game on xbox causes the win store to show data needing cloud syncing, which it appears to do.
Saving the game on windows causes the win store to show data needed upload, which it appears to do.

AND YET!.. Both platforms appear to maintain their own save games independently and don’t seem to share save data.

Blueprint nodes being used are:

  • Gameplay statics:
    • Load Game From Slot
    • Does Save Game Exist
    • Save Game To Slot

The User Index passed to these is obtained from:

  • Player Controller: Get Local Player Controller ID (see code below)
  • Left as zero for Settings save/load (oops, does seem to work and persist alongside the game save though)

Thoughts are:

  1. Something buried in the Partner net UI which we’ve missed to ‘connect the saves’, and allow cross-play.

  2. The user/player/controller id/index/handle being passed to the save functions somehow changes the behaviour of the save process. The calls do say that the “UserIndex” parameter is “The platform user index that identifies the user doing the saving, ignored on some platforms” though so not sure if it is an issue if we’re getting it from the wrong place.

  3. The whole User Index thing could be important, but could be a red-herring. It’s really confusing as there seem to be several different identifiers at play and some are ignore, some aliased, some equivalent. For example…

    int32 UGameplayStatics::GetPlayerControllerID(APlayerController* PlayerController)
    {
    FPlatformUserId UserID = PlayerController ? PlayerController->GetPlatformUserId() : PLATFORMUSERID_NONE;
    return FGenericPlatformMisc::GetUserIndexForPlatformUser(UserID);
    }

Mentions Controller ID, User ID, and User Index all in one function :frowning:

Any more ideas?

P.S. In anticipation of needing to make changes, I hope we aren’t going to invalidate any users saves in the field by fixing this issue :frowning:

See existing question: https://forums.unrealengine.com/t/wingdk-and-xbox-savegame-roaming/2688188

Sorry for the long delay (busy/conference/ill/away). I did finally work out the issue, and it was a line buried in the:

Config/Windows/Custom/MSGameStore/WindowsEngine.ini

It was as follows:

; add this if you are planning on using Xbox cross-platform save games

;[PlatformFeatures]

;SaveGameSystemModule=GDKSaveGameSystem

Basically the GDK save system wasn’t enabled. A real facepalm moment. In my defence the config system for platforms is really inconsistent and I had completely forgotten about that file. It wasn’t until I saw that the version number wasn’t updating properly for MSG builds that I started looking in this direction. By checking my local changes I was able to find the version and then spotted the above. It’s confusing that this can be enabled independently of the GDK as a whole, and I had the service config etc all set up properly in the same file and so achievements were working. Madness.

Thankyou for all the help. I hope this helps someone in the future navigate the MSG config and issues around it.

Anyway, the fix was to uncomment out the lines:

; add this if you are planning on using Xbox cross-platform save games

[PlatformFeatures]

SaveGameSystemModule=GDKSaveGameSystem

Sam