Datastore doesn't save the table but no errors

  1. What do you want to achieve? I want to fix a script that doesn’t work.

  2. What is the issue? I tried to save multiple values into a table but they don’t save.

  3. What solutions have you tried so far? I see that when I reset my character the values are still there saved but when I rejoin that is when the values in the folder are not turned on as last time.

If someone could find the reason I have this problem it would be great. I don’t know if its from the script so if you find the problem in the script tell me what change I should do! :slight_smile:

local players = game:GetService("Players")
local dataStore = game:GetService("DataStoreService")
local CarDataStore1 = dataStore:GetDataStore("VehicleDataStore0")

local defaultCarOwnership = {
	["2020BloxWagenGulf"] = false,
	["1983PIATDOS"] = false,
	["2020TacoCarry"] = false,
	["2015PiatHundred"] = false,
	["2003JacuzziRS4"] = false,
	["2020TokenModelIII(Uncustomizable)"] = false,
	["1997ToySupra"] = false,
	["2008BAM320Y"] = false,
}

function setCarOwnership(player, carName, ownership)
	local folder = player:FindFirstChild("OwnedCars")
	if not folder then
		folder = Instance.new("Folder")
		folder.Name = "OwnedCars"
		folder.Parent = player
		end

	local car = folder:FindFirstChild(carName)
	if not car then
		car = Instance.new("BoolValue")
		car.Name = carName
		car.Parent = folder
	end

	car.Value = ownership
	CarDataStore1:SetAsync(player.UserId .. "_" .. carName, ownership)
	end

function getCarOwnership(player, carName)
	local folder = player:FindFirstChild("OwnedCars")
	if not folder then
		return defaultCarOwnership[carName]
	end

	local car = folder:FindFirstChild(carName)
	if not car then
		return defaultCarOwnership[carName]
	end

	local value = CarDataStore1:GetAsync(player.UserId .. "_" .. carName)
	if value ~= nil then
		return value
	else
		return car.Value
	end
end

players.PlayerAdded:Connect(function(player)
	for carName, defaultOwnership in pairs(defaultCarOwnership) do
		local ownership = getCarOwnership(player, carName)
		setCarOwnership(player, carName, ownership)
	end
end)

for _, player in ipairs(players:GetPlayers()) do
	for carName, defaultOwnership in pairs(defaultCarOwnership) do
		local ownership = getCarOwnership(player, carName)
		setCarOwnership(player, carName, ownership)
	end
end

players.PlayerRemoving:Connect(function(player)
	CarDataStore1:RemoveAsync(player.UserId)
end)

game:BindToClose(function()
	for _, player in ipairs(players:GetPlayers()) do
		CarDataStore1:SetAsync(player.UserId, nil)
	end
end)

When you rejoin DataStore values are not there?
But, you actually stated that behaviour in the script by adding these:

players.PlayerRemoving:Connect(function(player)
	CarDataStore1:RemoveAsync(player.UserId)
end)

game:BindToClose(function()
	for _, player in ipairs(players:GetPlayers()) do
		CarDataStore1:SetAsync(player.UserId, nil)
	end
end)

When PlayerRemoving occurs you are using RemoveAsync() to delete the DataStore entry, and when game shutdown you are turning the DataStore of the player to nil.
So you are deleting the data when player leaves and when server shutdown

Well I didn’t make this script myself so I don’t really know… I am not really that good in scripting and I am still learning and this is something that I tried to do with the help of internet.

Should I change removeasync with setasync?

well, you can remove it completely cause seems you are already saving the DataStore value at midGame when using the car functions, perhaps you want to only save when player leaves. Its your desition.
The thing is, do not use RemoveAsync or SetAsync the player data with nil, thats why the issue occurs, cause you are deleting the data.

I removed them completely but its still not saving and I don’t understand why. What am I doing wrong?

Its complicated to point out where is the exact issue without analizing the script carefully, by quick reading I find many bad practices like doing a DataStore check constantly on a loop, using the car table to constantly read dataStore. Which is totally wrong and will cause the dataStore service to get “clogged”

I understand that you are learning, probably you should rebuild some parts of the script to use a better approach, its useful for learning more!

Whats exactly the behaviour you want?
Players while inGame selects a car, and its saved on a DataStore per player, next time they join they can see that saved DataStore values? By having a folder in their player instance, with boolValues to indicate what they own?

Yeah. Basically if someone buys the car the value of the vehicle that its in the ownedcars folder of the player its enabled and he can spawn it.

The problem is when you rejoin the values aren’t enabled anymore and it doesn’t save anything.

Yup, I understand the problem, I just wanted to know what you are exactly looking for to help you.

First, when PlayerAdded do only one call to DataStore to read it GetAsync(), that DSS will contain all the cars that the player has as table made of names/strings {“CarName1”, “FlyingCar”, “BananaCar” }

Pass that table to a function that will create the folder and will iterate that table gotten to create a value and place it in the player folder. If datastore doesnt exist (first time player) just create all values to false or empty as you wish.

When player leaves, read the player folder, iterate on each value, place them on a table that will look like this: {“CarName1”, “FlyingCar”, “BananaCar” }
And you only do a SetAsync to DSS to save that table into the player’s dss.

I will try to send you a basic example in a few minutes, you could try to start experimenting with the steps I told you :yum:

This is a basic example.
It only loads once when player joins and create the folder and values based on the player’s DSS. Only one DSS per player, not per car as it was before.

It only saves once, when the player leaves or when server shutdown.

It has pcalls now, to handle errors, but I did not add DSS retries for this basic example to keep it simple, but adding retries is recommended cause DSS fails sometimes.

local players = game:GetService("Players")
local dataStore = game:GetService("DataStoreService")
local CarDataStore1 = dataStore:GetDataStore("DSS_Vehicle_01")

local defaultCarOwnership = {
	["2020BloxWagenGulf"] = false,
	["1983PIATDOS"] = false,
	["2020TacoCarry"] = false,
	["2015PiatHundred"] = false,
	["2003JacuzziRS4"] = false,
	["2020TokenModelIII(Uncustomizable)"] = false,
	["1997ToySupra"] = false,
	["2008BAM320Y"] = false,
}

-- POPULATE DATA IN PLAYER
local function PopulatePlayerFolder(player, data)
	warn("Populating player...")
	local folder = Instance.new("Folder")
	folder.Name = "OwnedCars"
	folder.Parent = player

	-- Iterate players gotten data to create values in player folder or default data if new player
	for carName, val in pairs(defaultCarOwnership) do
		local car = Instance.new("BoolValue")
		car.Name = carName
		car.Parent = folder
		car.Value = val

		if data then
			if table.find(data, carName) then
				car.Value = true
			end
		end

		print("BoolValue created:", carName, car.Value)
	end
end

-- JOIN EVENT
players.PlayerAdded:Connect(function(player)
	warn("Reading DSS of", player)
	local succ, data = pcall(function()
		return CarDataStore1:GetAsync(player.UserId)
	end)
	
	if succ then
		if data then
			warn("Player has previous Data", player)
			PopulatePlayerFolder(player, data)
		else
			warn("New Player", player)
			PopulatePlayerFolder(player, data)
		end
	end	
end)

-- SAVE DATA FUNCTION
local function SaveData(player)
	local folder = player:FindFirstChild("OwnedCars")
	if folder then
		local Table2Save = {}
		for _, carVal in pairs(folder:GetChildren()) do
			if carVal:IsA("BoolValue") then
				if carVal.Value then
					table.insert(Table2Save, carVal.Name)	
				end
			end
		end
		warn("table to save created:")
		print(Table2Save)
		local succ, err = pcall(function()
			return CarDataStore1:SetAsync(player.UserId, Table2Save)
		end)
		if succ then
			warn("data saved for", player)
		else
			warn("DSS failed to save", err)
		end
	end
end

-- LEAVE EVENT
players.PlayerRemoving:Connect(function(player)
	SaveData(player)
end)

-- CLOSE GAME EVENT
game:BindToClose(function()
	for _, player in pairs(players:GetPlayers()) do
		SaveData(player)
	end
end)

Make sure you check output, this is what I see after “purchasing” 3 cars and I rejoined after that (those 3 are true):
image
Only those 3 are true, while all other ones are false:

Its only saving the names of the cars that I own, not the others, cause false cars are not needed to be saved watch output:
image

1 Like

Thank you so much for helping me! Now its working perfectly!

1 Like

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