I have some IntValues in my game that aren’t in the leaderstats folder, they’re in a folder called HiddenVals, because they are hidden. One of them is “ClickGain” which is how many currency you gain per click, however this IntValue needs to save so when players leave and rejoin it stays the same. I am trying to use my datastore script to save this data (which does work, I’ve used it before on values in the leaderstats folder), but it doesn’t save for some reason. Here is my data store script
local DSS = game:GetService("DataStoreService")
local DataStore = DSS:GetDataStore("Data")
local coin
local cals
local cg
local success, errormessage = pcall(function()
coin = DataStore:GetAsync(Player.UserId.."-Coins")
cals = DataStore:GetAsync(Player.UserId.."-Calories")
cg = DataStore:GetAsync(Player.UserId.."-ClickGain")
end)
if success then
Coins.Value = coin
Calories.Value = cals
ClickGain.Value = cg
else
print("There was an error while saving")
warn(errormessage)
end
end)
game.Players.PlayerRemoving:Connect(function(player)
local DSS = game:GetService("DataStoreService")
local DataStore = DSS:GetDataStore("Data")
local success, errormessage = pcall(function()
DataStore:SetAsync(player.UserId.."-Coins",player.leaderstats.Coins.Value)
DataStore:SetAsync(player.UserId.."-Calories",player.leaderstats.Calories.Value)
DataStore:SetAsync(player.UserId.."-ClickGain",player.HiddenVals.ClickGain.Value)
end)
if success then
print("Player Data saved successfully")
else
print("error when saving data")
warn(errormessage)
end
end)
There’s probably some obvious answer that I don’t see, and I am sorry if that is the case.
There are better ways to do this since you could use one datastore for all of these values or you could use Datastore2 as a way of saving your data. It’s also better to have your variables on the outside of your functions, for example, put the datastore variables at the top of your code and only use: GetDataStore() once instead of every time a play joins and leaves.
A better way you could save it is by using a table to save values in a certain order so it can be loaded and called in that specific order.
Saving:
local DataToSave = {
Player.leaderstats.Coins.Value, -- Coins value
Player.leaderstats.Calories.Value, -- Calories value
Player.HiddenVals.ClickGain.Value, -- Clickgain value
}
local succ,err = pcall(function()
DataStore:SetAsync(Player.UserId .. "-key", DataToSave)
end)
if not succ then
warn(err)
end
Loading:
local DataLoaded = DataStore:GetAsync(Player.UserId .. "-key")
if DataLoaded then
Instance.Value = DataLoaded[1] -- Coins
Instance.Value = DataLoaded[2] -- Calories
Instance.Value = DataLoaded[3] -- Clickgain
end
Doesn’t matter where data is. If it’s passed to a DataStore write method (Set, Update & Increment), then it’ll be written to the DataStore. What you are most likely experiencing is a code error which comes from the lack of debugging on your end, or if that was done then it’s not clearly indicated.
Details will need to be provided to further help you with your issue. Remember that saying that your code work isn’t sufficient enough to know the problem: we can’t assume we know what you mean by it’s not working. Be sure to do some debugging yourself as well.
With that aside, I did notice an awful thing about your DataStore: you are making far too many calls because you aren’t using DataStores efficiently. You end up using three keys in a DataStore to save three different values when you can instead pack that away into a dictionary.
I doubt that. I can guarantee it will fail if what you’ve posted is the full script (and if it isn’t, perhaps post the full script) because you’re indexing variables that don’t exist, namely Coins, Calories and ClickGain on lines 14, 15, 16.
Can you confirm that a) it doesn’t error at all, and that you’ve just not provided the whole script, and b) that it prints “Player Data saved successfully” after attempting to save?
Well given that the loading part of the script relies on variables that you haven’t defined in the part that you’ve chosen to give us, I recommend you provide the whole data saving and loading script.
If it prints that it saved, then it has saved, so its likely that your values are wrong, the key you’re loading from isn’t that same as the key you’re saving to, or you’re reading from a different valueobject when saving than you’re setting to when loading. All of those would only be identifiable with the part of the script you’ve decided to omit.
The clickgain value immediately gets set to 0 when a new player joins the game, because you load cg from the datastore, the key doesn’t exist, so the value is nil, and setting an IntValue to nil will resolve to a value of 0. Is this intentional? The only reason I ask is that you deliberately set it to 1 just to get overrided to 0 or another value from the datastore.
I put this in a blank baseplate game, joined, left, it correctly saved my data as being 0 upon leaving the first time, and loaded this in instead of nil next time. I then used the command line to set the IntValue’s value to 2000, left, it saved, came back, it loaded and correctly set it to 2000. Your code therefore seems to do exactly what you asked it to. Any problems (other than that pointed out in 1.) are somewhere else in your programming, not in this saving/loading script.
What is it that is making you believe it isn’t saving? That might help to narrow down the issue. Look into your scripts that use/display the value of ClickGain to ensure it’s not those that are having the issue and are either reading the wrong ValueObject or something.
It’s also not particularly recommended to store things other than leaderstats in the Player object so try using a player-named folder in ReplicatedStorage that you create when they join and destroy after saving to see if that solves your issues.