Data Saving Help

  1. What do you want to achieve? I am creating a shop system

  2. What is the issue? The script is coming out with an error every time I try to buy, but the script still works, it just does not save.

  3. What solutions have you tried so far? I looked at the data store script and it should work, so the issue must be in the “BuyHandler” script. Probably an error stopping the rest of the script from running, but I don’t know what the error is.

Buy Handler

local rp = game.ReplicatedStorage
local evenmt = rp.RemoteEvent

game:GetService("ReplicatedStorage").RemoteEvent.OnServerEvent:Connect(function(player, toolName, price)
	    if(player.pointFolder.Points.Value >= price) then
		player.pointFolder.Points.Value = player.pointFolder.Points.Value - price
		player.Equipped.Value = toolName
		player.Swords:FindFirstChild(toolName).Value = true
		print(player.." bought "..toolName)
    end
end)

rp.Equip.OnServerEvent:Connect(function(player, item)
	if player.Swords:FindFirstChild(item).Value == true then
		player.Equipped.Value = item
	end
end)

Local Script

This script is in each button

local player = game.Players.LocalPlayer

script.Parent.MouseButton1Click:Connect(function()
	if player.Swords.RubySword.Value == true then

	elseif player.Swords.RubySword.Value == false then

		game:GetService("ReplicatedStorage").RemoteEvent:FireServer("RubySword", 2000)

	end
end)

Thanks in advance!

1 Like

As the error says you’re trying to compare an instance with a string.

You should try changing it to player.Name (instead of just player)

1 Like

Is that the error that is stopping the script?

No I don’t think that’s what prevents the data from saving since it’s the last line. After looking closer I can’t find any problem with it. I believe the problem is in your datastore script.

2 Likes

Ok let me send that!

local DataStoreService = game:GetService("DataStoreService")
local DataStore = DataStoreService:GetDataStore("DataStore") 

game.Players.PlayerAdded:Connect(function(player)
	
	local pointFolder = Instance.new("Folder")
	pointFolder.Name = "pointFolder"
	pointFolder.Parent = player

	
	local points = Instance.new("IntValue")
	points.Name = "Points"
	points.Parent = pointFolder
	
	local swords = Instance.new("Folder")
	swords.Name = "Swords"
	swords.Parent = player
	
	local GoldSword = Instance.new("BoolValue")
	GoldSword.Name = "GoldSword"
	GoldSword.Parent = swords
	
	local EmeraldSword = Instance.new("BoolValue")
	EmeraldSword.Name = "EmeraldSword"
	EmeraldSword.Parent = swords
	
	local AmythestSword = Instance.new("BoolValue")
	AmythestSword.Name = "AmythestSword"
	AmythestSword.Parent = swords
	
	local RubySword = Instance.new("BoolValue")
	RubySword.Name = "RubySword"
	RubySword.Parent = swords
	
	local Sword = Instance.new("BoolValue")
	Sword.Name = "Sword"
	Sword.Parent = swords
	Sword.Value = true
	
	
	player.CharacterAdded:Connect(function(character)
		character.Humanoid.WalkSpeed = 16
		character.Humanoid.Died:Connect(function()
			if character:FindFirstChild("deadTag") then
				character.deadTag:Destroy()
			end
		player:LoadCharacter()
	end)

end)
	
local playerUserId = "Player_"..player.UserId


--Local Data

	
local success, errormessage = pcall(function()
	data = DataStore:GetAsync(playerUserId)
end)
	
if success and data then
		points.Value = data[1]
		RubySword.Value	= data[2]
		EmeraldSword.Value	= data[3]
		AmythestSword.Value	= data[4]
		GoldSword.Value	= data[5]
	--Set the data equal to the current value
else
	print("Data not found")
end
end)

game.Players.PlayerRemoving:Connect(function(player)
local playerUserId = "Player_"..player.UserId

local data = {
		player:WaitForChild("pointFolder").Points.Value;
		player.Swords.RubySword.Value;
		player.Swords.EmeraldSword.Value;
		player.Swords.GoldSword.Value;
		player.Swords.AmythestSword;
}
end)

Ok so first of all I can’t see where you’re actually saving the data? For that you should use DataStore:SetAsync(playerUserId, data).

However datastore isn’t able to save tables so instead you should use JSONEncode (For saving data) and JSONDecode (For loading data)

https://developer.roblox.com/en-us/api-reference/function/HttpService/JSONEncode
https://developer.roblox.com/en-us/api-reference/function/HttpService/JSONDecode

1 Like

I have been able to save it through a table before. Could you fix the data store for me? I could pay you, I am really in a rush. (maybe explain through comments what you are doing)

You can save tables in a datastore actually. You can’t save the actual table but you can save what’s inside the table using a for loop.

1 Like

Oh ok that is what I thought, thanks for clearing that up. I think I may have deleted half of the data store script :woman_facepalming:

Edit - This is what I was missing

local success, errormessage = pcall(function()
	DataStore:SetAsync(playerUserId, data)
end)
	
if success then
	print("Data saved")	
else
	print("Error in saving data")
	warn(errormessage)
end
end)

@daslick @Rezzorex

It is able to save tables (yes, the actual table), you dont need to encode and decode anymore, it does it for you and has been for a while now

3 Likes

Hey, you spelled event wrong here. Could that be why it isn’t working? Sorry, I’m new to scripting.

That wouldn’t really make a difference I was just lazy

1 Like

By the way I changed the datastore and it still won’t work.

local DataStoreService = game:GetService("DataStoreService")
local DataStore = DataStoreService:GetDataStore("DataStore") 

game.Players.PlayerAdded:Connect(function(player)
	
	local pointFolder = Instance.new("Folder")
	pointFolder.Name = "pointFolder"
	pointFolder.Parent = player

	
	local points = Instance.new("IntValue")
	points.Name = "Points"
	points.Parent = pointFolder
	
	local swords = Instance.new("Folder")
	swords.Name = "Swords"
	swords.Parent = player
	
	local GoldSword = Instance.new("BoolValue")
	GoldSword.Name = "GoldSword"
	GoldSword.Parent = swords
	
	local EmeraldSword = Instance.new("BoolValue")
	EmeraldSword.Name = "EmeraldSword"
	EmeraldSword.Parent = swords
	
	local AmythestSword = Instance.new("BoolValue")
	AmythestSword.Name = "AmythestSword"
	AmythestSword.Parent = swords
	
	local RubySword = Instance.new("BoolValue")
	RubySword.Name = "RubySword"
	RubySword.Parent = swords
	
	local Sword = Instance.new("BoolValue")
	Sword.Name = "Sword"
	Sword.Parent = swords
	Sword.Value = true
	
	
	player.CharacterAdded:Connect(function(character)
		character.Humanoid.WalkSpeed = 16
		character.Humanoid.Died:Connect(function()
			if character:FindFirstChild("deadTag") then
				character.deadTag:Destroy()
			end
		player:LoadCharacter()
	end)

end)
	
local playerUserId = "Player_"..player.UserId


--Local Data

	
local success, errormessage = pcall(function()
	data = DataStore:GetAsync(playerUserId)
end)
	
if success and data then
		points.Value = data[1]
		RubySword.Value	= data[2]
		EmeraldSword.Value	= data[3]
		AmythestSword.Value	= data[4]
		GoldSword.Value	= data[5]
	--Set the data equal to the current value
else
	print("Data not found")
end
end)

game.Players.PlayerRemoving:Connect(function(player)
local playerUserId = "Player_"..player.UserId

local data = {
		player:WaitForChild("pointFolder").Points.Value;
		player.Swords.RubySword.Value;
		player.Swords.EmeraldSword.Value;
		player.Swords.GoldSword.Value;
		player.Swords.AmythestSword;
}
	
	
local success, errormessage = pcall(function()
	DataStore:SetAsync(playerUserId, data)
end)
	
if success then
	print("Data saved")	
else
	print("Error in saving data")
	warn(errormessage)
end

#1: You forget an end) after the last line

#2: The scope is incorrect - You’re not defining the data variable before you use it to set back the values. The script gets confused on which one to use because you didnt define which one is for getting and which one is for setting. The only time you defined it was on the bottom, you needa create a new one for the pcall to use

[spoiler]tip: Also please use correct indentation so that the code is easier to read, the last part was hard to tell which was which because it wasnt indented right[/spoiler]

So now, try this, it should work

local DataStoreService = game:GetService("DataStoreService")
local DataStore = DataStoreService:GetDataStore("DataStore") 

game.Players.PlayerAdded:Connect(function(player)
	
	local pointFolder = Instance.new("Folder")
	pointFolder.Name = "pointFolder"
	pointFolder.Parent = player

	local points = Instance.new("IntValue")
	points.Name = "Points"
	points.Parent = pointFolder
	
	local swords = Instance.new("Folder")
	swords.Name = "Swords"
	swords.Parent = player
	
	local GoldSword = Instance.new("BoolValue")
	GoldSword.Name = "GoldSword"
	GoldSword.Parent = swords
	
	local EmeraldSword = Instance.new("BoolValue")
	EmeraldSword.Name = "EmeraldSword"
	EmeraldSword.Parent = swords
	
	local AmythestSword = Instance.new("BoolValue")
	AmythestSword.Name = "AmythestSword"
	AmythestSword.Parent = swords
	
	local RubySword = Instance.new("BoolValue")
	RubySword.Name = "RubySword"
	RubySword.Parent = swords
	
	local Sword = Instance.new("BoolValue")
	Sword.Name = "Sword"
	Sword.Parent = swords
	Sword.Value = true
	
	
	player.CharacterAdded:Connect(function(character)
		character.Humanoid.WalkSpeed = 16
		character.Humanoid.Died:Connect(function()
			if character:FindFirstChild("deadTag") then
				character.deadTag:Destroy()
			end
			player:LoadCharacter()
		end)

	end)
	
	local playerUserId = "Player_"..player.UserId
	
	local data -- Make a new variable to use
	local success, errormessage = pcall(function()
		data = DataStore:GetAsync(playerUserId)
	end)
	

	if success and data then
		points.Value = data[1]
		RubySword.Value	= data[2]
		EmeraldSword.Value	= data[3]
		AmythestSword.Value	= data[4]
		GoldSword.Value	= data[5]
	--Set the data equal to the current value
	else
		print("Data not found")
	end
	
end)

game.Players.PlayerRemoving:Connect(function(player)
	local playerUserId = "Player_"..player.UserId

	local data = {
		player:WaitForChild("pointFolder").Points.Value;
		player.Swords.RubySword.Value;
		player.Swords.EmeraldSword.Value;
		player.Swords.GoldSword.Value;
		player.Swords.AmythestSword;
	}
	
	
	local success, errormessage = pcall(function()
		DataStore:SetAsync(playerUserId, data)
	end)
	
	if success then
		print("Data saved")	
	else
		print("Error in saving data")
		warn(errormessage)
	end
end)

In dms I changed up the Data Store, here is the new script. It still doesn’t work :confused:

local HttpService = game:GetService("HttpService") --Simply gets the HttpService
local DataStoreService = game:GetService("DataStoreService")
local DataStore = DataStoreService:GetDataStore("DataStore") 

game.Players.PlayerAdded:Connect(function(player)
	
	local pointFolder = Instance.new("Folder")
	pointFolder.Name = "pointFolder"
	pointFolder.Parent = player

	
	local points = Instance.new("IntValue")
	points.Name = "Points"
	points.Parent = pointFolder
	
	local swords = Instance.new("Folder")
	swords.Name = "Swords"
	swords.Parent = player
	
	local GoldSword = Instance.new("BoolValue")
	GoldSword.Name = "GoldSword"
	GoldSword.Parent = swords
	
	local EmeraldSword = Instance.new("BoolValue")
	EmeraldSword.Name = "EmeraldSword"
	EmeraldSword.Parent = swords
	
	local AmythestSword = Instance.new("BoolValue")
	AmythestSword.Name = "AmythestSword"
	AmythestSword.Parent = swords
	
	local RubySword = Instance.new("BoolValue")
	RubySword.Name = "RubySword"
	RubySword.Parent = swords
	
	local Sword = Instance.new("BoolValue")
	Sword.Name = "Sword"
	Sword.Parent = swords
	Sword.Value = true
	
	
	player.CharacterAdded:Connect(function(character)
		character.Humanoid.WalkSpeed = 16
		character.Humanoid.Died:Connect(function()
			if character:FindFirstChild("deadTag") then
				character.deadTag:Destroy()
			end
		player:LoadCharacter()
	end)

end)
	
local playerUserId = "Player_"..player.UserId


--Local Data

	
local success, errormessage = pcall(function()
	data = DataStore:GetAsync(playerUserId)
end)
	
if data then
	dataTable = HttpService:JSONDecode(data) --Turns the JSON string into a lua table
end
	
if success and data then
		points.Value = dataTable[1]
		RubySword.Value	= dataTable[2]
		EmeraldSword.Value	= dataTable[3]
		AmythestSword.Value	= dataTable[4]
		GoldSword.Value	= dataTable[5]
	--Set the data equal to the current value
else
	print("Data not found")
end
end)

game.Players.PlayerRemoving:Connect(function(player)
local playerUserId = "Player_"..player.UserId

local data = {
		player:WaitForChild("pointFolder").Points.Value;
		player.Swords.RubySword.Value;
		player.Swords.EmeraldSword.Value;
		player.Swords.GoldSword.Value;
		player.Swords.AmythestSword.Value;
}

dataTable = HttpService:JSONEncode(data) --Turns the data table into a JSON string
print(dataTable)
local success, errormessage = pcall(function()
	DataStore:SetAsync(playerUserId, dataTable)
end)
	
if success then
	print("Data saved")	
else
	print("Error in saving data")
	warn(errormessage)
end

end)

what are you using JSONEncode for? You don’t need it. Also, try my script first, it should work with that old version. The new one you sent is unnecessarily complicated

1 Like

Doesn’t seem to work in roblox studio

#1: Try it in game first
#2: Try changing the name of the Datastore

Also, it’s better to use a dictionary to save instead of an array so that you know which value is which

1 Like

Might be because there is no bind to close. Studio is notorious for shutting down before data can save.

2 Likes

Yeah exactly. With datastores when I first started scripting I tried debugging so much just to find out my code was perfectly fine and that it was just studio, lol

2 Likes