I’m simply having an issue that I’ve looked around for but couldn’t find a solution for. Every time it tries to run it returns with “Unable to cast value to function.”
local DSS = game:GetService("DataStoreService")
local statStore = DSS:GetDataStore("statStore")
game.Players.PlayerAdded:Connect(function(plr)
local plrId = plr.UserId
local data = statStore:GetAsync(plrId)
local leaderstats = Instance.new("Folder", plr)
leaderstats.Name = "leaderstats"
local wins = Instance.new("IntValue", leaderstats)
wins.Name = "Victories"
if data then
wins.Value = data["Victories"]
else
wins.Value = 0
end
end)
local function create_table(plr)
local player_stats = {}
for _, stat in ipairs(plr.leaderstats:GetChildren()) do
player_stats[stat.Name] = stat.Value
end
return player_stats
end
local function onPlayerExit(plr)
local player_stats = create_table(plr)
local plrId = plr.UserId
local success, errorMessage = pcall(function()
statStore:UpdateAsync(plrId, player_stats)
print("Player had data, using :UpdateAsync()")
end)
if not success then
task.wait(2)
onPlayerExit(plr)
print("Player had an error whilst saving data. Retrying...")
end
end
game.Players.PlayerRemoving:Connect(onPlayerExit)
while true do
for i, v in pairs(game.Players:GetChildren()) do
onPlayerExit(v)
end
task.wait(74)
end
game:BindToClose(function()
for i, v in pairs(game.Players:GetPlayers()) do
onPlayerExit(v)
end
end)
The UpdateAsync requires a key and a function in its arguments like this
local function ExampleFunction(oldValue)
return oldValue + 100
end
exampleDataStore:UpdateAsync("ExampleKey", ExampleFunction)
In your case, I do not recommend to use UpdateAsync since the method is used for comparing the old value of the DataStore. I recommend SetAsync instead, but if you’d like to use UpdateAsync anyway:
local DSS = game:GetService("DataStoreService")
local statStore = DSS:GetDataStore("statStore")
game.Players.PlayerAdded:Connect(function(plr)
local plrId = plr.UserId
local data = statStore:GetAsync(plrId)
local leaderstats = Instance.new("Folder", plr)
leaderstats.Name = "leaderstats"
local wins = Instance.new("IntValue", leaderstats)
wins.Name = "Victories"
if data then
wins.Value = data["Victories"]
else
wins.Value = 0
end
end)
local function create_table(plr)
local player_stats = {}
for _, stat in ipairs(plr.leaderstats:GetChildren()) do
player_stats[stat.Name] = stat.Value
end
return player_stats
end
local function onPlayerExit(plr)
local player_stats = create_table(plr)
local plrId = plr.UserId
local success, errorMessage = pcall(function()
statStore:UpdateAsync(plrId, function(oldValue)
return player_stats
end)
print("Player had data, using :UpdateAsync()")
end)
if not success then
task.wait(2)
onPlayerExit(plr)
print("Player had an error whilst saving data. Retrying...")
end
end
game.Players.PlayerRemoving:Connect(onPlayerExit)
while true do
for i, v in pairs(game.Players:GetChildren()) do
onPlayerExit(v)
end
task.wait(74)
end
game:BindToClose(function()
for i, v in pairs(game.Players:GetPlayers()) do
onPlayerExit(v)
end
end)
No, it doesn’t need to have data. UpdateAsync works like SetAsync, but takes the oldValue in consideration. If the oldValue is not important, then you should definitely use SetAsync. For example, if you have a key in your datastore that’s a rank, there’s no need to consider the old value. However, if you have a key that’s the highscore or something, you might wanna consider the old value.