Hello, I recently followed @GEILER123456’s tutorial on how to make a Datastore, but the data is not saving. The output says "There was an error with saving a player’s data Unable to cast to array.
This is the script:
local dataStoreService = game:GetService("DataStoreService")
local players = game:GetService("Players")
local dataStore = dataStoreService:GetDataStore("Name")
local function leaderboardSetUp(player)
local userId = player.UserId
local key = "Player_" .. userId
local data = dataStore:GetAsync(key)
local leaderstats = Instance.new("Folder")
leaderstats.Name = "leaderstats"
leaderstats.Parent = player
local wins = Instance.new("IntValue")
wins.Name = "Wins"
wins.Value = data or 0
wins.Parent = leaderstats
local money = Instance.new("IntValue")
money.Name = "Money"
money.Value = data or 0
money.Parent = leaderstats
print("Leaderstats loaded.")
end
local function save(player)
local userId = player.UserId
local key = "Player_" .. userId
local leaderstats = player:FindFirstChild("leaderstats")
if leaderstats then
local winsValue = leaderstats.Wins.Value
local moneyValue = leaderstats.Money.Value
local success, ret = pcall(dataStore.GetAsync, dataStore, key, winsValue, moneyValue)
if success then
print("Data has been saved successfully!")
else
print("There was an error with saving a player's data" .. ret)
end
end
end
local function onShutDown()
wait(1)
end
game:BindToClose(onShutDown)
players.PlayerAdded:Connect(leaderboardSetUp)
players.PlayerRemoving:Connect(save)
while true do
wait(60)
for _,player in ipairs(players:GetPlayers()) do
coroutine.wrap(save)(player)
end
end
Is there any problem with the script? What am I doing wrong? Thank you.
You can use SetAsync when its the first time the player enters the game, when it already has player data, he have to use Update Async 'cause SetAsync is dangerous
local dataStore = game:GetService("DataStoreService"):GetDataStore("Name")
local players = game:GetService("Players")
players.PlayerAdded:Connect(function(player)
local Success,data = pcall(function()
return dataStore:GetAsync("Player_" .. player.UserId)
end)
if not Success then print(data) end
local leaderstats = Instance.new("Folder")
leaderstats.Name = "leaderstats"
leaderstats.Parent = player
local wins = Instance.new("IntValue")
wins.Name = "Wins"
wins.Value = 0
if data then wins.Value = data["Wins"] end
wins.Parent = leaderstats
local money = Instance.new("IntValue")
money.Name = "Money"
money.Value = 0
if data then wins.Value = data["Money"] end
money.Parent = leaderstats
print("Leaderstats loaded.")
end)
function save(player)
local key = "Player_" .. player.UserId
local leaderstats = player:FindFirstChild("leaderstats")
if leaderstats then
local Success, Err = pcall(function()
dataStore:SetAsync(key, {
["Money"] = leaderstats.Money.Value,
["Wins"] = leaderstats.Wins.Value
})
end)
if Success then
print("Data has been saved successfully!")
else
print("There was an error with saving a player's data" .. Err)
end
end
end
players.PlayerRemoving:Connect(save)
game:BindToClose(function()
for _,player in pairs(game:GetService("Players"):GetPlayers()) do
coroutine.wrap(save)(player)
end
wait(2)
end)
for i = 1, 10 do
local success, ret = pcall(dataStore.GetAsync, dataStore, key, winsValue, moneyValue)
if success then
print("Data has been saved successfully!")
break
else
print("There was an error with saving a player's data" .. ret)
end
end
UpdateAsync is the best one to use as if other servers access it then it will not become messy. Is it possible the values are being removed before the player leaves. Also, you should ALSO have PlayerRemoving as BindToClose only fires when a server is shutting down not a player leaving.