Download

Seamless Travel - Persisting Data

Hello all, I’m using a dedicated server, and I’ve been struggling for a week trying to create a solid workflow to keep the data from one level to another.

I have a scene where time is being counted, and each player has his own player info struct (player name, selected character, etc…).
After a round has ended, the game mode loads a new map (actually it’s the same map).

Here is my problem, I can’t seem to be able to keep any data from the previous scene to the current scene. Although I am sending the game state’s data using parameters in the “execute console command” (ServerTravel MapName?Var1=value1?Var2=value etc…). Then I’ve tried in both the “Event OnSetMatchState” and the “PostSeamlessTravel” (Created a C++ script for that to be exposed to blueprint) to set these parameters in the game state, although the parameters are being fetched and printed correctly, and saved successfully in the game state, but later on the variables have their default values. I figured maybe the game state I’m setting in is still the old one before the new one has been created? (just guessing!)

Same goes for the player state. I’ve used the “Event CopyProperties” to set the new data from the old player state into the new player state, and the data is correct if I print it out. But same as the game state, the variables later on are in their default values.

541c5c0f5d788b29d4206a01a9177fbb9838678c.png

a706121bfb784ed2e5aaac028309eb5a7dd4f9ab.png

7f46daf25c8249f305ff0bd58a8abaac15178414.png

Can you guys please guide me to the proper way of initializing the values after seamless travel? So that I can respawn the players with their data and still have the game state’s variable values.

Thanks in advance! :slight_smile:

Have you tried storing and reading the data from the Game Instance BP instead?

Hey there Gmi, no i haven’t tried saving and reading from game instance, I’ll try it later at night.
But what difference might it make since i am able to read the data using the options string?

I haven’t used that option string method so I’m not sure, but any data within the Game Instance blueprint is stored between levels. Other blueprints get wiped. I always use the Game instance when I have to load something or create a save file before loading it again after changing levels.

Well the thing is i can’t save the player state in the game instance because each player controller has its own player state, and the player controllers get reassigned on seamless travel (as i have read).

“Event Copy Properties” is said to work, but i don’t know if i have setup something wrong :confused:

Can’t you just keep a name variable or some kind of ID for each player and then just look through the array of player states or controllers for the correct one?

I used game state and game mode to first load a save file and then look up different players in my player struct array and apply correct settings/saved data to each based on name and/or steamid.

I haven’t really run into any issues yet with the wrong pcs being attached to players… so far at least.

Hmm, that seems like a nice idea to try. I will definately give it a try tonight, but it will take a lot of work :frowning:

I will give my feedback once i’ve tried it.

Thanks Gmi :slight_smile:

Yep, it’s a bit of a work :stuck_out_tongue: if you don’t figure it out I might dig up my old files and post some pics (although it’ll be quite messy I suppose) when I have time.

I saved two arrays in the game instance, one for the player id (Steam id) and the other for the player state. And the index of each array matches the other.
Right before executing the seamless travel console command, I’m looping the player states and saving them in the game instance.

Now after the seamless travel is done and the map is loaded, I need to fetch the player state for each player, but how am I to send them the correct player state?
The players now don’t have any data after the seamless travel, so they don’t have any id assigned to them. All I could think of is fetching it from the game instance on each client (in a way or another) but that isn’t a secure way because the variable is stored locally and can be manipulated with.

Any suggestions?

I’m pulling my hair out over here… Please can someone help me in this, this should be a basic thing to do but i’m facing trouble with it no idea why :frowning:

I have concluded that the player state’s data is correct if I display it on the server, but it is not being replicated on to the client after seamless travel.

Any idea why?

   @KingOfProgramz

The way I do it roughly is:

  1. Before quitting the game, or loading a new level or whatever, in each players state, I gather all data I want to be saved about that player and put it in a single struct (including name, steam id, stats, progress, location, class etc etc) (lets call it PlayerStruct)

  2. The server loops through each player state, gets the newly updated player struct and saves it in an array of PlayerStructs. I then save that Array of PlayerStructs to a file.

  3. When a new level opens or a game is continued or whatever, every connected player checks their game instance (since clients only see their instance) and sends their own name and/or steamid to the server.

  4. On the server, compare every connected players name and/or steamid with every saved index in the array of PlayerStructs from step 2. I basically get each saved player struct, one at a time, break the required info output and compare it to the current player.

  5. If a match is found, send the data to the matching players playerstate.

  6. Repeat from step 1 when required.

Sorry for my late reply :slight_smile: I just saw a notification here now.

Hey there Gmi,

I have actually solved this problem a few days ago (i was about to quit my game because of it)

The way i was doing it at first was working properly, and the data was being transferred from map to map, but this was only done on the server (the player state was not being replicated after seamless travel), so what i had to do is everytime i needed to get the player state on the client side, i would validate if the player state is valid (using the IsValid? macro), if it isn’t, then i get the new player state)

The initial problem was that i am saving a reference to the player state in a local variable, so i just needed to reinitialize them on the client side because the player state and game state get deleted after seamless travel, so the reference is broken.

Thank you for your continuous help, really appreciate it :slight_smile:

Hey Sorry to reopen this but KinngOfProgramz, how did you get your client to “check” and request the data from the server is its not valid? I have gotten to the same point as in your original post but cannot work out why my clients do not have the latest version after Server Travel has complete.

Are there any updates on copy properties event? How does it work? Isn’t the intention of this event to have different player states on each level and easily share the variables of the player states on each level?