Data store block problem

Hello,

I’m trying to make a other datastoreservice script

but this time I’m trying to save parts position and size, I’ve gotten the size and position kinda right but its not putting it in the right position and its only doing it for 1 part and theres 4

what I was trying to do was make it so it would pretty much close the blocks and put them there, for like a building game save system so heres the script

local data_store_service = game:GetService("DataStoreService")
local work_space = game:GetService("Workspace")

local block_data = data_store_service:GetDataStore("block_data")

local blocks_folder = work_space:WaitForChild("sem")

function load_blocks()
	
	local function string_to_vector(string_value: string)
		local split = string_value:split(",", "")
		return Vector3.new(split[1], split[2], split[3])
	end
	
	local saved_block_data = block_data:GetAsync("blocks_data")
	
	if saved_block_data then
	
		if typeof(saved_block_data) == "table" then
			for _, v in pairs(saved_block_data) do
				local new_part = Instance.new("Part")
				new_part.Parent = work_space
				
				if _ == "string_size" then
					local size_for_part = string_to_vector(v)
					new_part.Size = size_for_part
				end
				
				if _ == "string_position" then
					local position_for_part = string_to_vector(v)
					new_part.Position = position_for_part
				end
				
			end
		end
	
	end
	
end

function save_blocks()
	
	local function vector_to_string(postition)
		return tostring(postition.X)..","..tostring(postition.Y)..","..tostring(postition.Z)
	end
	
	local block_table = {}
	
	for _, v in pairs(blocks_folder:GetChildren()) do
		if v:IsA("BasePart") then
			
			local size_from_part = v.Size
			local position_from_part = v.Position
			
			local string_vector = vector_to_string(position_from_part)
			local string_size = vector_to_string(size_from_part)
			
			block_table = {
				string_size = string_size,
				string_position = string_vector
			}
			
		end
		
	end
	
	print("saved data")

	block_data:SetAsync("blocks_data",block_table)
	
end


game:BindToClose(save_blocks)

load_blocks()

You’re overwriting block_table with a single serialization, not inserting each individual serialization to make an array.

Change:

block_table = {
    string_size = string_size,
    string_position = string_vector
}

To:

table.insert(block_table, {
    string_size = string_size,
    string_position = string_vector
})

I didn’t know you could do table.insert with a other table. I did that and now it saves the amount of parts but not the size/position

It looks like you are saving a matrix and then loading it like a single table. In the load function, change this:

if _ == "string_size" then
	local size_for_part = string_to_vector(v)
	new_part.Size = size_for_part
end
				
if _ == "string_position" then
	local position_for_part = string_to_vector(v)
	new_part.Position = position_for_part
end

to this:

local size_for_part = string_to_vector(v.string_size)
new_part.Size = size_for_part
				
local position_for_part = string_to_vector(v.string_vector)
new_part.Position = position_for_part

I changed it to those and now it’s getting this error.

ServerScriptService.Script:11: attempt to index nil with 'split'

Note:

I changed the save_blocks table to this

	table.insert(block_table, {
		string_size = string_size,
		string_position = string_vector
	})

maybe change v.string_size to v["string_size"] (same thing with string_position). If that doesn’t work, maybe try doing some debug pring statements to see what is actually getting loaded and split.

So, it’s printing 5, 5, 5 that’s size, then nil. so, it must be the table part that’s messing it up.

Sorry, just got messed up in the variables, change v.string_vector to v.string_position

1 Like

That worked. Thank you.

working script for others that run into this problem.

local data_store_service = game:GetService("DataStoreService")
local work_space = game:GetService("Workspace")

local block_data = data_store_service:GetDataStore("block_data")

local blocks_folder = work_space:WaitForChild("sem")

function load_blocks()
	
	local function string_to_vector(string_value: string)
		local split = string_value:split(",", "")
		return Vector3.new(split[1], split[2], split[3])
	end
	
	local saved_block_data = block_data:GetAsync("blocks_data")
	
	if saved_block_data then
	
		if typeof(saved_block_data) == "table" then
			
			for _, v in pairs(saved_block_data) do
				local new_part = Instance.new("Part")
				new_part.Parent = work_space
				
				local size_for_part = string_to_vector(v["string_size"])
				new_part.Size = size_for_part

				local position_for_part = string_to_vector(v["string_position"])
				new_part.Position = position_for_part
				
			end
		end
	
	end
	
end

function save_blocks()
	
	local function vector_to_string(postition)
		return tostring(postition.X)..","..tostring(postition.Y)..","..tostring(postition.Z)
	end
	
	local block_table = {}
	
	for _, v in pairs(blocks_folder:GetChildren()) do
		if v:IsA("BasePart") then
			
			local size_from_part = v.Size
			local position_from_part = v.Position
			
			local string_vector = vector_to_string(position_from_part)
			local string_size = vector_to_string(size_from_part)
			
			table.insert(block_table, {
				string_size = string_size,
				string_position = string_vector
			})
			
		end
		
	end
	
	print("saved data")

	block_data:SetAsync("blocks_data",block_table)
	
end


game:BindToClose(save_blocks)

load_blocks()
1 Like

I cleaned up and simplified the code for you:

--!strict
local DataStoreService = game:GetService("DataStoreService")


local BlocksData = DataStoreService:GetDataStore("Blocks", "v1.0.0")
local Blocks     = workspace.sem



local function serializeVector3CSV(vector3: Vector3): string
	local axes = {
		vector3.X,
		vector3.Y,
		vector3.Z
	}
	
	return table.concat(axes, ",")
end

local function deserializeVector3CSV(csv: string): Vector3
	local axes = string.split(csv, ",") :: any
	
	return Vector3.new(table.unpack(axes))
end

local function loadBlocks()
	local serializedBlocks = BlocksData:GetAsync("Blocks")
	if not serializedBlocks then
		return
	end
	
	for _, data in serializedBlocks do
		local block = Instance.new("Part")
		block.Position = deserializeVector3CSV(data.Position)
		block.Size     = deserializeVector3CSV(data.Size)
		block.Parent   = Blocks
	end
end

local function saveBlocks()
	local serializedBlocks = {}
	
	for _, block in Blocks:GetChildren() do
		local data = {}
		data.Position = serializeVector3CSV(block.Position)
		data.Size     = serializeVector3CSV(block.Size)

		table.insert(serializedBlocks, data)
	end
	
	BlocksData:SetAsync("Blocks", serializedBlocks)
end



loadBlocks()

game:BindToClose(saveBlocks)

Looks nice, but when I tried it, it got a error

ServerScriptService.Script:27: attempt to iterate over a nil value

Ah, I switched out the data-stores. This would lead to an empty database, which cannot be iterated over. I adjusted the code to account for this

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.