I was following a tutorial from AlvinBlox, because I'm relatively new to RBX Lua scripting, on how to DataStore leaderstats. I couldn't really find anything on Youtube that stored multiple leaderstats and worked for me, so I tried to common-sense my way out of the problem. Turns out this doesn't work, because even though everything prints out success it doesn't actually load anything in. If anyone could fix up my code and/or tell me why it doesn't work would be greatly appreciated.
local DataStoreService = game:GetService("DataStoreService") local myDataStore = DataStoreService:GetDataStore("myDataStore") local myDataStore2 = DataStoreService:GetDataStore("myDataStore2") local myDataStore3 = DataStoreService:GetDataStore("myDataStore3") game.Players.PlayerAdded:Connect(function(player) local leaderstats = Instance.new("Folder") leaderstats.Name = "leaderstats" leaderstats.Parent = player local Points = Instance.new("IntValue") Points.Name = "LagPoints" Points.Parent = leaderstats local Minutes = Instance.new("IntValue") Minutes.Name = "Minutes" Minutes.Parent = leaderstats local Bricks = Instance.new("IntValue") Bricks.Name = "Bricks" Bricks.Parent = leaderstats local datapoints local dataminutes local databricks local success, errormessage = pcall(function() datapoints = myDataStore:GetAsync(player.UserId.."-points") end) if success then Points.Value = datapoints print("Data succesfully loaded your LagPoints.") else print("There was an error whilst getting your data for LagPoints.") end local success, errormessage = pcall(function() dataminutes = myDataStore2:GetAsync(player.UserId.."-mins") end) if success then Points.Value = dataminutes print("Data succesfully loaded your Minutes in Lag-Mode.") else print("There was an error whilst getting your data for Minutes.") end local success, errormessage = pcall(function() datapoints = myDataStore3:GetAsync(player.UserId.."-bricks") end) if success then Points.Value = databricks print("Data succesfully loaded your Bricks Spawned.") else print("There was an error whilst getting your data for Bricks.") end end) game.Players.PlayerRemoving:Connect(function(player) local success, errormessage = pcall(function() myDataStore:SetAsync(player.UserId.."-points",player.leaderstats.LagPoints.Value) end) if success then print(player.Name.."'s Data Saved Succesfully.") else print("There was an error saving "..player.Name.."'s data!") warn(errormessage) end local success, errormessage = pcall(function() myDataStore2:SetAsync(player.UserId.."-mins",player.leaderstats.Minutes.Value) end) if success then print(player.Name.."'s Data Saved Succesfully.") else print("There was an error saving "..player.Name.."'s data!") warn(errormessage) end local success, errormessage = pcall(function() myDataStore3:SetAsync(player.UserId.."-bricks",player.leaderstats.Bricks.Value) end) if success then print(player.Name.."'s Data Saved Succesfully.") else print("There was an error saving "..player.Name.."'s data!") warn(errormessage) end end)
Well in order to make a fully functioning leaderboard, here is my approach.
Setting the leaderboard
game.Players.PlayerAdded:Connect(function(plr) local leaderstats = Instance.new('Folder') leaderstats.Name = 'leaderstats' leaderstats.Parent = plr local dollar = Instance.new('IntValue') dollar.Name = 'Money' dollar.Value = 0 dollar.Parent = leaderstats local item = Instance.new('IntValue') item.Name = 'Items' item.Value = 0 item.Parent = leaderstats end)
Now in order to actually see visible change, I added a part to show the intValue increment by 1.
Updating leaderboard
script.Parent.Parent.Part.Touched:Connect(function(touch) local parent = touch.Parent --Who touched the part local humanoid = parent:FindFirstChildWhichIsA('Humanoid') if humanoid then --If humanoid local plr = game:GetService('Players'):GetPlayerFromCharacter(parent) -- Gets leaderboard local leaderstats = plr.leaderstats local moneyMaker = leaderstats and leaderstats:FindFirstChild('Money') if moneyMaker then moneyMaker.Value = moneyMaker.Value + 1 --Changes value from 0 to +1 everytime it is touched. end end end)
This is a simple leaderboard approach that I made just now. I also suggest you look on roblox's tutorials here- Leaderboard tutorial - https://developer.roblox.com/en-us/articles/Leaderboards
Full script-
local dds = game:GetService('DataStoreService') local moneyData = dds:GetDataStore('MONEYDATA') local itemData = dds:GetDataStore('ITEMDATA') game.Players.PlayerAdded:Connect(function(plr) local data local data2 local leaderstats = Instance.new('Folder') leaderstats.Name = 'leaderstats' leaderstats.Parent = plr local dollar = Instance.new('IntValue') dollar.Name = 'Money' dollar.Value = 0 dollar.Parent = leaderstats local item = Instance.new('IntValue') item.Name = 'Items' item.Value = 0 item.Parent = leaderstats while wait(5) do --every 5 seconds saves data moneyData:SetAsync(plr.UserId..'-moneyData', dollar.Value) itemData:SetAsync(plr.UserId..'-itemData', item.Value) end local success, err = pcall(function() data = moneyData:GetAsync(plr.UserId..'-moneyData') or 0 end) if success then dollar.Value = data else -- Failed to retrieve data end local success, err = pcall(function() data2 = itemData:GetAsync(plr.UserId..'-itemData') or 0 end) if success then item.Value = data2 else -- Failed to retrieve data2 end end)
Part Script
script.Parent.Parent.Part.Touched:Connect(function(touch) local parent = touch.Parent local humanoid = parent:FindFirstChildWhichIsA('Humanoid') if humanoid then local plr = game:GetService('Players'):GetPlayerFromCharacter(parent) local leaderstats = plr.leaderstats local moneyMaker = leaderstats and leaderstats:FindFirstChild('Money') if moneyMaker then moneyMaker.Value = moneyMaker.Value + 1 end end end)
Also, if u dont understand, here is a link for datastores - https://developer.roblox.com/en-us/api-reference/function/GlobalDataStore/GetAsync
I believe I know the error in this script, you're setting the value of "points" 3 different times, but you only need to set it once.
Here's the fix:
Change line 41 to:
Minutes.Value = dataminutes
Change line 51 to:
Bricks.Value = databricks
have fun scripting, hydrogyn
I recommend saving it all in one table, this way you don't have to multiple setasyncs or update async
local StatsTable = {} StatsTable.Money = Player.leaderstats.Money.Value StatsTable.Items = Player.leaderstats.Items.Value while true do repeat local Success, Error_ = pcall(function() StatsDataStore:SetAsync(Player.Userid.."_Stats", StatsTable) end) wait(2) until Success wait(10) end
I am pretty sure while wait() do is a bad idea, so just do a normal while true do is good with a coroutine on the while true do function for saving data, also, having a longer wait period on set asyncs is a good idea because you don't want to make to many requests in a short period of time. Using the pccall is a good idea because sometimes Datastores will error, and using a call can prevent it from breaking the code. https://devforum.roblox.com/t/avoiding-wait-and-why/244015