Somehow datastore is trying to save an array

Hello developers! I am currently working on build mode for my game, Bloxy Kart. I am currently figuring out how to save and load models. I am getting this error:
image

Here is the script that is handling the saving:

local players = game:GetService("Players")
local dataStoreService = game:GetService("DataStoreService")
local dataStore1 = dataStoreService:GetDataStore("BuildModeData_Testers1")

local plot = workspace.base.itemHolder

local function getColor(obj)
	local allPartOneColor
	for _, color in pairs(obj:GetDescendants()) do
		if color:IsA("BasePart") then
			if color.Color == obj.PrimaryPart.Color then
				allPartOneColor = true
			elseif not color.Color == obj.PrimaryPart.Color then
				allPartOneColor = false
				return false
			end
		end
	end
	return allPartOneColor
end

local function getMaterial(obj)
	local allPartOneMaterial
	for _, Material in pairs(obj:GetDescendants()) do
		if Material:IsA("BasePart") then
			if Material.Material == obj.PrimaryPart.Material then
				allPartOneMaterial = true
			elseif not Material.Material == obj.PrimaryPart.Material then
				allPartOneMaterial = false
				return false
			end
		end
	end
	return allPartOneMaterial
end

local function Save(plr, plotNumber)
	local key = plotNumber.."_"..plr.UserId

	local save = {}

	for i, obj in pairs(plot:GetChildren()) do
		if obj then
			local tab = {

				["Name"] = obj.Name,
				["CFS"] = {
					["X"] = plot.Parent.CFrame:ToObjectSpace(CFrame.new(obj.PrimaryPart.CFrame.p)).X;
					["Y"] = plot.Parent.CFrame:ToObjectSpace(CFrame.new(obj.PrimaryPart.CFrame.p)).Y;
					["Z"] = plot.Parent.CFrame:ToObjectSpace(CFrame.new(obj.PrimaryPart.CFrame.p)).Z;

					["R"] = obj.PrimaryPart.Orientation.Y

				},
				["Color"] = nil,
				["Material"] = nil
			}
			local allPartOneColor = getColor(obj)
			local allPartOneMaterial = getMaterial(obj)
			if allPartOneColor then
				tab.Color = {
					Red = obj.PrimaryPart.Color.R,
					Green = obj.PrimaryPart.Color.G,
					Blue = obj.PrimaryPart.Color.B,
				}
			end
			if allPartOneMaterial then
				tab.Material = obj.PrimaryPart.Material
			end
			print(tab.Color, tab.Material)
			print(allPartOneColor, allPartOneMaterial)
			table.insert(save, tab)
		end
	end
	
	print(save)

	local success, err = pcall(function()
		dataStore1:SetAsync(key, save)
	end)

	if not success then
		warn("Failed to overwrite data: "..tostring(err))
	end
end

local function Load(plr, plotNumber)
	wait(1)

	local key = plotNumber.."_"..plr.UserId

	local savedData

	local success, err = pcall(function()
		savedData = dataStore1:GetAsync(key)
	end)

	if not success then
		warn("Failed to save data: "..tostring(err))
		return
	end

	if savedData then
		for i, data in pairs(savedData) do
			if data then
				local serializedModel = game.ReplicatedStorage.models:FindFirstChild(data.Name):Clone()
				if serializedModel then
					serializedModel.PrimaryPart.Transparency = 1

					serializedModel:SetPrimaryPartCFrame(plot.Parent.CFrame * CFrame.new(data.CFS.X, data.CFS.Y, data.CFS.Z) * CFrame.Angles(0, math.rad(data.CFS.R), 0))
					
					print(data.Color)
					print(data.Material)
					
					if data.Color ~= nil then
						for _, color in pairs(serializedModel:GetDescendants()) do
							if color:IsA("BasePart") then
								color.Color = Color3.fromRGB(data.Color.R, data.Color.G, data.Color.B)
							end
						end
					end
					if data.Material ~= nil then
						for _, Material in pairs(serializedModel:GetDescendants()) do
							if Material:IsA("BasePart") then
								Material.Material = data.Material
							end
						end
					end

					serializedModel.Parent = plot
				end
			end
		end
	end
end

game.ReplicatedStorage.remotes.Save.OnServerEvent:Connect(Save)
game.ReplicatedStorage.remotes.Load.OnServerEvent:Connect(Load)

I hope you can help. Thanks for reading! WE

You can’t save CFrames to Datastore. I do feel like the error is misleading a bit because it rather refers to unsupported types of data found then it being an array (but not fully misleading because it says it accepts only UTF8 characters) but just know you can’t save userdata values. Anything that is a value constructor like Vector3, Vector2, UDim2 will be userdata.

Serialization is required if you must save CFrames, meaning to convert the data into something you can save and load from.

It worked before, we just tried to add colors and materials to the saving.

1 Like

Because you’re saving individual values from the color RGB values which is basically serializing it and for Material, it probably fetched the Enum’s value or name instead of the Enum itself.

(I can’t test anything out so I’m just helping you here with what I know)