DataStores not working and no errors

I am new to working with DataStores so I may be missing something here, but I’m stumped. I’ve looked through older posts regarding this same issue but none of the solutions found on them worked for me. All values are being changed on the Server and not the client. It was working before when I only had one value that was being saved, but after I added all the others it stopped. I even added the print to see if the entire script was being ran. Any help?

EDIT: I do have both HTTP Requests and API Enabled in Security

--// Variables

local DSS = game:GetService("DataStoreService")
local SilverDS = DSS:GetDataStore("Data1") 
local GoldDS = DSS:GetDataStore("Data1") 
local DiamondDS = DSS:GetDataStore("Data1") 
local EmeraldDS = DSS:GetDataStore("Data1") 
local AmethystDS = DSS:GetDataStore("Data1") 
local RubyDS = DSS:GetDataStore("Data1") 

--// Main Function
game.Players.PlayerAdded:Connect(function(plr)
	
	--// Creating Folders and Values to be saved
	local MainFolder = Instance.new("Folder", plr)
	MainFolder.Name = "Gem_Stats"
	
	local Silver = Instance.new("IntValue", MainFolder)
	Silver.Name = "Silver"
	Silver.Value = SilverDS:GetAsync(plr.UserId) or 0
	
	local Gold = Instance.new("IntValue", MainFolder)
	Gold.Name = "Gold"
	Gold.Value = GoldDS:GetAsync(plr.UserId) or 0
	
	local Diamond = Instance.new("IntValue", MainFolder)
	Diamond.Name = "Diamond"
	Diamond.Value = DiamondDS:GetAsync(plr.UserId) or 0
	
	local Emerald = Instance.new("IntValue", MainFolder)
	Emerald.Name = "Emerald"
	Emerald.Value = EmeraldDS:GetAsync(plr.UserId) or 0
	
	local Amethyst = Instance.new("IntValue", MainFolder)
	Amethyst.Name = "Amethyst"
	Amethyst.Value = AmethystDS:GetAsync(plr.UserId) or 0
	
	local Ruby = Instance.new("IntValue", MainFolder)
	Ruby.Name = "Ruby"
	Ruby.Value = RubyDS:GetAsync(plr.UserId) or 0
	
	
	
	Silver.Changed:Connect(function()
		SilverDS:SetAsync(plr.UserId, Silver.Value)
	end)
	
	Gold.Changed:Connect(function()
		GoldDS:SetAsync(plr.UserId, Gold.Value)
	end)
	
	Diamond.Changed:Connect(function()
		DiamondDS:SetAsync(plr.UserId, Diamond.Value)
	end)
	
	Emerald.Changed:Connect(function()
		EmeraldDS:SetAsync(plr.UserId, Emerald.Value)
	end)
	
	Amethyst.Changed:Connect(function()
		AmethystDS:SetAsync(plr.UserId, Amethyst.Value)
	end)
	
	Ruby.Changed:Connect(function()
		RubyDS:SetAsync(plr.UserId, Ruby.Value)
	end)
	
end)


--// Saving after player leaves
game.Players.PlayerRemoving:Connect(function(plr)
	SilverDS:SetAsync(plr.UserId, plr.Gem_Stats.Silver.Value)
	GoldDS:SetAsync(plr.UserId, plr.Gem_Stats.Gold.Value)
	DiamondDS:SetAsync(plr.UserId, plr.Gem_Stats.Diamond.Value)
	EmeraldDS:SetAsync(plr.UserId, plr.Gem_Stats.Emerald.Value)
	AmethystDS:SetAsync(plr.UserId, plr.Gem_Stats.Amethyst.Value)
	RubyDS:SetAsync(plr.UserId, plr.Gem_Stats.Ruby.Value)
	print("Data has been saved successfully!")
end)

3 Likes

I think you only forgot to enable HTTP Requests, because your script works fine.

How to enable HTTP Requests:

1 Like

Yeah I forgot to mention it is all enabled. Both HTTP and API services. I will add that to the post now.

1 Like

And you could change your approach of what you are saving, I dont see a reason to have different DSS per item:

--// Saving after player leaves
game.Players.PlayerRemoving:Connect(function(plr)
	local playerDataTable = {
		Silver = plr.Gem_Stats.Silver.Value,
		Gold = plr.Gem_Stats.Gold.Value,
		-- etc...
	}
	
	local suc, err = pcall(function()
		return PlayersData:SetAsync(plr.UserId, playerDataTable)
	end)
	
	if suc then
		print("Data has been saved successfully!")
	else
		warn(err)
	end
end)
2 Likes

Actualy, I would rather suggest having the Data in a ServerSide Table, because this is unsafe and can be easily exploited by cheaters.

local data = {}

local function fetchData(player: Player)
    -- // Your code
end

-- Example
game.Players.PlayerAdded:Connect(function(player: Player)
    data[player.UserId] = fetchData(player);
end)

game.Players.PlayerRemoving:Connect(function(player: Player)
    data[player.UserId] = nil;
end)
1 Like

I always suggest to use tables in server modules handling all player data, because its more efficient than using values. But sometimes ppl dont know how yet, so Im not suggesting that upgrade atm.

About if its “easy” to exploit, nope, idk from where you get that information but no. You can use the Values and handle everything server side and there is no way to exploit that

1 Like

Do you have any other ideas? I’ve been stuck on this for a few hours and nothing is working. According to Dbom it should be working, but it’s evident it isnt because it isn’t working on my end. I have even tried testing it in game and not on studio because I know studio is a bit finicky with DataStores. TIA

Where do you have the Script stored in the Studio Place?

1 Like

ServerScriptService is where it is located.

If studio closes too fast there is a chance it has no enough time to save the data, different than a real server in which last 30 more seconds available in order to save.

As I recommended in my reply, firstly I would try to add the pcall and see the output warning when I close the server, adding game:BindToClose() could help too so you can see if there was enough time to save, or save under the event

Error I recieve

ServerScriptService.Gems_DATASTORE:84: attempt to index nil with 'SetAsync' - Server - Gems_DATASTORE:90

Also for whatever reason it sets all data values to 4 lol

Can you send the hole script, so I can check what could be wrong?

--// Variables

local DSS = game:GetService("DataStoreService")
local SilverDS = DSS:GetDataStore("Data1") 
local GoldDS = DSS:GetDataStore("Data1") 
local DiamondDS = DSS:GetDataStore("Data1") 
local EmeraldDS = DSS:GetDataStore("Data1") 
local AmethystDS = DSS:GetDataStore("Data1") 
local RubyDS = DSS:GetDataStore("Data1") 

--// Main Function
game.Players.PlayerAdded:Connect(function(plr)
	
	--// Creating Folders and Values to be saved
	local MainFolder = Instance.new("Folder", plr)
	MainFolder.Name = "Gem_Stats"
	
	local Silver = Instance.new("IntValue", MainFolder)
	Silver.Name = "Silver"
	Silver.Value = SilverDS:GetAsync(plr.UserId) or 0
	
	local Gold = Instance.new("IntValue", MainFolder)
	Gold.Name = "Gold"
	Gold.Value = GoldDS:GetAsync(plr.UserId) or 0
	
	local Diamond = Instance.new("IntValue", MainFolder)
	Diamond.Name = "Diamond"
	Diamond.Value = DiamondDS:GetAsync(plr.UserId) or 0
	
	local Emerald = Instance.new("IntValue", MainFolder)
	Emerald.Name = "Emerald"
	Emerald.Value = EmeraldDS:GetAsync(plr.UserId) or 0
	
	local Amethyst = Instance.new("IntValue", MainFolder)
	Amethyst.Name = "Amethyst"
	Amethyst.Value = AmethystDS:GetAsync(plr.UserId) or 0
	
	local Ruby = Instance.new("IntValue", MainFolder)
	Ruby.Name = "Ruby"
	Ruby.Value = RubyDS:GetAsync(plr.UserId) or 0
	
	
	
	Silver.Changed:Connect(function()
		SilverDS:SetAsync(plr.UserId, Silver.Value)
	end)
	
	Gold.Changed:Connect(function()
		GoldDS:SetAsync(plr.UserId, Gold.Value)
	end)
	
	Diamond.Changed:Connect(function()
		DiamondDS:SetAsync(plr.UserId, Diamond.Value)
	end)
	
	Emerald.Changed:Connect(function()
		EmeraldDS:SetAsync(plr.UserId, Emerald.Value)
	end)
	
	Amethyst.Changed:Connect(function()
		AmethystDS:SetAsync(plr.UserId, Amethyst.Value)
	end)
	
	Ruby.Changed:Connect(function()
		RubyDS:SetAsync(plr.UserId, Ruby.Value)
	end)
	
end)


--// Saving after player leaves

game.Players.PlayerRemoving:Connect(function(plr)
	local playerDataTable = {
		Silver = plr.Gem_Stats.Silver.Value,
		Gold = plr.Gem_Stats.Gold.Value,
		Diamond = plr.Gem_Stats.Diamond.Value,
		Emerald = plr.Gem_Stats.Emerald.Value,
		Amethyst = plr.Gem_Stats.Amethyst.Value,
		Ruby = plr.Gem_Stats.Ruby.Value,
	}

	local suc, err = pcall(function()
		return PlayersData:SetAsync(plr.UserId, playerDataTable)
	end)

	if suc then
		print("Data has been saved successfully!")
	else
		warn(err)
	end
end)

The variable PlayersData doesn’t exist, that is why. You didn’t define it.

Seems that you are doing it wrong. Btw you are getting the same datastore over and over again and just changing the name of the variable:

local SilverDS = DSS:GetDataStore("Data1") 
local GoldDS = DSS:GetDataStore("Data1") 
local DiamondDS = DSS:GetDataStore("Data1") 
local EmeraldDS = DSS:GetDataStore("Data1") 
local AmethystDS = DSS:GetDataStore("Data1") 
local RubyDS = DSS:GetDataStore("Data1")

All of those are the same datastore the Data1, if you gonna use all those DSS you gotta name them differently.

But as I suggested just use one datastore and save a table of the player’s data in there

1 Like

Oh ok… you used my example. But, my example assumes you have a datastore in a variable called PlayersData.

I am such an idiot. You were 100% right.

Thank you both for the help, I seriously have been stressing over this for hours lol

I’ll put both of your usernames down as contributors in the game :slight_smile:

1 Like

I added the PlayersData variable and changed your datastore names, so that it also really has different stores, else it will overwrite each.

--// Variables

local DSS = game:GetService("DataStoreService")
local SilverDS = DSS:GetDataStore("SilverDB") 
local GoldDS = DSS:GetDataStore("GoldDB") 
local DiamondDS = DSS:GetDataStore("DiamondDB") 
local EmeraldDS = DSS:GetDataStore("EmeraldDB") 
local AmethystDS = DSS:GetDataStore("AmethystDB") 
local RubyDS = DSS:GetDataStore("RubyDB")

local PlayersData = DSS:GetDataStore("StatsDB")

--// Main Function
game.Players.PlayerAdded:Connect(function(plr)

	--// Creating Folders and Values to be saved
	local MainFolder = Instance.new("Folder", plr)
	MainFolder.Name = "Gem_Stats"

	local Silver = Instance.new("IntValue", MainFolder)
	Silver.Name = "Silver"
	Silver.Value = SilverDS:GetAsync(plr.UserId) or 0

	local Gold = Instance.new("IntValue", MainFolder)
	Gold.Name = "Gold"
	Gold.Value = GoldDS:GetAsync(plr.UserId) or 0

	local Diamond = Instance.new("IntValue", MainFolder)
	Diamond.Name = "Diamond"
	Diamond.Value = DiamondDS:GetAsync(plr.UserId) or 0

	local Emerald = Instance.new("IntValue", MainFolder)
	Emerald.Name = "Emerald"
	Emerald.Value = EmeraldDS:GetAsync(plr.UserId) or 0

	local Amethyst = Instance.new("IntValue", MainFolder)
	Amethyst.Name = "Amethyst"
	Amethyst.Value = AmethystDS:GetAsync(plr.UserId) or 0

	local Ruby = Instance.new("IntValue", MainFolder)
	Ruby.Name = "Ruby"
	Ruby.Value = RubyDS:GetAsync(plr.UserId) or 0



	Silver.Changed:Connect(function()
		SilverDS:SetAsync(plr.UserId, Silver.Value)
	end)

	Gold.Changed:Connect(function()
		GoldDS:SetAsync(plr.UserId, Gold.Value)
	end)

	Diamond.Changed:Connect(function()
		DiamondDS:SetAsync(plr.UserId, Diamond.Value)
	end)

	Emerald.Changed:Connect(function()
		EmeraldDS:SetAsync(plr.UserId, Emerald.Value)
	end)

	Amethyst.Changed:Connect(function()
		AmethystDS:SetAsync(plr.UserId, Amethyst.Value)
	end)

	Ruby.Changed:Connect(function()
		RubyDS:SetAsync(plr.UserId, Ruby.Value)
	end)

end)


--// Saving after player leaves

game.Players.PlayerRemoving:Connect(function(plr)
	local playerDataTable = {
		Silver = plr.Gem_Stats.Silver.Value,
		Gold = plr.Gem_Stats.Gold.Value,
		Diamond = plr.Gem_Stats.Diamond.Value,
		Emerald = plr.Gem_Stats.Emerald.Value,
		Amethyst = plr.Gem_Stats.Amethyst.Value,
		Ruby = plr.Gem_Stats.Ruby.Value,
	}

	local suc, err = pcall(function()
		return PlayersData:SetAsync(plr.UserId, playerDataTable)
	end)

	if suc then
		print("Data has been saved successfully!")
	else
		warn(err)
	end
end)
1 Like

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.