Help with Leaderstats

As the title states, I am having trouble with leaderstats, but allow me to go into detail the problem I am facing.

What I am trying to achieve is a script that will increase an amount of points over time (For example, a player gains 1 point every second). I have managed to create a leaderstat system with a datastore (the datastore is necessary in this project), but am struggling with the increase of points over time.

Here is what I have so far:

Leaderstat and Datastore script (ServerScriptService)

local DataStoreService = game:GetService("DataStoreService")
local PointsStore = DataStoreService:GetDataStore("PointsStore")

game.Players.PlayerAdded:Connect(function(Player)
	
	local SavedPoints = PointsStore:GetAsync(Player.UserId)
	
	local Leaderstats = Instance.new("Folder", Player)
	Leaderstats.Name = "leaderstats"
	
	local PointsValue = Instance.new("IntValue", Leaderstats)
	PointsValue.Name = "Points"
	
	if SavedPoints ~= nil then
		PointsValue.Value = SavedPoints
	end
	
	PointsValue.Changed:Connect(function(NewPoints)
		PointsStore:SetAsync(Player.UserId, NewPoints)
			
	end)
end)

Point Increase Script (Server Script Service) - This script doesn’t seem to be working.

game.Players.PlayerAdded:Connect(function(player)

while true do

	player.leaderstats.Points.Value = player.leaderstats.Points.Value + 1

	wait(1)

	end
	
end)

The first script is working fine - it loads the leaderstats, and the datastore is working. The second script however isn’t working, and is not adding the points. I assume the solution is simple, however after searching around, there has been no success in finding a solution.

Any help is appreciated.

Try this code for the increase script

amount = 1
timedelay = 1
currencyName = "Points"

while true do
   wait(timedelay)
   for i,v in pairs(game.Players:GetPlayers) do
     if v:FindFirstChild("leaderstats") then
           v.leaderstats[currencyName].Value = v.leaderstats[currencyName].Value + 1
     end
  end 
end 

Hope this helps :slight_smile:

1 Like

has to be :GetPlayers()

v.leaderstats[currencyName].Value += 1 is much shorter

This is because the first script gets yielded when it accesses the datastore, so leaderstats isn’t made in time. The fix for this will be

game.Players.PlayerAdded:Connect(function(player)
    local leaderstats = player:WaitForChild("leaderstats") -- wait for leaderstats and store it in a variable
    while true do
        leaderstats.Points.Value += 1 -- compound operator, just increases value by 1
        wait(1)
    end
end)

second script btw

You could spawn a thread which handles the point increasing system whenever a new player joins.

My bad was typing in my iPad so it’s hard.

This one worked for me, thank you!

local currency = "Points" -- your currency name that will increase
local delay = 1 -- delay in second for each time will increase 
local amount = 1 -- The amount to be added each time


while true do
	for i, player in pairs(game.Players:GetPlayers()) do
		local leaderstats = player:FindFirstChild("leaderstats")
		
		if leaderstats then
			if leaderstats:FindFirstChild(currency) then
				leaderstats[currency].Value += amount
			end
		end
	end
	wait(delay)
end
PointsValue.Changed:Connect(function(NewPoints)
	PointsStore:SetAsync(Player.UserId, NewPoints)	
end)

This is not good for 2 reasons, you should use UpdateAsync() and far more importantly, you shouldn’t be updating the datastore every second.

os.time() gives the world time in seconds
I would do something like this.

local prevTime = os.time()

function updatePoints()
  local now = os.time()
  for p, player in pairs(Players:GetPlayers()) do
    player.leaderstats.Points.Value += now-prevTime
  end
  prevTime = now
end

When you want that to run is up to you. At the very least you need it to happen as people join and leave to keep the start time relevant to all current players.