Datastore problem, don't know what do to do

Great. Datastore problem

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.

3 Likes

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?

Players.PlayerRemoving:Connect(Set)

passed value is not a function

pass a function to the Connect

Still same error nothing changed.

uhh, where exactly should I??

kinda confused.

Uhh you didn’t pass anything to the player removing, you need to pass a function to it, we just said that.

OH, I confused my self, sorry about that

Not sure if this is relevant, but you shouldn’t be saving the Player’s Children but rather getting their Player’s ID’s by using GetPlayers()

game:BindToClose(function()
	for i, v in next, game.Players:GetPlayers() do
		if v then
			Set(v)
		end
	end
end)
Players.PlayerRemoving:Connect(Set)

Still error

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.

What line is the error on, can you provide a screenshot

error gone, But no data is saved

Error gone, But no data is saved, uh @Jackscarlett @elonrocket ???

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

Using roblox it’s self so not to do with studio API

So would this work?

game:BindToClose(function()
	for i, v in next, game:GetPlayers() do
		if v then
			Set(v)
		end
	end
end)

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

game.Players:GetPlayers
3 Likes

Thanks a lot, give me a min, I’ll try and implement this.

Should I keep tries as it is? or will that have to be table as well?

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

local debounce = false