DataStore won't work at all

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 help !

Any reason for this, if you can change keys?

I tried making that script a few days ago with changing keys, but it didn’t work and I thought that was the problem

When you’re naming Instances you’re using parenthesis around the speech marks when you shouldn’t.
Example here:

DataFolder.Name = ("leaderstats")

Should be:

DataFolder.Name = "leaderstats"

That’s the only problem I could spot.
FYI: I recommend to save a table containing all the data.

It doesn’t matter. Defining it with parentheses should make no difference.

local x = ((((("hi")))))
print(x) --> hi
3 Likes

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.
1 Like

Sorry if it’s unreadable, I just learnt how to use preformatted text.

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.

It doesn’t look like there are any errors in your code. Have you made sure that the script is running in the first place?

  • Script is of class Script.
  • Script is not disabled.
  • Script is in Workspace or ServerScriptService.

Yep, it’s a script inside ServerScriptService

1 Like

Ok this might be a dumb question, but is the game published? Datastore only works with published.
Also did you get any sort of error or http error?

1 Like

Replace that with

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!

That doesn’t make a difference.

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.

  • Don’t use the parent argument with Instance.new, considering you set properties (even if it is just one) after instancing. Create the instance, name it then parent it.

  • 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.

1 Like

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.

Try taking the datastore stuff out off the pcalls, the pcall could be masking most of the errors.

Nothing is in console besides an unrelated error saying game can’t find an image.

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

Also found out that in Output in studio, loadstring isn’t available, is that the problem ?