How do I make a plot saving system like Lumber Tycoon 2 or Oaklands?

I want to make a plot system where when a player joins the game, they will have a starter plot with a few parts in it as showed in the picture below, when the player go to leave the game the script will gather the following information from each part, (BrickColor, Size, Material, Position, Orientation). And when the player joins back to the game the parts will load back in. Also I want to be able to add other parts to the plot in game.

I want something exactly like they do in Lumber Tycoon 2 or OakLands!

And no this game is not copying any other games!!!

So here is a list of what I need:
– Starter Plots with a few parts
– A new part can be added to the plot
– Save plot when player leaves including all parts and their properties on it.
– Load the players plot when they join back in.

Starter Plot Picture:

The script for the saving System:

local DataStoreService = game:GetService("DataStoreService")
local dataStore = DataStoreService:GetDataStore("CharacterPlots")

local function serializePart(part)
	local properties = {
		Orientation = tostring(part.Orientation),
		Position = tostring(part.Position),
		Material = tostring(part.Material),
		Transparency = tostring(part.Transparency),
		BrickColor = tostring(part.BrickColor),
		Size = tostring(part.Size)
	}
	return properties
end

local function saveCharacterPlot(player, folder)
	local characterData = {}

	for _, part in ipairs(folder:GetDescendants()) do
		if part:IsA("BasePart") then
			characterData[part.Name] = serializePart(part)
		end
	end

	dataStore:SetAsync(player.UserId, characterData)
end

local function loadCharacterPlot(player, folder)
	local characterData = dataStore:GetAsync(player.UserId)

	if characterData then
		for partName, properties in pairs(characterData) do
			local part = folder:FindFirstChild(partName)

			if part and part:IsA("BasePart") then
				part.Orientation = Vector3.new(properties.Orientation)
				part.Position = Vector3.new(properties.Position)
				part.Material = Enum.Material[properties.Material]
				part.Transparency = tonumber(properties.Transparency)
				part.BrickColor = BrickColor.new(properties.BrickColor)
				part.Size = Vector3.new(properties.Size)
			end
		end
	end
end

game.Players.PlayerRemoving:Connect(function(player)
	local character = player.Character
	local folder = player.Character:FindFirstChild("PlotFolder")

	if folder then
		saveCharacterPlot(player, folder)
	end
end)

game.Players.PlayerAdded:Connect(function(player)
	local character = player.Character
	local folder = player.Character:FindFirstChild("PlotFolder")

	if folder then
		loadCharacterPlot(player, folder)
	end
end)

Picture of the Workspace:

I cant provide code, but I would assume its just have a folder with everything that can be placed. and then save it and its properties as a table. then loop through this table on join. and spawn items with they’re respective properties.