As for your code not working, assuming you’re trying to test this out in Studio, one common problem is the game server shutting down before the code can finish executing, this can happen in-game as well but it’s more rare as studio shuts down faster, either way, you can address this problem by having the game wait for all data saving to finish before shutting down, here’s a modified version of your code that adresses this issue, I also made some additional modifications with comments to explain why I did that:
local LoadedPlayers = {} -- Store all players that have their data loaded here so you can keep track
local datastore = game:GetService("DataStoreService"):GetDataStore("save")
local function load(player)
local success,returnval = pcall(datastore.GetAsync,datastore,player.UserId)
--The first value pcall is returns is whether or not the code errored, the second is whatever the code returns, if their is no return, this value will be nil, if there was an error during code execution, this will be the error string
if success then
LoadedPlayers[player] = true -- Store the player into the dictionary as their data has successfully loaded
if returnval then --Only set the value if the returnval isn't nil, data for new players who don't have an existing value will always be nil
workspace.Folder.Value.Value = returnval
end
else
player:Kick("Error occured while loading data, please rejoin") -- It's recommended that you remove players if data load fails
print(string.format("Data load failed\nError: %s",returnval))
end
end
local function save(player)
if LoadedPlayers[player] == nil then
return --This will prevent data from saving if the player's data load failed, this may not make much sense at first but if data fails to load when someone joins your game, and you do not have this check, once they leave, their new blank data will overwrite their original data, resulting in data loss
end
--You may have noticed I massively changed the code here, what I've done here is basically have it retry data saving if it fails once, to minimize any risks of data loss, currently I have it set to 1 so it will only try once, you can change this to your liking
local success,returnval = nil
local Max_Tries = 1
local CurrentTries = 0
while success ~= true and CurrentTries <= Max_Tries do
success,returnval = pcall(datastore.SetAsync,datastore,player.UserId,workspace.Folder.Value.Value)
CurrentTries += 1
end
if success then
print("werwer")
else
print(string.format("Data save failed\nError: %s",returnval))
end
end
game.Players.PlayerAdded:Connect(load)
game.Players.PlayerRemoving:Connect(function(player)
save(player)
LoadedPlayers[player] = nil -- Remove the player from the table, this is done outside of the save function as this should only be done when the player is leaving
end)
--Now this is where we finally make the game wait for data saving to finish before shutting off
game:BindToClose(function() --This function will only run once the game begins shutting down, :BindToClose() can stop the game from shutting down until your code has finished executing, however, if it takes longer than 30 seconds, it will shut down anyway, fortunately data saving will hardly take 3 seconds
while next(LoadedPlayers) ~= nil do
task.wait() -- Keep waiting until the LoadedPlayers data is empty, which will only be empty once all data saving operations have completed, the loop will automatically break once this happens and the game can finally shut down
end
end)
Also, as @Doomcolp3, make sure it’s not a LocalScript, data saving cannot work through a LocalScript