I've been trying to make a character customization GUI in which all of the character values save. However, everything works fine until when the player leaves. When they leave, the values don't update, they stay the same as they were previously when I joined the game. When I use a datastore editor plugin, and change them, they load as the values I changed them to, but when I change them in studio or in the game, the values appear to change but they still don't save when I leave.
Here's my datastore code:
local DataStore = game:GetService("DataStoreService"):GetDataStore("CustomizationData") game.Players.PlayerAdded:Connect(function(player) wait(1) --Creating the customization values for the player local Folder = Instance.new("Folder", player) Folder.Name = (player.Name.."Values") local SkinTone = Instance.new("IntValue", Folder) SkinTone.Name = "SkinTone" local HairOne = Instance.new("IntValue", Folder) HairOne.Name = "HairOne" local HairTwo = Instance.new("IntValue", Folder) HairTwo.Name = "HairTwo" local HairColour = Instance.new("IntValue", Folder) HairColour.Name = "HairColour" local Shirt = Instance.new("IntValue", Folder) Shirt.Name = "Shirt" local Pants = Instance.new("IntValue", Folder) Pants.Name = "Pants" local Key = (player.Name.."Data") --Setting the values based on the datastore local Get_Data = DataStore:GetAsync(Key) if Get_Data then SkinTone.Value = Get_Data[1] HairOne.Value = Get_Data[2] HairTwo.Value = Get_Data[3] HairColour.Value = Get_Data[4] Shirt.Value = Get_Data[5] Pants.Value = Get_Data[6] else SkinTone.Value = 1 HairOne.Value = 1 HairTwo.Value = 1 HairColour.Value = 1 Shirt.Value = 1 Pants.Value = 1 end for i, v in pairs(Folder:GetChildren()) do v.Changed:Connect(function() DataStore:SetAsync(Key, {SkinTone.Value, HairOne.Value, HairTwo.Value, HairColour.Value, Shirt.Value, Pants.Value}) print("Data changed, set") print(SkinTone.Value) end) end end) game.Players.PlayerRemoving:Connect(function(player) local Key = (player.Name.."Data") local Folder = player:FindFirstChild(player.Name.."Values") local SkinTone = Folder.SkinTone print (SkinTone.Value) local HairOne = Folder.HairOne local HairTwo = Folder.HairTwo local HairColour = Folder.HairColour local Shirt = Folder.Shirt local Pants = Folder.Pants print(SkinTone.Value) print("Saved") DataStore:SetAsync(Key, {SkinTone.Value, HairOne.Value, HairTwo.Value, HairColour.Value, Shirt.Value, Pants.Value}) end)
I suggest making the function that begins at line 55 a variable for this, your problem is that the saving code doesn't run before the game closes when the last player of a server leaves. To fix this use the built in function BindToClose. BindToClose fully runs a code right before the server closes.
local function SavePlayerStats(player) local Key = (player.Name.."Data") local Folder = player:FindFirstChild(player.Name.."Values") local SkinTone = Folder.SkinTone print (SkinTone.Value) local HairOne = Folder.HairOne local HairTwo = Folder.HairTwo local HairColour = Folder.HairColour local Shirt = Folder.Shirt local Pants = Folder.Pants print(SkinTone.Value) print("Saved") DataStore:SetAsync(Key, {SkinTone.Value, HairOne.Value, HairTwo.Value, HairColour.Value, Shirt.Value, Pants.Value}) end game:BindToClose(function() for i, player in pairs(game.Players:GetPlayers()) do SavePlayerStats(player) end end) -- the BindToClose function will save the player's data before the server closes -- and also ensures that multiple player's data will save if there is a server crash or something (which is what the loop does) game.Players.PlayerRemoving:Connect(function() SavePlayerStats(player) end) -- when a player leaves but the server is not closing, their data will save