How do I carry over player start choice after a seamless travel? game instance does not work.

I am building a multiplayer game with dedicated server.

After all players connect to the server, they first enter a lobby map, where they can choose their spawn point. After everyone is ready, a server travel is called to bring everyone into actual game map. The travel is seamless.

My problem is there is no way to transfer the choice they made in lobby map to actual game map when “ChoosePlayerStart()” event is called. We know that in order to transfer data between level we need to use game instance. Game instance dose not replicate, so I have to use RPC to deliver any info from client side game instance to server side player controller. However the event “ChoosePlayerStart()” is called too early that RPC is not possible at that stage. By the time any RPC is allowed to be called, the gamemode has already chosen the spawn point for the pawn(I think the character is even already spawned). I do not find any way to delay the ChoosePlayerStart(), or delay the spawning process to happen after player controller RPC is allowed.

How should I solve this problem?

One solution I come up with is to use Server Side Game Instance(which is completely independent from client side game instance, GI does not replicate) to store a list of player controller and their spawn choice. However there is no way for me to identify which player controller represents which player in previous map. I tried to use Get PlayerControllerID on server side and they all return -1.

One more thing that confuses me is that in document it says Seamless travel should automatically bring gamemode to next level(Travelling in Multiplayer | Unreal Engine Documentation), however I don’t think they carry over in my case. When I travel from lobby level to my actual game level, all the gamemode/player controllers are gone.

Hope someone can help me on this. Those are actually three separate question but related to each other. Really appreciate any advice. Thanks!

How are you calling server travel?

After client press the button, call a RPC in player controller and then at server side use “Execute Console Command” with input “ServerTravel GameplayMap”
It requires the game to launch at standalone mode.

Alright, I find the solution myself.

In case anyone in the future has the same problem:
Use “OnSwapPlayerControllers()” event in game mode. That thing is called before “ChoosePlayerStart()”