Datastores not working correctly

I ran the command for myself a couple of times on accident lol. And i ran the one that resets all datastores once.
Here’s what’s in the Output:

  • DataStoreService: CantStoreValue: Cannot store Dictionary in data store. Data stores can only accept valid UTF-8 characters. API: SetAsync, Data Store: playerData - Studio
  • Cannot store Dictionary in data store. Data stores can only accept valid UTF-8 characters. - Server - Leaderstats/Datastore:22

Oops, I made a typo. Check my edited code.

which code did you edit? i can’t tell lol

1 Like

i replace the code with that and its still not working. Wait… im testing in roblox studio right now and when i open up the player in the explorer there are two leaderstats folders in there, one of them has the saved values and the other has zero values.
Edit: i accidentally had another script that was creating a leaderstats folder and i forgot to delete it, so im gonna test in Roblox again quick.

IT WORKS FINALLY THANK YOU SO MUCH! especially for your quick responses!!!
Here’s the working code:

local Players = game:GetService("Players")
local DataStoreService = game:GetService("DataStoreService")
local playerDataStore = DataStoreService:GetDataStore("playerData")

local defaultData = {
	["Deaths I"] = 0,
	["Escapes I"] = 0,
	["Deaths II"] = 0,
	["Escapes II"] = 0,
	["Deaths III"] = 0,
	["Escapes III"] = 0
}

local leaderstatValues = {"Deaths I", "Escapes I"}

local function SaveData(player, data)
	local success, errorMessage = pcall(function()
		playerDataStore:SetAsync(player.UserId, data)
	end)

	if not success then
		warn(errorMessage)
	end
end

local function OnPlayerRemoving(player)
	local leaderstats = player.leaderstats
	local storedData = player.storedData

	local data = {}

	for valueName, _ in defaultData do
		data[valueName] = table.find(leaderstatValues, valueName) and leaderstats[valueName].Value or storedData[valueName].Value
	end

	SaveData(player, data)
end

Players.PlayerAdded:Connect(function(player)
	local playerData = playerDataStore:GetAsync(player.UserId) or defaultData

	local leaderstats = Instance.new("Folder")
	leaderstats.Name = "leaderstats"

	local storedData = Instance.new("Folder")
	storedData.Name = "storedData"

	for valueName, _ in defaultData do
		local intValue = Instance.new("IntValue")
		intValue.Name = valueName
		intValue.Value = playerData[valueName]
		intValue.Parent = table.find(leaderstatValues, valueName) and leaderstats or storedData
	end

	leaderstats.Parent = player
	storedData.Parent = player
end)

Players.PlayerRemoving:Connect(OnPlayerRemoving)

game:BindToClose(function()
	for i, player in Players:GetPlayers() do
		task.spawn(OnPlayerRemoving, player)
	end
end)
1 Like

No problem, I would appreciate the solution though.

If you have any questions, feel free to ask. Have a good day/night!

1 Like

Of course!! Thank you so much!

1 Like

I actually do have a quick question lol. Now that the Datastores work, i’m trying to refresh my physical Global Leaderboards so that they erase there old data. I especially want to do this because some of the names on the leaderboard say “Not Available” and i think that should be fixed with the new Datastore system.
Here’s what the code looks like for one part of the leaderboards: (they’re all the same exact with the different values for each of course)

local StatsName = "Deaths I"
local MaxItems = 100
local MinValueDisplay = 1
local MaxValueDisplay = 10e15
local UpdateEvery = math.random(15, 60)

local DataStoreService = game:GetService("DataStoreService")
local DataStore = DataStoreService:GetOrderedDataStore("GlobalLeaderboard_" .. StatsName)
local SurfaceGui = script.Parent
local Sample = script.Sample
local List = SurfaceGui.Frame.List
local ItemsFrame = List.ListContent.Items

local function GetItems()
	local Data = DataStore:GetSortedAsync(false, MaxItems, MinValueDisplay, MaxValueDisplay)
	local TopPage = Data:GetCurrentPage()
	
	ItemsFrame.Nothing.Visible = #TopPage == 0 and true or false
	
	for i, v in ipairs(TopPage) do
		local UserId = v.key
		local Value = v.value
		local Username = "[Not Available]"
		local Color = Color3.fromRGB(38, 50, 56)
		
		local Success, Error = pcall(function()
		 	Username = game.Players:GetNameFromUserIdAsync(UserId)
		end)
		
		if i == 1 then
			Color = Color3.fromRGB(255, 215, 0)
		elseif i == 2 then
			Color = Color3.fromRGB(192, 192, 192)
		elseif i == 3 then
			Color = Color3.fromRGB(205, 127, 50)
		end
		
		local Item = Sample:Clone()
		Item.Name = Username
		Item.LayoutOrder = i
		Item.Values.Number.TextColor3 = Color
		Item.Values.Number.Text = i
		Item.Values.Username.Text = Username
		Item.Values.Value.Text = Value
		Item.Parent = ItemsFrame
	end
end

while true do
	for i, v in pairs(game.Players:GetPlayers()) do
		local Stats = v.storedData:WaitForChild(StatsName).Value
		if Stats then
			pcall(function()
				DataStore:UpdateAsync(v.UserId, function(Value)
					return tonumber(Stats)
				end)
			end)
		end
	end
	
	for i, v in pairs(ItemsFrame:GetChildren()) do
		if v:IsA("ImageLabel") then
			v:Destroy()
		end
	end
	
	GetItems()
	
	wait()
	SurfaceGui.Heading.Heading.Text = StatsName .. " Leaderboard"
	List.ListContent.GuideTopBar.Value.Text = StatsName
	List.CanvasSize = UDim2.new(0, 0, 0, ItemsFrame.UIListLayout.AbsoluteContentSize.Y + 35)
	wait(UpdateEvery)
end

Those not available names could be because of a Local Server test, since the players created there don’t exist. You can try to change the DataStoreKey and it should be fine.

Code:

local DataStore = DataStoreService:GetOrderedDataStore("GlobalLeaderboard1_" .. StatsName)

You can also add checks to not save userIds under 0.

1 Like

That seems to have done the trick!! Thanks again! :slight_smile:

1 Like

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