Hello, I’m trying to make a script that saves and loads 2 values:
local DSS = game:GetService("DataStoreService")
local MoneyStore = DSS:GetDataStore("DataStore1")
local LevelStore = DSS:GetDataStore("DataStore2")
game.Players.PlayerAdded:Connect(function(player)
local DataFolder = Instance.new("Folder", player)
DataFolder.Name = ("leaderstats")
local MoneyInt = Instance.new("IntValue", DataFolder)
MoneyInt.Name = ("Money")
local LevelInt = Instance.new("IntValue", DataFolder)
LevelInt.Name = ("Level")
local data1
local data2
local success,errormessage = pcall(function()
data1 = MoneyStore:GetAsync(player.UserId.."cash")
data2 = LevelStore:GetAsync(player.UserId.."level")
end)
if success then
MoneyInt.Value = data1
LevelInt.Value = data2
else
warn(errormessage)
end
end)
game.Players.PlayerRemoving:Connect(function(player)
local success,errormessage = pcall(function()
MoneyStore:SetAsync(player.UserId.."cash",player.leaderstats.Money.Value)
LevelStore:SetAsync(player.UserId.."level",player.leaderstats.Level.Value)
end)
if success then
print("Succes saving data!")
else
warn(errormessage)
end
end)
The issue is that it won’t work at all, doesn’t give any error either, both API and HTTP requests are enabled in the game. I can’t figure out what is the problem.
I tried it even with only one value, still didn’t work.
Please indent your code! It makes it a readability nightmare! From what I’m aware of, you have an extra “end)” at the end of your code. And your events are separately enclosed, so I’m sure it’s that. You can easily avoid that by indenting it. You use the tab key to space it like this:
function thingy()
if variable == thing then
local blahblahblah = "do this"
end
end
event:Connect(function()
local thingy = "words and stuff"
end) -- typically end statements have a parenthesis after there is an unclosed parenthesis in the statement that created it.
If you mean that the PlayerAdded function doesn’t end before the PlayerRemoving function, I tried adding a bonus end before the PlayerRemoving function and it gave me an output error.
local successCash, ReturnCash = pcall(function()
return MoneyStore:GetAsync(player.UserId.."cash")
end)
local successLevel, ReturnLevel = pcall(function()
return MoneyStore:GetAsync(player.UserId.."level")
end)
if successCash then
MoneyInt.Value = ReturnCash
else
warn(ReturnCash)
end
if successLevel then
LevelInt.Value = ReturnLevel
else
warn(ReturnLevel)
end
That should be basically the whole data saving option, I doubt this is the problem but it’s just pleasing to me. I infer that the PROBLEM is that you aren’t parenting the MoneyInt and LevelInt values created in the beginning of your script. But yea along the way it’s much more readable to write it in the way that’s up there ^^^. Yea though your problem isn’t the loading but more of actually not parenting the instances you’ve made which could easily be solved with DataFolder.Parent = Player , MoneyInt = DataFolder , and LevelInt = DataFolder . Also, make sure to make these changes inside the PlayerAdded event. Yea though, Hope that helped!
Personally, I think the issue is that your players aren’t being registered at all. If you truly aren’t getting errors (check your console again) and you know you have all the game configurations set (DataStores do not need HttpEnabled), this is the only thing I can think of. Combat it using a catcher function. Essentially: take the anonymous function that listens to PlayerAdded and make it a defined function. Have it listen to PlayerAdded then run it on existing players.
local Players = game:GetService("Players")
-- DataStores up here, you should know how to move them over
local function playerAdded(player)
-- All your PlayerAdded code here; I'm not filling it in for you
end
-- Might as well stick to new conventions and make things readable
local function playerRemoving(player)
-- Your PlayerRemoving code here; I'm not filling it in for you
end
Players.PlayerAdded:Connect(playerAdded)
Players.PlayerRemoving:Connect(playerRemoving)
for _, player in pairs(Players:GetPlayers()) do
playerAdded(player)
end
Some other recommendations, besides this, to make.
Look into using only a single DataStore for all player data instead of one per stat. Having two DataStores for each player can result in any of the following consequences: unreadability, maintenance trouble, data loss, throttled/hogged DataStore requests, et cetera.
You aren’t making good use of pcalls. One pcall should be responsible for wrapping one call, not several of them. Furthermore, the creation of the upvalues data1 and data2 is unnecessary; you can return the result of GetAsync or wrap the function directly.
Your data script should not be assuming that if the pcall is successful, then it’s clear to add data. If a player doesn’t have data stored, your script is setting the values of some ValueObjects to nil. That’s a no-no. Cannot hardset nil just because a call passes.
@serverModule It’s not. The indenting may be bad but you can pretty clearly see that PlayerRemoving is outside of the PlayerAdded function. Despite this, it wouldn’t make a difference.
I remade the script using some solutions you guys said:
local DSS = game:GetService("DataStoreService")
local DataStore = DSS:GetDataStore("Data")
function playerAdded(player)
local DataFolder = Instance.new("Folder")
DataFolder.Parent = player
DataFolder.Name = "leaderstats"
local MoneyInt = Instance.new("IntValue")
MoneyInt.Parent = DataFolder
MoneyInt.Name = "Money"
local LevelInt = Instance.new("IntValue")
LevelInt.Parent = DataFolder
LevelInt.Name = "Rebirths"
local successCash, returnCash = pcall(function()
return DataStore:GetAsync(player.UserId..'Money')
end)
local succesLvl, returnLvl = pcall(function()
return DataStore:GetAsync(player.UserId.."Level")
end)
if successCash then
MoneyInt.Value = returnCash
else
warn(returnCash)
end
if succesLvl then
LevelInt.Value = returnLvl
else
warn(returnLvl)
end
end
function playerRemoving(player)
local sucess, errormessage = pcall(function()
DataStore:SetAsync(player.UserId..'Cash',player.leaderstats.Money.Value)
DataStore:SetAsync(player.UserId..'Level',player.leaderstats.Rebirths.Value)
end)
if sucess then
print("Succes saving data!")
else
warn(errormessage)
end
end
game.Players.PlayerAdded:Connect(playerAdded)
game.Players.PlayerRemoving:Connect(playerRemoving)
for i, player in pairs(game.Players:GetPlayers()) do
playerAdded(player)
end
It still doesn’t work. I double checked API and made the game public, yet it still doesn’t work.
This isn’t quite what I meant by flatten it down to one DataStore, but that’s beside the point, it was just a recommendation.
Need to know how specifically it isn’t working. Has anything appeared in your console? Please also print the returns of the pcalls. Adding prints on each line could help test what runs and what doesn’t, thus directing you to the problem code.
I just realized the biggest issue, You’re using return rather than setting it to a variable.
local cash -- variable placeholder
local success, errormessage = pcall(function()
cash = datastore:GetAsync(player.UserId .. 'Money')
end)
if success then
MoneyInt.Value = cash
else
warn(errormessage)
end