Individual part loading from DS

Hey there!

I have made a loading / saving system for parts in my game and have recently run into an issue.

How do i load parts individually with the same name?

I have tested my game and, when i try to load, all the parts go into one of the parts’ locations. How can i make a way to position them individually because they all have the same name?

Here is my loader code:

game.Players.PlayerAdded:Connect(function(player)
	local async = ds:GetAsync(player.UserId)
	
	if async then
		for i,v in pairs(async) do
			local name = tostring(async[7])
			
			print(name)
			local blockFound = game.ServerStorage.Models:WaitForChild("Block")

			if blockFound then
				print("blockfound")
				local clone = blockFound:Clone()

				clone.CFrame = CFrame.new(async[1], async[2], async[3])*CFrame.fromEulerAnglesXYZ(math.rad(tonumber(async[4]) or 0), math.rad(tonumber(async[5]) or 0), math.rad(tonumber(async[6]) or 0))
				clone.Name = "PlacedBlock"
				clone.Parent = workspace.BlocksPlaced
				clone:SetAttribute("Name", tostring(async[7]))
			end
		end
	end
end)
1 Like

I think you could just make a new block with the name that was saved instead of copying a block from ServerStorage, and modyfing it just like you did here.

I’ve just done this, it still loads it in it is just a new part instead of a clone.

Screenshot:

Show me the code you used for that please.

local ds = game:GetService("DataStoreService"):GetDataStore("Build")

local event = game.ReplicatedStorage.DataAdded

game.Players.PlayerAdded:Connect(function(player)
	local async = ds:GetAsync(player.UserId)

	if async then
		for i,v in pairs(async) do
			local name = tostring(async[7])

			print(name)
			
			print("blockfound")
			local clone = Instance.new("Part")

			clone.CFrame = CFrame.new(async[1], async[2], async[3])*CFrame.fromEulerAnglesXYZ(math.rad(tonumber(async[4]) or 0), math.rad(tonumber(async[5]) or 0), math.rad(tonumber(async[6]) or 0))
			clone.Name = "PlacedBlock"
			clone.Parent = workspace.BlocksPlaced
			clone:SetAttribute("Name", tostring(async[7]))
			clone.Anchored = true
			clone.Size = Vector3.new(4,4,4)
		end
	end
end)
1 Like

Does it prints the checks? I don’t see any error in this.

Yeah, everything using the print() function is printed

Then I don’t think I can help with this, unfortunately. I would suggest using pcall() for the data loading, but that’s all I can find.

Ok, thanks for the help! [cap limit]

I don’t quite get what you want to achieve exactly. I understand that async is a table that contains 6 numbers that describe the part CFrame, and a String that represent the name of the attribute Name.
Why are you looping through async here?

for i,v in pairs(async) do

i am trying to get all of the parts included in the async, but i am just seeing if it saves one part or more in the DS

yeah, it saves all of the different parts in the async, sorry for the confusion

Oh and, the data that is saved is:

local pos = {v.Position.X, v.Position.Y, v.Position.Z, v.Orientation.X, v.Orientation.Y, v.Orientation.Z, v:GetAttribute("Name")}

Can you show me how you actually Save the data in the datastore?

local name = tostring(clone:GetAttribute("Name"))

				local pos = {clone.Position.X, clone.Position.Y, clone.Position.Z, clone.Orientation.X, clone.Orientation.Y, clone.Orientation.Z, clone:GetAttribute("Name")}
				
				local packed = ds:GetAsync(player.UserId)
				
				if packed then
					if packed ~= nil then
						table.insert(packed, pos)

						ds:SetAsync(player.UserId, packed)
					end
				else
					ds:SetAsync(player.UserId, pos)
				end

Alright, Your DataStore should save a table of tables (table of parts, each part is defined by a table called pos).

In this case your script should be:

local pos = {clone.Position.X, clone.Position.Y, clone.Position.Z, clone.Orientation.X, clone.Orientation.Y, clone.Orientation.Z, clone:GetAttribute("Name")}

local packed = ds:GetAsync(player.UserId)

if packed then  -- this condition is the same as if packed ~= nil then
    table.insert(packed, pos)
    ds:SetAsync(player.UserId, packed)
else
	packed = {} --If this is the first part that will be saved in the DS, pos should be inserted in an empty table
	table.insert(packed, #packed+1, pos) 
	ds:SetAsync(player.UserId, packed)  -- The dataStore will contain a table that has 1 table which is pos
end

Yeah, my DataStore already has the table of tables, but i don’t know how to make each one unique and how i can change the position of each part to their saved data.

When you’re in the for loop, you should use v, not async:

game.Players.PlayerAdded:Connect(function(player)
	local async = ds:GetAsync(player.UserId)
	
	if async then
		for i,v in pairs(async) do
			local name = tostring(v[7])
			
			print(name)
			local blockFound = game.ServerStorage.Models:WaitForChild("Block")

			if blockFound then
				print("blockfound")
				local clone = blockFound:Clone()

				clone.CFrame = CFrame.new(v[1], v[2], v[3])*CFrame.fromEulerAnglesXYZ(math.rad(tonumber(v[4]) or 0), math.rad(tonumber(v[5]) or 0), math.rad(tonumber(v[6]) or 0))
				clone.Name = "PlacedBlock"
				clone.Parent = workspace.BlocksPlaced
				clone:SetAttribute("Name", tostring(v[7]))
			end
		end
	end
end)

Also, I don’t think you should clone the part from ServerStorage. Creating the part using Instance.new(“Part”) is a better and more efficient solution.

I’ve done this and i’ve got the error

ServerScriptService.Loader:10: attempt to index number with number 

i am just investigating this

Can you just print(async) ?
I want to see what it has in it.