My game usually saves and loads players levels properly. However, when I try having two players teleport into my game (from another like using :place all) they both receive the level that belonged to one of them. Here is the code that saves and loads the level:
Make “keyname” in your first picture a local variable, as well as “name” in your second picture. Because they are global, when both players join or leave at the same time, one player’s keyname/name variable is overwritten by the other.
Thanks, hopefully that’ll do the trick. Also, I noticed whenever the game shuts down or a player crashes PlayerLeft doesn’t run. However, I don’t want to repeatedly save the stats over and over ingame, otherwise I start getting warnings for saving too often. Is there a way to avoid this? How long of an interval do you think would help?
Like @Uglypoe said, make them locals. In general practice, it is bad to have a variable that can be quickly overwritten global like that, because it can cause unforseen consequences that you described. While a script’s thread is fast and can execute things very quickly, it is still a risk to overwrite something that wasn’t inteded to be overwritten. Additionally, local variables will be quicker than globals. Also, that brings up the question: what do I do about other parts in the script that require those variables? Well because they are overwritten like that, it is again dangerous and bad practice, especially when dealing with datastores. Making sure you handle your functions properly for the whole script, and handing off that data in the form of arguments, is crucial. Hope that helps!
You won’t get warnings as long as you moderate how often you save. My game auto saves data every 60 seconds, as well as when the player leaves.
You may also want to replace the Players.ChildRemoved with Players.PlayerRemoving. At the very least it should be more reliable because PlayerRemoving is guaranteed to fire before the player has been fully disconnected.
In addition to PlayerRemoving, you might also want to look into game::BindToClose
, to make sure you have enough time to save the players’ data.