Hi, I am a new scripter and I was following a YT secure data saving tutorial, I got an error and I can’t find what it is causing it.
Script:
local Players = game:GetService("Players")
local DataStoreService = game:GetService("DataStoreService")
local DataStore = DataStoreService:GetDataStore("Save123")
local tries = 3
local dataloaded = false
-- Handles Player Data Saving
local function Set(plr)
if dataloaded then
-- Datastore Variables
local key = "plr-"..plr.UserId
local count = 0
local data = {
["Cash"] = plr.leaderstats.Cash.Value,
["XP"] = plr.leaderstats.XP.Value
}
local success, err
repeat
success, err = pcall(function()
DataStore:SetAsync(key, data)
end)
count = count + 1
until count >= tries or success
if not success then
warn("Failed to set data. Error code: "..tostring(err))
end
else
return
end
end
-- Handles Player Data loading
local function Get(plr)
local key = "plr-"..plr.UserId
local count = 0
local data
local success, err
repeat
success, err = pcall(function()
data = DataStore:GetAsync(key)
end)
count = count + 1
until count >= tries or success
if not success then
warn("Failed to read data. Error code: "..tostring(err))
--plr:Kick ("uh, that's not good")
return
end
if success then
if data then
dataloaded = true
return data
else
return {
["Cash"] = 0,
["XP"] = 1
}
end
end
end
-- Handles Leaderboard
local function createleaderstats(plr)
local values = Get(plr)
-- Leaderboard
local leaderstats = Instance.new("Folder")
leaderstats.Name = "leaderstats"
leaderstats.Parent = plr
local cash = Instance.new("IntValue")
cash.Name = "Cash"
cash.Parent = leaderstats
local xp = Instance.new("IntValue")
xp.Name = "XP"
xp.Parent = leaderstats
-- values
cash.Value = values.Cash
xp.Value = values.XP
end
-- Calls Functions Above
Players.PlayerRemoving:Connect()
Players.PlayerAdded:Connect(createleaderstats)
game:BindToClose(function()
for i, v in next, game.Players:GetChildren() do
if v then
Set(v)
end
end
end)
Output:
Attempt to connect failed: Passed value is not a function
Another thing to add, I don’t have much experience with Data stores.
I believe you made this parameter empty when attempting to connect your PlayerRemoving Event, try to replace that with this so that you’ll be able to connect it?
whenever you connect an event you need to pass a function to run, in this case I’m pretty sure you want to run the Set function
game.Players.PlayerRemoving:Connect(Set)
All get players does different is get the Player Objects that are parented to game.Players instead of all the children. If he doesn’t put any other objects in game.Players he’ll be fine.
Should probably implement a couple of print() statements then to debug when the Data gets Saved, or check that API Services are still enabled or something
Okay I found a vital mistake which you won’t notice until multiple people start playing, these same variables will be set for any player that joins the game.
Example if player1 joins the game and sets “dataloaded” to true, then when player2 joins the game “dataloaded” will also be set to true.
This will have for any kind of debounce variable you make on the server for multiple players, the way you get around it is by making a table and using the player Instance as the key
local dataloaded = {}
-- then when player data loads
dataloaded[player] = true
no GetPlayers is not a function of DataModel
you would have to do
it would have to be a table, anything that you want to have different values for different players (any kind of debounce) you will need to use a table.
On the client you wouldn’t need to use tables most of the time because you are just working with LocalPlayer so you can have something like