So i made a random maze generator and it gives me a error saying attempt to perform arithmetic (sub) on number and nil Why?

All i want is my maze generator to work when i test it it gives me this error image

This is my code on the line
image

This is my whole code
local ignoreinstance = script.Parent
local TS = game:GetService("TweenService")
local Info = TweenInfo.new(0.5,Enum.EasingStyle.Linear,Enum.EasingDirection.Out,0,false,0)
local Part = script.Parent
local db = false
local TotalParts = 8
local CurrentParts = 0
wait(10)
print("Maze Generation Started")

local Pos = {
	Vector3.new(0,0,-15),
	Vector3.new(-15,0,0),
	Vector3.new(0,0,15),
	Vector3.new(15,0,0)
}

local OldPositions = {}

while true do
	for i=1,4 do
		script.Parent.Orientation = Vector3.new(0,i*90,0)
		local ray = Ray.new(script.Parent.Position,Pos[i])
		local part, position = workspace:FindPartOnRay(ray,ignoreinstance,false,true)
		if part then
			if not db then
				db = true
				if part.Name == "MazePart" and math.random(1,2) == 1 then
					StartTick = math.round(tick())
					local PrevPartPosition = script.Parent.Position
					local Tween = TS:Create(Part,Info,{Position = part.Position})
					Tween:Play()
					local Distance = math.round((part.Position - PrevPartPosition).Magnitude)
					local DistancePart = Instance.new("Part",game.Workspace)
					DistancePart.Material = Enum.Material.SmoothPlastic
					DistancePart.CanCollide = false
					DistancePart.Anchored = true
					local Orientation = Part.Orientation.Y	
					DistancePart.Size = Vector3.new(Distance+3,1,3)
					DistancePart.Orientation = Vector3.new(0,Orientation,0)
					if Orientation == -90 then
						DistancePart.Position = PrevPartPosition+Vector3.new(0,0,(Distance/2))
					elseif Orientation == 90 then
						DistancePart.Position = PrevPartPosition-Vector3.new(0,0,(Distance/2))		
					elseif Orientation == -180 then
						DistancePart.Position = PrevPartPosition-Vector3.new((Distance/2),0,0)		
					else
						DistancePart.Position = PrevPartPosition+Vector3.new((Distance/2),0,0)
					end
					CurrentParts = CurrentParts + 1
					PrevPartPosition = part.Position
					table.insert(OldPositions,#OldPositions+1,part.Position)
					part:Destroy()
				end
				print(tick() - StartTick,CurrentParts,OldPositions)
				if tick() - StartTick > 2 and CurrentParts < TotalParts then
					print("No Parts Found")
					local Tween = TS:Create(Part,Info,{Position = OldPositions[#OldPositions]})
					Tween:Play()
					table.remove(OldPositions,#OldPositions)
					StartTick = math.round(tick())
				end
				wait()
				db = false
			end
		end
		wait(0)
	end
end

Please help me

I think one of your vars is nil

2 Likes

StartTick is nil when that line of code was ran. I can’t fix the code since I’m at mobile but:

Try moving these above the print statement or put the print inside at the end of the if statement

1 Like

012aca32e2689515066f50009c218c2768dcfbe9
It’s saying “StartTick” is nil, and you tried to subtract tick() (a function that returns a “number”) and StartTick (being “nil”), somewhere in your code, you forgot to change that, or you put the variable “StartTick” in the wrong stack or location

i solved it its cause the starttick was nil so i used repeat until to do it and now works

I’m not sure you should do that, it might crash you if you never set the variable

well i obviously added wait() i know it crashes it but now it works fine but i have one problem

1 Like
local ignoreinstance = script.Parent
local TS = game:GetService("TweenService")
local Info = TweenInfo.new(0.5,Enum.EasingStyle.Linear,Enum.EasingDirection.Out,0,false,0)
local Part = script.Parent
local db = false
local TotalParts = #game.Workspace.Parts:GetChildren()
local CurrentParts = 0
function IsEven(num)
	return num % 2 == 0
end
for i=5,1,-1 do
	print("Starting In "..i)
	wait(1)
end
print("Maze Generation Started")

local Finished = false
repeat
	Elapsed = tick()
	wait()
until Elapsed ~= nil

local Pos = {
	Vector3.new(0,0,-15),
	Vector3.new(-15,0,0),
	Vector3.new(0,0,15),
	Vector3.new(15,0,0)
}

local OldPositions = {}


while not Finished do
	for i=1,4 do
		script.Parent.Orientation = Vector3.new(0,i*90,0)
		local ray = Ray.new(script.Parent.Position,Pos[i])
		local part, position = workspace:FindPartOnRay(ray,ignoreinstance,false,true)
		if part then
			if not db then
				db = true
				if part.Name == "MazePart" and math.random(1,2) == 1 then
					repeat
						StartTick = math.round(tick())
					wait()	
					until StartTick ~= nil
					local PrevPartPosition = script.Parent.Position
					script.Parent.Position = part.Position
					local Distance = math.round((part.Position - PrevPartPosition).Magnitude)
					local DistancePart = Instance.new("Part",game.Workspace)
					DistancePart.Material = Enum.Material.SmoothPlastic
					DistancePart.CanCollide = false
					DistancePart.Anchored = true
					local Orientation = Part.Orientation.Y
					DistancePart.Orientation = Vector3.new(0,Orientation,0)
					DistancePart.Size = Vector3.new(14,1,6)
					if IsEven(Distance) then
						print(Distance)
					else
						Distance = Distance +1
					end
					if Orientation == -90 then
						DistancePart.Position = PrevPartPosition+Vector3.new(1,0,(Distance/2))
					elseif Orientation == 90 then
						DistancePart.Position = PrevPartPosition-Vector3.new(-1,0,(Distance/2))	
					elseif Orientation == -180 then
						DistancePart.Position = PrevPartPosition-Vector3.new((Distance/2),0,-1)		
					elseif Orientation == 0 then
						DistancePart.Position = PrevPartPosition+Vector3.new((Distance/2),0,1)
					end
					DistancePart.Position = Vector3.new(math.round(DistancePart.Position.X),DistancePart.Position,math.round(DistancePart.Position.Z))
					CurrentParts = CurrentParts + 1
					PrevPartPosition = part.Position
					table.insert(OldPositions,#OldPositions+1,part.Position)
					part:Destroy()
				end
				if StartTick then
					if math.round(tick() - StartTick) > 1 and CurrentParts < TotalParts then
						print("No Parts Found")
						script.Parent.Position = OldPositions[#OldPositions]
						table.remove(OldPositions,#OldPositions)
						StartTick = math.round(tick())
					elseif CurrentParts == TotalParts and not Finished then
						Finished = true
						print("Maze Was Finished In "..math.round(tick() - Elapsed).." Seconds")
					end
				end
				wait()
				db = false
			end
		end
		wait(0)
	end
end

Current code

My problem is that the distancepart’s position is a bit messed up

What it is currently with this code
image

what i want it to be like
image

this is because i dont know the new one i know the old one ok and yes this is VERY off topic

yes obviously i can see that one variable is nil

(:laughing: feels like I’m doin an IQ test lol)
Could you simplify this code to where you set the part’s position?

Haha nice joke

while not Finished do
	for i=1,4 do
		script.Parent.Orientation = Vector3.new(0,i*90,0)
		local ray = Ray.new(script.Parent.Position,Pos[i])
		local part, position = workspace:FindPartOnRay(ray,ignoreinstance,false,true)
		if part then
			if not db then
				db = true
				if part.Name == "MazePart" and math.random(1,2) == 1 then
					repeat
						StartTick = math.round(tick())
					wait()	
					until StartTick ~= nil
					local PrevPartPosition = script.Parent.Position
					script.Parent.Position = part.Position
					local Distance = math.round((part.Position - PrevPartPosition).Magnitude)
					local DistancePart = Instance.new("Part",game.Workspace)
					DistancePart.Material = Enum.Material.SmoothPlastic
					DistancePart.CanCollide = false
					DistancePart.Anchored = true
					local Orientation = Part.Orientation.Y
					DistancePart.Orientation = Vector3.new(0,Orientation,0)
					DistancePart.Size = Vector3.new(14,1,6)
					if IsEven(Distance) then
						print(Distance)
					else
						Distance = Distance +1
					end -- below this part is positioning
					if Orientation == -90 then
						DistancePart.Position = PrevPartPosition+Vector3.new(1,0,(Distance/2))
					elseif Orientation == 90 then
						DistancePart.Position = PrevPartPosition-Vector3.new(-1,0,(Distance/2))	
					elseif Orientation == -180 then
						DistancePart.Position = PrevPartPosition-Vector3.new((Distance/2),0,-1)		
					elseif Orientation == 0 then
						DistancePart.Position = PrevPartPosition+Vector3.new((Distance/2),0,1)
					end
					DistancePart.Position = Vector3.new(math.round(DistancePart.Position.X),DistancePart.Position,math.round(DistancePart.Position.Z))
					CurrentParts = CurrentParts + 1
					PrevPartPosition = part.Position
					table.insert(OldPositions,#OldPositions+1,part.Position)
					part:Destroy()
				end
				if StartTick then
					if math.round(tick() - StartTick) > 1 and CurrentParts < TotalParts then
						print("No Parts Found")
						script.Parent.Position = OldPositions[#OldPositions]
						table.remove(OldPositions,#OldPositions)
						StartTick = math.round(tick())
					elseif CurrentParts == TotalParts and not Finished then
						Finished = true
						print("Maze Was Finished In "..math.round(tick() - Elapsed).." Seconds")
					end
				end
				wait()
				db = false
			end
		end
		wait(0)
	end
end

I’m sorry, but I’m still kinda confused by this code, so here’s some useful tips instead!

1: You should learn about CFrame, I promise you, it will be the most useful (in terms of positioning and rotating objects) tool in roblox!
2:Try to use shorter, but memorable variables, when scripting I understand the amount of variables will increase, not everyone has a photo-graphic memory, plus, it also shortens your code and makes things look A LOT neater!
3: This

[quote=“Qinrir, post:13, topic:1485663”]
#OldPositions+1
[/quote] Is no longer necessary when using table.insert anymore, also, instead of this

you should do this


local myPoses = {
	Vector3.new(0,0,-15),
	Vector3.new(-15,0,0),
	Vector3.new(0,0,15),
	Vector3.new(15,0,0)
}
local OldPositions = {}

for i,pos in pairs(myPoses) do

4: Don’t use wait(), use task.wait() or runservice.Heartbeat:Wait()
wait() is not very reliable anymore, these would be a TON better, also, if you’re using waits to wait for the physics to render then just use hearbeat, it’s much better and much faster, and (as I said before) much more reliable!

i see thanks for telling me about waitCframe and variables

1 Like

also i used this so the old position is always at the end also if i dont use +1 it would put it to 0 meaning it would give error i did tried this with +1 but no work

I know, but roblox change the function to that you don’t need that anymore

oh ok i see and would use it then

1 Like