When i go to my second place, for example, though it doesn’t load my saved Part 1 values.
Here’s the code for the second place:
local Players = game:GetService("Players")
local DataStoreService = game:GetService("DataStoreService")
local playerDataStore = DataStoreService:GetDataStore("playerData")
local defaultData = {
leaderstats = {
["Deaths II"] = 0,
["Escapes II"] = 0,
},
storedData = {
["Deaths I"] = 0,
["Escapes I"] = 0,
["Deaths III"] = 0,
["Escapes III"] = 0
}
}
local leaderstatsName = game.PlaceId == myreal2ndplaceidishere and "leaderstats" or "folder"
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 data = defaultData
for folderName, folderValues in defaultData do
local folder = player[folderName == "leaderstats" and leaderstatsName or folderName]
for valueName, _ in folderValues do
data[folderName][valueName] = folder[valueName].Value
end
end
SaveData(player, data)
end
Players.PlayerAdded:Connect(function(player)
local playerData = playerDataStore:GetAsync(player.UserId) or defaultData
for folderName, folderValues in defaultData do
local folder = Instance.new("Folder")
folder.Name = folderName == "leaderstats" and leaderstatsName or folderName
for valueName, _ in folderValues do
local intValue = Instance.new("IntValue")
intValue.Name = valueName
intValue.Value = playerData[folderName][valueName]
intValue.Parent = folder
end
folder.Parent = player
end
end)
Players.PlayerRemoving:Connect(OnPlayerRemoving)
game:BindToClose(function()
for i, player in Players:GetPlayers() do
task.spawn(OnPlayerRemoving, player)
end
end)
That is what i want, but when i check the storedData folder inside of the Player, where Deaths1, Escapes1, Deaths3, & Escapes3 should all be, they’re in the folder but their values are all at zero, so they didn’t save from place 1 or place 3. I’m trying to get all of the data to transfer to the other places because in my Lobby place i have leaderboards for each of the different values.
Oh, I just realized you did it wrong. If you want the leaderstats to only show the current world’s count, then we have to do something different.
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 = {"Death I", "Escapes I"} -- Change this depending on level
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)
Do i need to reset everybody’s data as well? because there are a couple of other people that have tested my game out and they have data. Is there a way to reset all data? if that’s what i need to do?
local DSS = game:GetService("DataStoreService")
local DataStore = DSS:GetDataStore("playerData")
local KeysPages = DataStore:ListKeysAsync()
while true do
local CurrentKeysPage = KeysPages:GetCurrentPage()
for j, Key in pairs(CurrentKeysPage) do
DataStore:RemoveAsync(Key.KeyName)
end
if KeysPages.IsFinished then break end
KeysPages:AdvanceToNextPageAsync()
end
If you want me to implement a way that preserves their data, tell me. There will be a performance cost though.
The data still isn’t saving or transferring.
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"} -- Change this depending on level
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] or storedData[valueName]
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)
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
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)
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.