For loop isn't spawning parts as intended

For the last couple of days I have been working on a function that converts saved bunker data to a model.

However when I test run the function it doesn’t ever load the data correctly.

I have tried arranging the for loop differently (making one for loop that changes each property, and different for loops for each property) but it would always result in an incorrect number of parts, incorrectly named parts or incorrectly positioned parts.

also sorry incapaxx i didn’t use get service

Resources:

ServerScript:

local DataStore2 = require(1936396537)
local ServerStorage = game.ServerStorage
local Workspace = game.Workspace 
local Players = game.Players
local default omega_coins = 0
local default_likes = 0
local default_wins = 0
local default_bunker_terrain_position = {CFrame.new(26.927, -33.383, -435.507), CFrame.new(26.927, 23.365, -572.788), CFrame.new(164.479, 23.365, -434.153), 
CFrame.new(-110.625, 23.365, -435.236), CFrame.new(25.844, 23.365, -297.955)}
local default_bunker_terrain_size = {Vector3.new(277.27, 8.143, 277.27), Vector3.new(277.27, 108.309, 2.708),Vector3.new(2.166, 108.309, 274.562),Vector3.new(2.166, 108.309, 272.396),Vector3.new(275.104, 108.309, 2.166)}
local default_bunker_materials = {"Mud","Rock","Rock","Rock","Rock"}




Players.PlayerAdded:Connect(function(plr)
	local pointsDataStore = DataStore2("Ωmega Coins",plr)
	
	local leaderstats = Instance.new("Folder",plr) ---leaderstats folder
	leaderstats.Name = "leaderstats"
	
	
	local wins = Instance.new("IntValue",leaderstats)  --leaderstats
	wins.Name = "Wins"
	
	local omega_coins = Instance.new("IntValue",leaderstats)
	omega_coins.Name = "Ωmega $"
	
	local likes = Instance.new("IntValue",leaderstats)
	likes.Name = "Likes"
end)

function save_to_model(folder_name, target_location, xoffset, yoffset, zoffset)
ServerStorage.empty_map:Clone()
ServerStorage.empty_map.Name = folder_name
ServerStorage[folder_name].Parent = Workspace
local terrain = Workspace[folder_name].terrain:WaitForChild("cubes")
	
	for i, v in pairs(default_bunker_materials) do
		Instance.new("Part",terrain)
	end
	for i, v in pairs(default_bunker_terrain_size) do
		terrain.Part. Size = v
	end
	for i, v in pairs(default_bunker_terrain_position) do
		terrain.Part.CFrame = v
	end
	for i, v in pairs(default_bunker_materials) do
		terrain.Part.Name = v
	end
end

save_to_model("MrGuyROBLOX's Dungeon", game.Workspace.maps,0,0,0)

Explanation of my map format:
image

1 Like

Yes this is because in your loops you are inserting a part (with no reference) and then calling on it’s parent to change properties within different loops. Here’s a better understanding. You create 5 parts patented to terrain. All these parts are named “Part”. You then create a loop for each of the default bunker properties which sets terrain.Part (terrain.Part could be anyone of the 5 parts you created above) property (say size here) to the value of the last item in the size table (since you iterated though the whole table)

I still don’t have a full understanding of what you are trying to do.
A screenshot of what you are trying to accomplish and what you are running into would help

2 Likes

I need to make 2 functions that convert arrays to parts and vice versa. I’m going to make the game load a bunker on startup, which is whatever is saved for the player, or the default bunker (which is supposed to represent the construction of a new player’s bunker) if there is no data found

. After the player selects play, they are given a starter bunker which has actual stuff in it which I will be able to program when I get the starter bunker code working. Also this starter bunker shown is just an unused map btw.

1 Like

Updated my script and now it is saying it wants a string not an object

	for i, v in pairs(default_bunker_materials) do
		Instance.new("Part",terrain)
		terrain.Part.Name = v
		local part = terrain[v]
		for i, v in pairs(default_bunker_terrain_position) do
			terrain[part].CFrame = v -- expects a string but i'm trying to reference the part.
		end
		for i, v in pairs(default_bunker_terrain_size) do
			terrain[part].Size = v
		end
		
	end
end
1 Like

You could probably just index each of your arrays with the index already provided from default_bunker_materials:

for i, v in pairs(default_bunker_materials) do
	local part = Instance.new("Part")
	part.Name = v

	-- new block:
	part.CFrame = default_bunker_terrain_position[i]
	part.Size = default_bunker_terrain_size[i]

	part.Parent = terrain
end

If you are wondering why I left out the parent argument from your Instance.new("Part"):

If this works, why this works

Whenever you use an array, you are secretly indexing them with numbers starting from 1:

-- this
{"a", "b", "c"}

-- is the same as this
{
	[1] = "a",
	[2] = "b",
	[3] = "c"
}

So this gives the i meaning in the for loop by giving you the number part on the left, which every other array has as well:

local array = {"a", "b", "c"}
local otherArray = {"x", "y", "z"}

for i, v in pairs(array) do
	print(i, v)
end
--> 1 a
--> 2 b
--> 3 c

for i, v in pairs(array) do
	print(otherArray[i])
end
--> x
--> y
--> z
3 Likes

Now there is nothing parented in cubes

1 Like

Are you sure the terrain variable is defined? It could be nil if you omitted the local terrain = ... line beforehand.

yes it is defined. It goes to (whatever the map being saved is).terrain.cubes

1 Like

So I tested your code myself, and I found out that your newly instanced parts were falling into the abyss, since parts created from Instance.new are not anchored on default. The fix is easy though, you just have to add a part.Anchored = true statement in your for loop.


Along with that, I found an issue in this block:

function save_to_model(folder_name, target_location, xoffset, yoffset, zoffset)
	ServerStorage.empty_map:Clone()
	ServerStorage.empty_map.Name = folder_name
	ServerStorage[folder_name].Parent = Workspace
	local terrain = Workspace[folder_name].terrain:WaitForChild("cubes")

You need to save the cloned object to a variable and parent that to Workspace. Otherwise, you will be referencing the original empty_map asset.

function save_to_model(folder_name, target_location, xoffset, yoffset, zoffset)
	local newMap = ServerStorage.empty_map:Clone()
	newMap.Name = folder_name
	newMap.Parent = Workspace
	local terrain = newMap.terrain:WaitForChild("cubes")
2 Likes

Oops. Btw i actually store maps in a folder called maps stored in the Workspace.

1 Like