Trouble with leaderstats saving

Well then, put an ) after the end I assume that something wasn’t closed off.

1 Like

I have, I am getting this output:
09:59:02.927 - ServerScriptService.myDataStore:30: Expected ')' (to close '(' at line 28), got 'end'. Yet It’s been closed off?

One moment as I put the code into studio and fix the indenting for you and then see what’s wrong.

Little off-topic here, but I’m having some trouble with another script. I have a tool, when you equip it, and you click it’ll add points to the leaderboard. But it’s not working as it should. Here’s that script:
script.Parent.Activated:Connect(function()

    local plr = game.Players:GetPlayerFromCharacter(script.Parent.Parent)

    plr.leaderstats.Coins.Value = plr.leaderstats.Coins.Value +3
end)

I have formatted the code and fixed all possible errors.

local dataStoreService = game:GetService("DataStoreService")
local myDataStore = dataStoreService:GetDataStore("myDataStore")
local players = game:GetService("Players")
local plrsLeft = 0

players.PlayerAdded:Connect(function(player)
	plrsLeft = plrsLeft + 1
	local leaderstats = Instance.new("Folder")
	leaderstats.Name = "leaderstats"
	leaderstats.Parent = player
	
	local cash = Instance.new("IntValue")
	cash.Name = "Coins"
	cash.Parent = leaderstats
	
	local success1,response1 = pcall(myDataStore.GetAsync,myDataStore,player.UserId)
	if success1 then
		cash.Value = response1
	else
		warn(response1)
	end
	
	while true do
		wait(30)
		local success2,response2 = pcall(myDataStore.UpdateAsync,myDataStore,player.UserId,function(oldValue)
			return cash.Value
		end)
		if not success2 then
			warn(response2)
		end
	end
end)

local BindEvent = Instance.new("BindableEvent")
players.PlayerRemoving:Connect(function(player)
	plrsLeft = plrsLeft - 1
	
	local success,response = pcall(myDataStore.UpdateAsync,myDataStore,player.UserId,function(oldValue)
		return player.leaderstats.Coins.Value
	end)
	if success then
		BindEvent:Fire()
	else
		warn(response)
	end
end)

game:BindToClose(function()
	while plrsLeft > 0 do
		BindEvent.Event:Wait()
	end
end)

You’re welcome! Also, there may be bits and pieces missing that I did not include but you can always modify the code.

It works perfectly for me, is your script a child of the tool? Is this a server script? Have you tried putting a print right after the event is fired? Also, I would recommend putting in a debounce to prevent someone just autoclicking to get a million coins instantly.

1 Like

Also, In the code:

local dataStoreService = game:GetService("DataStoreService")
local myDataStore = dataStoreService:GetDataStore("myDataStore")
local players = game:GetService("Players")
local plrsLeft = 0

players.PlayerAdded:Connect(function(player)
	plrsLeft = plrsLeft + 1
	local leaderstats = Instance.new("Folder")
	leaderstats.Name = "leaderstats"
	leaderstats.Parent = player
	
	local cash = Instance.new("IntValue")
	cash.Name = "Coins"
	cash.Parent = leaderstats
	
	local success1,response1 = pcall(myDataStore.GetAsync,myDataStore,player.UserId)
	if success1 then
		cash.Value = response1
	else
		warn(response1)
	end
	
	while true do
		wait(30)
		local success2,response2 = pcall(myDataStore.UpdateAsync,myDataStore,player.UserId,function(oldValue)
			return cash.Value
		end)
		if not success2 then
			warn(response2)
		end
	end
end)

local BindEvent = Instance.new("BindableEvent")
players.PlayerRemoving:Connect(function(player)
	plrsLeft = plrsLeft - 1
	
	local success,response = pcall(myDataStore.UpdateAsync,myDataStore,player.UserId,function(oldValue)
		return player.leaderstats.Coins.Value
	end)
	if success then
		BindEvent:Fire()
	else
		warn(response)
	end
end)

game:BindToClose(function()
	while plrsLeft > 0 do
		BindEvent.Event:Wait()
	end
end) - Where does the leaderstats end and begin? I have a leaderstats script, and I believe by making one in this script It's messing with the tool script.

The script you posted above (post 24) should work with that script if everything is spelled correctly.

Hm, referring back to my original script… Everything works fine, if I alter the script, everything doesn’t work as needed.

Weird, make sure the paths are correct.

Adding onto my previous post, everything works with my original script, except for the data store script.

Use DataStore2 Instead Problems?

Use This Tutorial

Note: If you try my code it would basically work


local DataStore2 = require(game.ServerStorage:WaitForChild(“DataStore2”))

local ReplicatedStorage = game:GetService("ReplicatedStorage") -- incase for events

function playerAdded(player)
local blades = DataStore2(“blades”, player)


local Fold = Instance.new("Folder")
Fold.Name = "leaderstats"
Fold.Parent = player

local Blades = Instance.new("IntValue")
Blades.Name = "Blades"
Blades.Value = blades:Get(0)  -- there's no need for a function, you can hook to a getpropertychangedsignal on the client
-- the only reason why the docs have a function it to get changes
Blades.Parent = Fold

blades:OnUpdate(function(value) -- hook to onupdate, because when you update with datastore2 you use functional methods, you don't update value objects
	-- you would use methods like :Increment(-value) when purchasing items (you lose money when you buy stuff)
	Blades.Value = value
end)


end

for _, player in pairs(game.Players:GetPlayers()) do
playerAdded(player)
end

game.Players.PlayerAdded:Connect(playerAdded)

-- lastly adding values
while true do
            wait(1)
            for i, plr in pairs(game.Players:GetPlayers()) do
                     local blades = DataStore2("blades", plr) -- doing some checking
                     blades:Increment(1)
        end
end

This was my test sample of DataStore2 ill give you some tracks

I had a problem quite similar to yours, you can read my post, maybe that can help you.

Is your tool script a LocalScript?

No, It’s just a script.
(3030)

local dataStoreService = game:GetService("DataStoreService")
local myDataStore = dataStoreService:GetDataStore("myDataStore")
local players = game:GetService("Players")

player.PlayerAdded:Connect(function(player)
  local leaderstats = Instance.new("Folder")
  leaderstats.Name = "leaderstats"
  leaderstats.Parent = player

  local cash = Instance.new("IntValue")
  cash.Name = "Coins"
  cash.Parent = leaderstats

  local success, data = pcall(function()
         myDataStore:GetAsync(player.UserId, cash.Value)

end)

  if success then
    cash.Value = data[1]
  else
    print("There was an error whilst getting your data.")
    warn(data)
  end
end)

players.PlayerRemoving:Connect(function(player)
  local success, errormessage = pcall(function()

      myDataStore:UpdateAsync(player.UserId, player.leaderstats.Coins.Value)
end
      if success then
       print("Player data successfully saved!")
  else
    print("There was an error saviing data.")
    warn(errormessage)
  end
end)

try this

just use DataStore2 i used it everything went fine now for me

Hey It would be wonderful if you could stop suggesting the use of DataStore2 as a “problem fix”, DataStore2 is nowhere near being called “Good” as a “DataStore” it’s just doing more requests for no reason at all ( well for the reason that the person using it cannot handle data properly so it saves it twice ) :smiley:

Instead of suggesting something as an “alternative” that clearly isn’t helpful at all you could try helping OP more! I am very glad we both agree ( It’s not just you, it’s to everyone who keeps suggesting the use of DataStore2 for the stupdest reasons ) unpopular opinion though haha!

and to fix OP’s code even though it’s not broken I quickly uh edited some stuff in and out :

local dataStoreService = game:GetService("DataStoreService")
local myDataStore = dataStoreService:GetDataStore("myDataStore")
local players = game:GetService("Players")

players.PlayerAdded:Connect(function(player)
    local leaderstats = Instance.new("Folder")
    leaderstats.Name = "leaderstats"
    leaderstats.Parent = player

    local cash = Instance.new("IntValue")
    cash.Name = "Coins"
    cash.Parent = leaderstats

    local success, data = pcall(myDataStore.GetAsync, myDataStore, player.UserId)

    if success then
        cash.Value = data
    else
        print("There was an error whilst getting your data.")
        warn(data)
    end
end)

function playerRemoving(player)
        local success, errormessage = pcall(myDataStore.SetAsync, myDataStore, player.UserId, player.leaderstats.Coins.Value)

    if success then
        print("Player data successfully saved!")
    else
        print("There was an error saviing data.")
        warn(errormessage)
    end
end


players.PlayerRemoving:Connect(playerRemoving)

game:BindToClose(function()
    for _,v in ipairs(players:GetPlayers()) do
        coroutine.wrap(playerRemoving)(v)
    end
	wait(30)
end)

And just a message for OP : I am not the best you could probably find some bad habits in the code I just posted, you should really look again the DataStore’s article in roblox’s developer guide.
I think the issue with your code is that the server was closing before saving data? Which is kind of weird so I added a BindToClose.

If the code above I posted doesn’t work it means you’re doing something wrong on your end like :

  1. Not changing the value from the server but from the client.
  2. You’re testing on studio and didn’t enable Studio Access to API Services.

normal datastores wont work for me so i used this instead
In circumstances i never received data loss using it

In normal DataStores when used properly you won’t suffer any “Data loss” either :smiley:
personally I’ve been using the rocket science DataStores for a lot of time and I’ve never had any issues with the thing you said either… You should consider reading roblox’s guide on DataStores and other people’s!