Blocks Data Store

Hello! I am making a building system where the blocks you’ve placed will save, but the Data Store doesn’t work and I don’t know why.

local _L = {}

local DataStoreService = game:GetService("DataStoreService")
local BlocksDataStore = DataStoreService:GetDataStore("BlocksDataStore")

function _L.Call()
	game.Players.PlayerAdded:Connect(function(player)
		_L.Load(player)
	end)
	
	game.Players.PlayerRemoving:Connect(function(player)
		_L.Save(player)
	end)
end

function _L.Load(player)
	local playerBlocks = Instance.new("Folder", workspace)
	playerBlocks.Name = tostring(player.Name).."_blocks"
	
	local userid = player.UserId
	
	local success, err = pcall(function()
		BlocksDataStore:GetAsync(userid)
	end)
	
	if success then
		while true do
			for i, v in pairs(playerBlocks:GetChildren()) do
				v.Parent = playerBlocks
			end
			wait(3)
		end
	end
end

function _L.Save(player)
	local userid = player.UserId
	
	local data = {}
	while true do
		for i, v in ipairs(workspace:FindFirstChild(player.Name.."_blocks"):GetChildren()) do
			table.insert(data, {Pos = v.Position, Orientation = v.Orientation})
		end
		wait(3)
	end
	
	local success = pcall(function()
		BlocksDataStore:SetAsync(userid, data)
	end)
end

return _L

You should just create the Load() function before the Call() function.

It doesn’t work, because it’s the same thing.

You should define a function first when you’re creating a function that gonna need that function. Also, you just only load the blocks in workspace, and not setting their position and orientation.

It’s in a module script so I don’t need to define the function first when I am creating a function that’s going to need that function.

Dude. The script reads the function, the problem is in the data store.

So then did you try to print out what the data loaded?

yes, and it says that the table is nil

Pretty sure Datastore doesn’t support Vector3 values. From what I recall I had to save the X,Y,Z individually

Hope this helps

DataStores can only store primitive value types which are native to the Lua language, not instance values. Think tables, strings, numbers etc.

Is the problem in this section. Seems to me you are not using the result of the GetAsync call, I think you need either a return before BlocksDataStore:GetAsync(userid) or just remove the function wrapper around it. As it is I don’t think err will be populated with the data you expect.

Ok, so how can I save them then?

Save position & orientation of blocks by saving their individual X, Y & Z components separately, like this:

local partTable = {part.Position.X, part.Position.Y, part.Position.Z, part.Orientation.X, part.Orientation.Y, part.Orientation.Z}

Those components are number (double precision floating point) numbers and as such they can be stored within a table which is then stored inside the DataStore.

So this is the updated script, but it still doesn’t work!

local _L = {}

local DataStoreService = game:GetService("DataStoreService")
local BlocksDataStore = DataStoreService:GetDataStore("BlocksDataStore")

function _L.Call()
	game.Players.PlayerAdded:Connect(function(player)
		_L.Load(player)
	end)
	
	game.Players.PlayerRemoving:Connect(function(player)
		_L.Save(player)
	end)
end

function _L.Load(player)
	local playerBlocks = Instance.new("Folder", workspace)
	playerBlocks.Name = tostring(player.Name).."_blocks"
	
	
	local data = {}
	game.ReplicatedStorage.Events.Add.Event:Connect(function(posX, posY, posZ, oY, oX, oZ)
		table.insert(data, {PosX = posX, PosY = posY, PosZ = posZ, OX = oX, OY = oY, OZ = oZ})
	end)

	local userid = player.UserId
	
	BlocksDataStore:GetAsync(userid)

	if data then
		for i, v in pairs(playerBlocks:GetChildren()) do
			v.Parent = playerBlocks
			v.Postion.X = data[v].PosX
			v.Postion.Y = data[v].PosY
			v.Postion.Z = data[v].PosZ
			
			v.Orientation.X = data[v].OX
			v.Orientation.Y = data[v].OY
			v.Orientation.X = data[v].OZ
		end
		
		while true do
			print(data)
			wait(5)
		end
	end
end

function _L.Save(player)
	local userid = player.UserId

	local data = {}
	game.ReplicatedStorage.Events.Add.Event:Connect(function(posX, posY, posZ, oY, oX, oZ)
		table.insert(data, {PosX = posX, PosY = posY, PosZ = posZ, OX = oX, OY = oY, OZ = oZ})
	end)
	
	workspace:FindFirstChild(tostring(player.Name).."_blocks"):Destroy()
	
	local success = pcall(function()
		BlocksDataStore:SetAsync(userid, data)
	end)
end

return _L

Use instancestore module, it saves all type of classes objects accept for unions.

You can’t store the parent like that either since the property “Parent” is a reference to an instance.

So how can I save the parent then?

As a string value (use its name).

Can you give me an example please.

part.Parent.Name

Would be how you get an instance’s parents name.