Persisting data on level changes in multiplayer with GameInstance and PlayerState

So i am working on a lobby in an RTS style multiplayer game and trying to persist data like player color and team from the lobby level through to the main level. So far i have done everything in blueprints. Most of the forum stuff on this is old (~2016) so i thought i might ask the question again

There are two options i am aware of - Game instance and PlayerState->CopyProperties.

For game instance, I can store an array of my players lobby choices, along with a unique identifier for the player state, and then repopulate the player state after level load.

So far i have managed to retrieve data from game instance, and i am a little unsure which property i should use to identify the player again. There is a player ID in the player state but does this persist over level changes? I am using an advanced sessions plugin to handle connecting over steam, but its unique NET ID seems a little dodgy. So any insight in how to do this well would be great.

That brings me to the copy properties, which seems like the ‘correct’ way to do the above. This has a blueprint node that, when looking at the previous comments, seems pointless as variables cant be blueprint readWrite? so it seems that this can only be used in C++? All this info seems to be close to 8 years old so maybe this node is useable now but when i try it, nothing is copied across. I have made sure seamless travel is enabled, and tested in standalone as i read things may not work in PIE.

I am hoping someone may have some insight in what the most direct and correct way to do this would be, I feel like i am looking at 2 dodgy options, CopyProperties seems ‘correct’ but also broken, and i could set myself up to work with it in C++ only to get lost and have little documentation to help me. Using the game instance will probably work if i can reliably identify the player, it just seems like CopyProperties was there to solve this issue.

player state is rebuilt on travel so do not key the lobby data by the player state reference, key it by something that survives, like teh unique net id string. store a struct of colour, team and that id in an array on a game instance subsystem, then repopulate each new player state once the next level is up.

a plain game instance variable works too, but a subsystem keeps the array out of a class you may want to keep thin and any blueprint can fetch it by class without casting to your game instance.

you can also try Blueprint Subsystems Bridge, a blueprint scripting plugin for Unreal Engine that lets you create game instance subsystems without writing c++: Blueprint Subsystems Bridge — Game Instance, World, Engine & Player Subsystems | Fab