DataStore Problem

I need help with my players stats
When player rejoin they don’t earn +1 for joins (stuck in the same number) and minutes seem to work fine (I think) idk how to fix without a data reset

Script:

local DataStoreService = game:GetService("DataStoreService")
local TimeStatsStore = DataStoreService:GetDataStore("TimeStats")
local JoinStatsStore = DataStoreService:GetDataStore("JoinStats")

local function createLeaderstats(player)
	local leaderstats = Instance.new("Folder")
	leaderstats.Name = "leaderstats"
	leaderstats.Parent = player
	local Joins = Instance.new("IntValue")
	Joins.Name = "Joins"
	Joins.Value = 1
	Joins.Parent = leaderstats

	local Minutes = Instance.new("IntValue")
	Minutes.Name = "Minutes"
	Minutes.Value = 0
	Minutes.Parent = leaderstats
	return leaderstats
end

local function updateMinutes(player)
	while true do
		wait(60)
		player.leaderstats.Minutes.Value = player.leaderstats.Minutes.Value + 1
	end
end

game.Players.PlayerAdded:Connect(function(player)
	local leaderstats = createLeaderstats(player)
	local success, data = pcall(TimeStatsStore.GetAsync, TimeStatsStore, player.UserId)
	if success then
		leaderstats.Minutes.Value = data or 0
	end
	coroutine.wrap(updateMinutes)(player)
	local plrKey = "id_" .. player.UserId
	local save2 = player.leaderstats.Joins
	local success2, savedData = pcall(JoinStatsStore.GetAsync, JoinStatsStore, plrKey)
	if success2 then
		if savedData then
			if type(savedData) == "table" then
				save2.Value = savedData[1] + 1
			else
				save2.Value = savedData + 1 
			end
		else
			save2.Value = 1
		end
	end
end)

game.Players.PlayerRemoving:Connect(function(player)
	TimeStatsStore:SetAsync(player.UserId, player.leaderstats.Minutes.Value)
	JoinStatsStore:SetAsync("id_" .. player.UserId, player.leaderstats.Joins.Value)
end)

image

I’m so bad at scripting if you can help to understand the issue

2 Likes

Hello,

The issue you’ve encountered might be the API service is not properly enabled. To enable the API service, you could check the following Roblox documentation.

2 Likes

Nothing changed sadly, I’m pretty sure the problem is on the script but I don’t know where since it’s not making any errors

2 Likes

i am a little confused about why you’re assuming one datastore can be expected to store either a number or table.

1 Like

Overall, there’s nothing wrong with the code relating to this problem. All I can say is to make sure that API Services are enabled in the game settings, and that you test your data in the game through the Roblox app. If you don’t know already, most of the time data won’t save if you change it on studio. You could try adding game:BindToClose(function() at the bottom of your script and see if it works:

local function SaveData(player)
    TimeStatsStore:SetAsync(player.UserId, player.leaderstats.Minutes.Value)
    JoinStatsStore:SetAsync("id_" .. player.UserId, player.leaderstats.Joins.Value)
end

game.Players.PlayerRemoving:Connect(SaveData)
game:BindToClose(function()
    for _, player in game.Players:GetPlayers() do
        SaveData(player)
    end
end)

I do have some suggestions for your code:

  1. There’s absolutely no need to check if the savedData is a table.
  2. The loop in updateMinutes is a memory leak. If a player leaves, the while loop still runs and errors every time it tries to update that player’s data. Not game breaking, but will cause lag to compound overtime. I recommend having one loop running which updates all players’ minutes value.
1 Like

Still not working and API Services is enabled

1 Like

Could you show us the output log?
image
image

Home
Output

1 Like

Sorry for the late answer , nothing in the output and still didn’t fixed yet

1 Like

I’m new about scripting since they was no error in the past , I was not minding about this but if can show me what can be changed that would be nice

1 Like

there could be an error in JoinStatsStore.GetAsync(), try printing the error message if success2 is false (failed) then check the output

	if success2 then
		if savedData then
			if type(savedData) == "table" then
				save2.Value = savedData[1] + 1
			else
				save2.Value = savedData + 1 
			end
		else
			save2.Value = 1
		end
	else -- GetAsync failed
		warn("Getting data from JoinStatsStore failed")
		print(savedData) -- prints the error message
	end
1 Like

I find when using a pcall the way you did there, it doesn’t work sometimes (e.g. it doesn’t catch the error at all, it just errors as if the pcall isn’t there). Try doing something like this:

local success, data = pcall(TimeStatsStore.GetAsync, TimeStatsStore, Player.UserId)

(Also, SetAsync needs a pcall as well).

edit from months later:
yeah it was the way i was indexing it sorry thats mb i was a bit dumb xd

i edited post for correct code please ignore this

1 Like

what’s your proof of this, when

pcall(function()
    return TimeStatsStore:GetAsync(player.UserId)
end)

functions the same as

pcall(TimeStatsStore.GetAsync, TimeStatsStore, player.UserId)

as stated in the documentation of pcall()

pcall(TimeStatsStore.GetAsync, TimeStatsStore, player.UserId) will basically execute TimeStatsStore.GetAsync(TimeStatsStore, player.UserId) (which is the same as TimeStatsStore:GetAsync(player.UserId)) and return if it executed successfully and the value the function returned (if execution failed, returns the error message instead)

2 Likes

I know they are the exact same thing.

I ran this code:
local success, result = pcall(DataStore.GetAsync, DataStore, key)

And I forced it to error, just to double check.
In my error handling code, I made it warn the error and kick the player without saving data. It didn’t do that, the code just errored and execution halted, so the player’s data was lost. Only when I did it the other way, it worked. It might be a bug, but I don’t see the harm in making an anonymous function if it worked and the other didn’t.

1 Like

hmm definitely a bug, though that never happened to me before, really weird

1 Like

ok so, I’ve fixed it
tell me if I need to do other change

local DataStoreService = game:GetService("DataStoreService")
local TimeStatsStore = DataStoreService:GetDataStore("TimeStats")
local JoinStatsStore = DataStoreService:GetDataStore("JoinStats")

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

	local Joins = Instance.new("IntValue", leaderstats)
	Joins.Name = "Joins"
	Joins.Value = 0 

	local Minutes = Instance.new("IntValue", leaderstats)
	Minutes.Name = "Minutes"
	Minutes.Value = 0 

	return leaderstats
end

local function updateMinutes(player)
	while player.Parent do
		task.wait(60)
		player.leaderstats.Minutes.Value += 1
	end
end

game.Players.PlayerAdded:Connect(function(player)
	local leaderstats = createLeaderstats(player)

	local success, data = pcall(TimeStatsStore.GetAsync, TimeStatsStore, player.UserId)
	if success then
		leaderstats.Minutes.Value = data or 0
	end

	local plrKey = "id_" .. player.UserId
	local save2 = player.leaderstats.Joins
	local success2, savedData = pcall(JoinStatsStore.GetAsync, JoinStatsStore, plrKey)
	if success2 then
		save2.Value = (savedData and type(savedData) == "table") and savedData[1] or savedData or 0
	end

	save2.Value += 1 
	JoinStatsStore:SetAsync(plrKey, save2.Value) 

	coroutine.wrap(updateMinutes)(player)
end)

game.Players.PlayerRemoving:Connect(function(player)
	TimeStatsStore:SetAsync(player.UserId, player.leaderstats.Minutes.Value)
end)

game:BindToClose(function()
	for _, player in ipairs(game.Players:GetPlayers()) do
		TimeStatsStore:SetAsync(player.UserId, player.leaderstats.Minutes.Value)
	end
end)
1 Like

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.