Why is this code working so weird?

Hi Guys, so basically I was trying to make a generating script that would generate an obby.

Script -

local ObbyGenerator = {}

local partsFolder = game.ServerStorage.ObbyParts:GetChildren()

local currentPart = nil
local previousPart = nil

local brick_limit = math.random(5,7)

local brick_counter = 0

function ObbyGenerator:Generate()
	for i=1, 50 do
		local number = math.random(1, #partsFolder)
		local currentPart = partsFolder[number]:Clone()
		currentPart.Parent = workspace
		print(currentPart.Name)
		
			if previousPart == nil then
			previousPart = currentPart
			currentPart.CFrame = CFrame.new(140, 1, 15)
		end
		
		 if previousPart == currentPart then
 			currentPart = game.ServerStorage.ObbyParts.SlimPart:Clone()
 			currentPart.Parent = workspace
 			currentPart.CFrame = CFrame.new(previousPart.CFrame.X, previousPart.CFrame.Y, (previousPart.CFrame.Z + previousPart.Size.Z/2 + currentPart.Size.Z/2) + 3)
			previousPart = currentPart
		end
		
 			if previousPart == currentPart and previousPart.Name == "SlimPart" then
				local number_of_times = math.random(2, 5)
				local previousPosition = nil
				local previousSize = nil
				local final_part = nil
				for i=1, number_of_times do
				local part = partsFolder["SlimPart"]:Clone()
				part.Parent = workspace
					final_part = part
					if previousPosition == nil then
						previousPosition = previousPart.CFrame
						previousSize = previousPart.Size
						part.CFrame = CFrame.new(previousPart.CFrame.X, previousPart.CFrame.Y, (previousPart.CFrame.Z + previousPart.Size.Z/2) + 3)
					else
						part.CFrame = CFrame.new(previousPosition.X, previousPosition.Y, (previousPosition.Z + previousSize.Z/2) + 3)
					end
				end
				previousPart = final_part
				currentPart = final_part
		end
		
		if previousPart ~= currentPart then
			currentPart.CFrame = CFrame.new(previousPart.CFrame.X, previousPart.CFrame.Y, (previousPart.CFrame.Z + previousPart.Size.Z/2 + currentPart.Size.Z/2) + 3)
			previousPart = currentPart
		end
	end
end

return ObbyGenerator

This code seems fine to me, but it returns this error -
attempt to index nil with ‘Clone’ - Server - ObbyGenerator:37

Now why is it even happening? Any help is appreciated!

Because the :GetChildren() return an Array of parts (which if you don’t know, it is an indexed-based table)
To fix it, you need to add another initialization of a variable that use the :GetChildren()
So it can be like:

local partsFolder = game.ServerStorage.ObbyParts
local partsFolderChildren = partsFolder:GetChildren()

and change these lines of code

To be

local number = math.random(1, #partsFolderChildren)
local currentPart = partsFolderChildren[number]:Clone()

Hope this helps! :grinning:

1 Like

Thanks for your advice! It worked perfectly!

But how does this differ from writing in one variable?

EDIT- Sorry to say, but it still errors and shows that it’s nil.
Code -

local ObbyGenerator = {}

local partsFolder = game.ServerStorage:WaitForChild("ObbyParts")
local partsFolderChildren = partsFolder:GetChildren()

local currentPart = nil
local previousPart = nil

local brick_limit = math.random(5,7)

local brick_counter = 0

function ObbyGenerator:Generate()
	for i=1, 50 do
		local number = math.random(1, #partsFolderChildren)
		local currentPart = partsFolderChildren[number]:Clone()
		currentPart.Parent = workspace
		print(currentPart.Name)
		
			if previousPart == nil then
			previousPart = currentPart
			currentPart.CFrame = CFrame.new(140, 1, 15)
		end
		
		if currentPart == previousPart then
			print("yes")
			currentPart = game.ServerStorage.ObbyParts.SlimPart:Clone()
			currentPart.Parent = workspace
			currentPart.CFrame = CFrame.new(previousPart.CFrame.X, previousPart.CFrame.Y, (previousPart.CFrame.Z + previousPart.Size.Z/2 + currentPart.Size.Z/2) + 3)
			previousPart = currentPart
		end
		
			if previousPart == currentPart and previousPart.Name == "SlimPart" then
				local number_of_times = math.random(2, 5)
				local previousPosition = nil
				local previousSize = nil
				local final_part = nil
				for i=1, number_of_times do
				local part = partsFolderChildren["SlimPart"]:Clone()
				part.Parent = workspace
					final_part = part
					if previousPosition == nil then
						previousPosition = previousPart.CFrame
						previousSize = previousPart.Size
						part.CFrame = CFrame.new(previousPart.CFrame.X, previousPart.CFrame.Y, (previousPart.CFrame.Z + previousPart.Size.Z/2) + 3)
					else
						part.CFrame = CFrame.new(previousPosition.X, previousPosition.Y, (previousPosition.Z + previousSize.Z/2) + 3)
					end
				end
				previousPart = final_part
				currentPart = final_part
		end
		
		if currentPart ~= previousPart then
			currentPart.CFrame = CFrame.new(previousPart.CFrame.X, previousPart.CFrame.Y, (previousPart.CFrame.Z + previousPart.Size.Z/2 + currentPart.Size.Z/2) + 3)
			previousPart = currentPart
		end
	end
end

return ObbyGenerator

Because of the :GetChildren() function.
When it’s used in a loop, it really slows down the performance of the script.
So, it is recommended to separate it out to another variable.

I didn’t specify that you don’t have to change the variable in

You can leave it the way it is the old way, I apologize for not clarifying it.
So it will be local part = partsFolder["SlimPart"]:Clone()

1 Like

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