DataStore using for i, v in pairs help

So, I have a DataStore Script that DataStores the Transparency property of Parts in my game.

This is the important section of the Script

local DataStoreService = game:GetService("DataStoreService")
local dataStore = DataStoreService:GetDataStore("WhateverDataStore")
local partsFolder = workspace.PartsFolder

local function getTable()
	
	for i, v in pairs(partsFolder:GetChildren()) do
		
		if v:IsA("Part") and v.Name == "Part" then
			local PropertiesTable = {
				v.Transparency
			}
			
			return PropertiesTable
		end
	end
end

local function saveData(player)
	
	local success, errorMsg = pcall(function()
		
		dataStore:SetAsync(player.UserId, getTable())
		
	end)
	
	if success then
		
		print("Data has been saved!")
		
	else
		
		print("Data has not been saved!")
		warn(errorMsg)
		
	end
end

game.Players.PlayerAdded:Connect(function(player)
	
	local data
	
	local success, errorMsg = pcall(function()
		
		data = dataStore:GetAsync(player.UserId)
		
	end)
	
	if success and data then
		
		for i, v in pairs(workspace:GetDescendants()) do
			if v:IsA("Part") and v.Name == "Part" then
				v.Transparency = data[1]
			end
		end
		
	else
		
		print("The player has no data!")
		
	end
	
end)

It does not DataStore Transparency property unless all of the parts’ transparency was changed, because apparently v refers to all of the parts.

It would be really messy to define every part in the game and DataStore them one by one.

How can I DataStore each part’s transparency property using for i, v in pairs?

1 Like

DataStores have some limitations that could make this a bit difficult for you depending on how you have your parts set up. The only way I can come up with to pull what you want to achieve off is to store either a parts index or name as a key in a table and assign its transparency as the value respectively. In your case an implementation of that would look like this:

local DataStoreService = game:GetService("DataStoreService")
local dataStore = DataStoreService:GetDataStore("WhateverDataStore")
local partsFolder = workspace.PartsFolder

local function getTable()

    local PropertiesTable = {}
	
	for i, v in pairs(partsFolder:GetChildren()) do
		
		if v:IsA("Part") and v.Name == "Part" then
			
			PropertiesTable[v.Name] = v.Transparency 
            --Or alternatively: PropertiesTable[i] = v.Transparency 

		end
	end

    return PropertiesTable
end

local function saveData(player)
	
	local success, errorMsg = pcall(function()
		
		dataStore:SetAsync(player.UserId, getTable())
		
	end)
	
	if success then
		
		print("Data has been saved!")
		
	else
		
		print("Data has not been saved!")
		warn(errorMsg)
		
	end
end

game.Players.PlayerAdded:Connect(function(player)
	
	local data
	
	local success, errorMsg = pcall(function()
		
		data = dataStore:GetAsync(player.UserId)
		
	end)
	
	if success and data then
		
		for i, v in pairs(workspace:GetDescendants()) do
			if v:IsA("Part") and v.Name == "Part" then
				v.Transparency = data[v.Name] --Or alternatively data[i]
			end
		end
		
	else
		
		print("The player has no data!")
		
	end
	
end)

Both of these methods have drawbacks however. Using the index requires that the order of parts doesn’t change between saving and loading. Using the name to save a part transparencies requires that each part has to have a different name. Generally speaking you need each part to be identifiable across sessions so you can tell which part has what transparency when loading.

1 Like

Did you actually use a pleyer removing event to call the function?

1 Like

Would it be a bad practice to define every part and set their transparencies? I have 100 parts, which means 100 variables.

Yes.

What’s the problem in that?

Nothing, was just making sure because it felt like your script was incomplete.

1 Like

It’s complete, but I posted the important section of it.

Depends on the bigger picture. What exactly are you using this script for?

1 Like

Well, it’s like a Find The game. When the player clicks the Part, its transparency and other properties change.

So I want to change its transparency as some kind of a progress save, and DataStore it as well.

Okay some questions:

First, do you want every part’s transparency to be changed on the server whenever any client joins with different data? Because this will affect everyone.

Second, your datastore should be changing the transparency property for all the parts as soon as a player has joined. Atleast, from the code it looks like it should be doing that.

However, it will only chnage the part’s transparency whenever a player is added it seems.

Side thing, you don’t need to use pairs to loop through tables anymore. Simply just use “in”.

Edit: First question seems kind of answered by your reply.

You should utilize an attribute after the data has loaded in for the client so that you can use it later for stuff like clicking on parts:

if success and data then
		
		for i, v in pairs(workspace:GetDescendants()) do
			if v:IsA("Part") and v.Name == "Part" then
player:SetAttribute("PartData", data[1])
				v.Transparency = data[1]
			end
		end
-- Example of your clicking part thing
local cd = workspace.Part.ClickDetector

cd..MouseClick:Connect(function(plr)
local data = plr:GetAttribute("PartData")
workspace.Part.Transparency = data

I wouldn’t recommend sending too many getasync/setasync requests, since they actually have limits. Only ever use getasync/setasync when the player has joined and leaved. You usually always have an option to use some sort of other method.

It doesn’t. It will change when a player clicks on a part. I have another script that implements how the Parts are collected.

Then it’s probably not to do with the data system itself, can you print the data variable just in case to see whats contained?

â–Ľ {
[1] = 0
}
‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎

Yeah than it’s definitely to do with another script like your part collecting system.

And remember, like I said earlier. Only use getasync/setasync sparingly.

1 Like

I will :+1:

Guess I’ll have to define every part and set their transparencies then.

Thanks for your help also!