Help with datastore script please

  1. What do you want to achieve?
    I want my datastore script to work.

  2. What is the issue?
    Here is a screen of my current data script.
    My datascript won’t work. My leaderstats are in a different script but it works really good but if you need it you can see the last script in my message.
    image

  3. What solutions have you tried so far?
    I was watching, and listening aswell the output all the time. When I end up fixing all the other error messages I still get this one…
    image
    (Don’t even think that it is the fault of any of my both scripts the datastore and the leaderstats…)

I would be so glad if anyone would try to help. :slight_smile:
Here’s the script if you want to take it to fix anything.
I appreciate any replies that is sent here. I don’t take care about when it is posted so feel free to help as many time as you want to.

Datastore

--Datastore
local DS = game:GetService("DataStoreService"):GetDataStore("SaveData")
game.Players.PlayerAdded:Connect(function(plr)
	wait()
	local plrkey = "id_"..plr.userId
	local savevalue1 = plr.leaderstats.Points.Value

	local GetSaved = DS:GetAsync(plrkey)
	if GetSaved then
		savevalue1 = GetSaved[1]
	else
		local NumbersForSaving = {savevalue1.Value}
		DS:GetAsync(plrkey, NumbersForSaving)
	end
end)

game.Players.PlayerRemoving:Connect(function(plr)
	DS:SetAsync("id_"..plr.userId, {plr.leaderstats.Points.Value})
end)

leaderstats

--leaderstats
game:GetService('Players').PlayerAdded:Connect(function(plr)
	local leaderstats = Instance.new("Folder")
	leaderstats.Name = "leaderstats"
	leaderstats.Parent = plr

	local Cash = Instance.new("NumberValue") 
	Cash.Name = "Points"
	Cash.Parent = leaderstats
end)
1 Like

Remove the .Value from this line, you need to directly set the Value, this will just save a variable with the value of the value, but wont change it.

add .Value after savevalue1 here

You probably meant to do SetAsync here.

Lastly, you should simply move the Creation of the leaderstats here.

--Datastore
local DS = game:GetService("DataStoreService"):GetDataStore("SaveData")
game.Players.PlayerAdded:Connect(function(plr)
	local leaderstats = Instance.new("Folder")
	leaderstats.Name = "leaderstats"
	leaderstats.Parent = plr

	local Cash = Instance.new("NumberValue") 
	Cash.Name = "Points"
	Cash.Parent = leaderstats
	
	local plrkey = "id_"..plr.userId

	local GetSaved = DS:GetAsync(plrkey)
	if GetSaved then
		Cash.Value = GetSaved[1]
	else
		local NumbersForSaving = {Cash.Value}
		DS:SetAsync(plrkey, NumbersForSaving)
	end
end)

game.Players.PlayerRemoving:Connect(function(plr)
	DS:SetAsync("id_"..plr.userId, {plr.leaderstats.Points.Value})
end)

Also, the first few points I made will mostly take effect only if the scripts are separate.

1 Like

Thank you so much. I will test right now and won’t forget to put this as the solution if it works !

I put the script in ServerScriptService but it won’t work…Thank you for helping anyways. If you may help again it will really be appreciated.

Mind telling me the error that occurred, or if there was an error at all? If I had to assume, it would be because u in userId is uncapitalized.

--Datastore
local DS = game:GetService("DataStoreService"):GetDataStore("SaveData")
game.Players.PlayerAdded:Connect(function(plr)
	local leaderstats = Instance.new("Folder")
	leaderstats.Name = "leaderstats"
	leaderstats.Parent = plr

	local Cash = Instance.new("NumberValue") 
	Cash.Name = "Points"
	Cash.Parent = leaderstats
	
	local plrkey = "id_"..plr.UserId

	local GetSaved = DS:GetAsync(plrkey)
	if GetSaved then
		Cash.Value = GetSaved[1]
	end
end)

game.Players.PlayerRemoving:Connect(function(plr)
	DS:SetAsync("id_"..plr.UserId, {plr.leaderstats.Points.Value})
end)

game:BindToClose(function()
	for i, plr in pairs(game.Players:GetPlayers()) do
		DS:SetAsync("id_"..plr.UserId, {plr.leaderstats.Points.Value})
	end
end)

Also, I removed the saving from the PlayerAdded as it was unneeded.
Another reason it not saving but not throwing an error could be because you are testing in Studio, which doesn’t run player removing when pressing stop, so I added a game:BindToClose().

Thank you. I will test it by the website. Now it makes me remember that player removing does not work on studio. Thank you.

Still not working throught the web site.

That’s quite weird. Are there any errors that occur? You can test through Studio since I added the BindToClose. Also, how are you gaining points? Make sure that you are receiving the points through the server and not the client, otherwise it won’t save.

First of all : Oops… I added the wrong script.
Second, yes I am getting points. And what do you mean “through the server and not the client ?” I have the script in a classic script anyways.

It is not working sadly…
I think I should help myself too in API Service. I’m gonna read a bit.

He means what is your method of changing your Points value. Like do you have a separate script giving you points, or are you just straight up going into the leaderstats folder to do so

I took his script. So it should work I dont have any separated scripts.

How are you changing your points then? You have to change them some way or else it will save and load as 0

Oh ! Hmm Im gonna give you the script below :slight_smile:

local Background = script.Parent;
local Block = Background.Block;
local Cube = Background.Cube;
local Score = Background.Score;

if game.Players.LocalPlayer:WaitForChild('leaderstats'):WaitForChild('Points') then
	local points = game.Players.LocalPlayer:WaitForChild('leaderstats'):WaitForChild('Points')

function OnMouseEnter()
	Cube.BackgroundColor3 = Color3.new(0, 1, 0);
	local number = math.random(1, 2);
	if number == 2 then
		Background["Undertale Sound Effect - Finishing Puzzle"]:Play()
		task.wait(1);
		Background["Ball Chime - Undertale"]:Play();
		Cube.BackgroundColor3 = Color3.new(1, 1, 1);
		points.Value = points.Value +1
	else
		Background["Undertale explode sound effect"]:Play();
	end
end

function OnMouseLeave()
	Cube.BackgroundColor3 = Color3.new(1, 0, 0)	;
	Background["Undertale - Swipe Sound Effect"]:Play();
end

Block.MouseEnter:Connect(OnMouseEnter);
Block.MouseLeave:Connect(OnMouseLeave);
points.Changed:Connect(function()
	Score.Text = points.Value.."/250"
	end)
end

This script is in a local script since I’m doig my game with guis only.
That is how we get points. And its random.

Ah thats why nothing’s saving, because the server doesn’t see any change to the value. You can only make changes to leaderstats values through the server if you want them to save. So what you will have to do is use a RemoteEvent and where you currently increase your point values, instead make that the place where you fire the server

1 Like

Okay I’m gonna try to use events gimme a sec and ty.

Now its not working…

Here is the script rn

local Background = script.Parent;
local Block = Background.Block;
local Cube = Background.Cube;
local Score = Background.Score;
local RS = game:GetService('ReplicatedStorage');
local Events = RS:FindFirstChild('Events');
local OnMouseEnter = Events:WaitForChild('OnMouseEnter');
local OnMouseLeave = Events:WaitForChild("OnMouseLeave");
local OnRandom = Events:WaitForChild("OnRandomGiven");
if game.Players.LocalPlayer:WaitForChild('leaderstats'):WaitForChild('Points') then
	local points = game.Players.LocalPlayer:WaitForChild('leaderstats'):WaitForChild('Points')
	
	OnRandom.OnClientEvent:Connect(function(Player)
		Background["Undertale Sound Effect - Finishing Puzzle"]:Play();
		task.wait(1);
		Background["Ball Chime - Undertale"]:Play();
		Cube.BackgroundColor3 = Color3.new(1, 1, 1);
		points.Value = points.Value +1
end)
	
	OnMouseEnter.OnClientEvent:Connect(function(Player)
	Cube.BackgroundColor3 = Color3.new(0, 1, 0);
	local number = math.random(1, 2);
	if number == 2 then
		OnRandom:FireServer()
	else
		Background["Undertale explode sound effect"]:Play();
	end
end)
OnMouseLeave.OnClientEvent:Connect(function(Player)
	Cube.BackgroundColor3 = Color3.new(1, 0, 0)	;
	Background["Undertale - Swipe Sound Effect"]:Play();
	end)
	
Block.MouseEnter:Connect(function()
	OnMouseEnter:FireServer()
end)
	
Block.MouseLeave:Connect(function()
	OnMouseLeave:FireServer()	
end)
	
points.Changed:Connect(function()
	Score.Text = points.Value.."/250"
	end)
end

Oh I think you misunderstood what I meant. Let me use the original script you posted.

local Background = script.Parent;
local Block = Background.Block;
local Cube = Background.Cube;
local Score = Background.Score;
local Event = game.RS.CashEvent --create a remoteevent, name it CashEvent and put it in replicatedStorage

if game.Players.LocalPlayer:WaitForChild('leaderstats'):WaitForChild('Points') then
	local points = game.Players.LocalPlayer:WaitForChild('leaderstats'):WaitForChild('Points')

function OnMouseEnter()
	Cube.BackgroundColor3 = Color3.new(0, 1, 0);
	local number = math.random(1, 2);
	if number == 2 then
		Background["Undertale Sound Effect - Finishing Puzzle"]:Play()
		task.wait(1);
		Background["Ball Chime - Undertale"]:Play();
		Cube.BackgroundColor3 = Color3.new(1, 1, 1);
		Event:FireServer() --I changed this here
	else
		Background["Undertale explode sound effect"]:Play();
	end
end

function OnMouseLeave()
	Cube.BackgroundColor3 = Color3.new(1, 0, 0)	;
	Background["Undertale - Swipe Sound Effect"]:Play();
end

Block.MouseEnter:Connect(OnMouseEnter);
Block.MouseLeave:Connect(OnMouseLeave);
points.Changed:Connect(function()
	Score.Text = points.Value.."/250"
	end)
end

And then create a server script and place it in serverscriptservice and put this inside

game.ReplicatedStorage.CashEvent.OnServerEvent:Connect(function(player)
    player.leaderstats.Points.Value = player.leaderstats.Points.Value + 1
end)

here I rewrote it cause I was bored maybe you can learn a thing or two from this

local players = game:GetService("Players")
local repstore = game:GetService("ReplicatedStorage")

local localplayer = players.LocalPlayer
local background = script.Parent

local block = background:WaitForChild("Block") :: GuiObject
local cube = background:WaitForChild("Cube") :: GuiObject
local score = background:WaitForChild("Score") :: GuiObject

local events = repstore:WaitForChild("Events") :: Folder

local onmouseenter = events:WaitForChild("OnMouseEnter") :: RemoteEvent
local onmouseleave = events:WaitForChild("OnMouseLeave") :: RemoteEvent
local onrandomgiven = events:WaitForChild("OnRandomGiven") :: RemoteEvent

local leaderstats = localplayer:WaitForChild("leaderstats")
local points = leaderstats:WaitForChild("Points")

if typeof(points) == 'Instance' and points:IsA("IntValue") then
	local finishingpuzzle = background:WaitForChild("Undertale Sound Effect - Finishing Puzzle") :: Sound
	local bellchime = background:WaitForChild("Bell Chime - Undertale") :: Sound
	local explode = background:WaitForChild("Undertale explode sound effect") :: Sound
	local swipe = background:WaitForChild("Undertale - Swipe Sound Effect") :: Sound
 	onrandomgiven.OnClientEvent:Connect(function(player: Player)
		finishingpuzzle:Play()
		task.wait(1)
		cube.BackgroundColor3 = Color3.fromHSV(0, 0, 1)
		points.Value += 1 -- setting points on the client (not sure if intentional) might be why it doesn't work?
		bellchime:Play() -- sound queue is better to play when the changes are made
	end)
	onmouseenter.OnClientEvent:Connect(function(player: Player)
		cube.BackgroundColor3 = Color3.fromRGB(0, 255, 0)
		if math.random(1, 2) == 1 then
			return onrandomgiven:FireServer()
		end
		return explode:Play()
	end)
	onmouseleave.OnClientEvent:Connect(function(player: Player)
		cube.BackgroundColor3 = Color3.fromRGB(255, 0, 0)
		return swipe:Play()
	end)
	block.MouseEnter:Connect(function()
		onmouseenter:FireServer()
	end)
	block.OnMouseLeave:Connect(function()
		onmouseleave:FireServer()
	end)
	points.Changed:Connect(function()
		score.Text = ('%s/250'):format(tostring(points.Value))
	end)
end

I learnt how to use return! Thank you so much.