trying to keep it short and simple (reading back to this it is not short or simple)
generating the walls leave this corner section on some of them
for my generation i use models with “pathsections”
these pathsections define the layout of the chosen path for example
this T shape is made up out of 5 sections
Each section has attachments like this
The blue circles are pathconnectors, they are the main points for paths to connect to each other
The red circles are wallconnectors, will normally only be used for placement of walls
The one on the bottom is for the floor and the one on the top is for the roof
now normally i could just place the corner model into the preset pathsections where corners would be but refering back to the normally part in wallconnectors
there may be some times where the maze hit its max distance and theres no more pathconnectors to connect to, so it will generate off a random wall connection instead
making the pre-placed models not work
So im just wondering what could i do to make place these corner pieces with accuracy and speed
Heres the module
local SectionGenerationValues = require(script.GenValues)
local SectionModule = require(script.SectionInfo)
local Useful = require(script.Useful)
local Randomizer = Random.new()
local SectionHolder = workspace.Sections
local SectionAssets = game:GetService("ServerStorage").SectionAssets
local RunService = game:GetService('RunService')
local MaxSectionGeneration = 3 -- How many sections can generate at once
local CurrentGeneratingSections = {} -- The current sections generating
local GeneratedSections = {}
local AllSections = {}
-- Timers --
local Path_Placement_Check_WaitTime = 5
local Wall_Delay_Number = 10
-- Zero Variables --
local Path_Placement_Check_TimeNum = 0
local Wall_Delay_TimeNum = 0
--
-- Math --
local random = math.random
local rad = math.rad
local randomNew = Random.new
--
-- Extra Functions
local function RNGd(PathValues, CurrentWeight : number, RngTable)
local CanRoll = {}
local Rng = Random.new()
local Counter = 0
for Path, PathInfo in pairs(PathValues) do
if PathInfo.Weight <= CurrentWeight then
local ChanceMult = {}
local Chance = PathInfo.Chance
local SpareWeight = CurrentWeight - PathInfo.Weight
local Rolls = RngTable.RollsSinceLastRolled[Path]
local MultipleRolls = RngTable.MultipleRolls[Path]
local BaseMullipier = 1
if SpareWeight > 0 then table.insert(ChanceMult, math.clamp(SpareWeight/55,0,2)) end
if Rolls > PathInfo.Pity then table.insert(ChanceMult, Rolls/5) end
if MultipleRolls > 3 then table.insert(ChanceMult, -(MultipleRolls/5)) end
for i, v in ipairs(ChanceMult) do BaseMullipier += v end
BaseMullipier = math.clamp(BaseMullipier, .1, 4)
local ModifiedChance = math.clamp(Chance * BaseMullipier, 0, 100)
CanRoll[Path] = ModifiedChance
end
end
for _, Chance in pairs(CanRoll) do
Counter += Chance
end
local Chosen = Rng:NextNumber(0, Counter)
for Path, Chance in pairs(CanRoll) do
Counter -= Chance
if Chosen > Counter then
return Path
end
end
end
local function UnionCreationAndPosition(BaseUnionPart:Part, PartsToUnion:table, CollisionFidelity:Enum.CollisionFidelity?, RenderFidelity:Enum.RenderFidelity?, WaitTime:number)
local FarthestPositveX
local FarthestPositveY
local FarthestPositveZ
local FarthestNegativeX
local FarthestNegativeY
local FarthestNegativeZ
local NewUnion:UnionOperation
local OperationStartTime = os.clock()
local IsSucessful, ErrorMessage = nil, nil
local SelfCoroutine = coroutine.create(function()
IsSucessful, ErrorMessage = pcall(function()
NewUnion = BaseUnionPart:UnionAsync(PartsToUnion, CollisionFidelity, RenderFidelity)
end)
end)
coroutine.resume(SelfCoroutine)
for Num, Part : Part in ipairs(PartsToUnion) do
if not FarthestPositveX then FarthestPositveX = Part.Position.X else
if FarthestPositveX < Part.Position.X then FarthestPositveX = Part.Position.X end
end
if not FarthestPositveY then FarthestPositveY = Part.Position.Y else
if FarthestPositveY < Part.Position.Y then FarthestPositveY = Part.Position.Y end
end
if not FarthestPositveZ then FarthestPositveZ = Part.Position.Z else
if FarthestPositveZ < Part.Position.Z then FarthestPositveZ = Part.Position.Z end
end
if not FarthestNegativeX then FarthestNegativeX = Part.Position.X else
if FarthestNegativeX > Part.Position.X then FarthestNegativeX = Part.Position.X end
end
if not FarthestNegativeY then FarthestNegativeY = Part.Position.Y else
if FarthestNegativeY > Part.Position.Y then FarthestNegativeY = Part.Position.Y end
end
if not FarthestNegativeZ then FarthestNegativeZ = Part.Position.Z else
if FarthestNegativeZ > Part.Position.Z then FarthestNegativeZ = Part.Position.Z end
end
end
local MidpointPosition = (
Vector3.new(
FarthestPositveX,
FarthestPositveY,
FarthestPositveZ
) +
Vector3.new(
FarthestNegativeX,
FarthestNegativeY,
FarthestNegativeZ
))/2
repeat task.wait() until os.clock() - OperationStartTime >= WaitTime or NewUnion or (IsSucessful ~= nil)
if NewUnion then
return true, NewUnion, MidpointPosition
elseif os.clock() - OperationStartTime >= WaitTime then
warn("Time Exceeded Max Union Time")
return false
elseif (IsSucessful ~= nil) and IsSucessful == false then
warn("Error Accured: " .. if ErrorMessage then ErrorMessage else "[No Error Message]")
return false
end
end
--
-- Generation Functions
local function PathPlacementCheck(AttachTo : Attachment, AttachFrom : Attachment, AttachmentModel : Model, BoundingBoxPart : Part, Olp : OverlapParams, WallAttach : boolean)
if Path_Placement_Check_TimeNum > Path_Placement_Check_WaitTime then
task.wait()
Path_Placement_Check_TimeNum = 0
else
Path_Placement_Check_TimeNum += 1
end
local BaseOlp = OverlapParams.new()
BaseOlp.FilterType = Enum.RaycastFilterType.Include
BaseOlp.FilterDescendantsInstances = {workspace.Sections}
local PlacementCFrame = AttachTo.WorldCFrame * CFrame.fromOrientation(0, if WallAttach then rad(90) else rad(180), 0)
AttachmentModel:PivotTo(PlacementCFrame)
local Check1 = (AttachTo.WorldPosition - AttachFrom.WorldPosition).Magnitude < .01
local OverlappingParts = workspace:GetPartsInPart(BoundingBoxPart, if not Olp then BaseOlp else Olp)
local Check2 = #OverlappingParts == 0
if Check1 and Check2 then
return true
end
return false
end
local function WallPlacementCheck(WallAttachment : Attachment, AttachFrom : Attachment, ChosenWall : string, WallPathValues)
if ChosenWall == "openwall" then
if WallAttachment.Adornee.Value ~= nil then
WallAttachment.Adornee.Value:Destroy()
end
return true
elseif WallPathValues[ChosenWall].Instance then
local Wall = WallPathValues[ChosenWall].Instance:Clone()
Wall:PivotTo(WallAttachment.CFrame)
Wall.Parent = WallAttachment.Parent.Parent
if WallAttachment.Adornee.Value ~= nil then
WallAttachment.Adornee.Value:Destroy()
WallAttachment.Adornee.Value = Wall
end
return true
end
end
local function CheckForPathToPathConnection(SectionInformation, TempAttachmentList) -- Checks If any attachment on the path connections with another paths attachment that is unattached
local AllAttachments = SectionInformation.Values.AllAttachments
for Attachment2, _ in pairs(SectionInformation.Values.ConnectableAttachments) do
for _, TempAttachment2 in ipairs(TempAttachmentList) do
if (Attachment2.WorldPosition - TempAttachment2.WorldPosition).Magnitude < .01 then
SectionInformation.Values.ConnectableAttachments[Attachment2] = nil
table.remove(TempAttachmentList, table.find(TempAttachmentList, TempAttachment2))
AllAttachments[Attachment2] = nil
end
end
end
end
local function CheckForPathToWallConnection(SectionInformation, TempAttachmentList, WallPathValues)-- Checks If any attachment on the path connects to a wall, will roll rng to try and change the wall
local WallConnectionRngTable = SectionInformation.Values.RollTables.WallConnectionRolls
for _, TempAttachment2 in ipairs(TempAttachmentList) do
task.wait()
for _, WallAttachment in ipairs(SectionInformation.Values.ConnectableWallAttachments) do
if (WallAttachment.WorldPosition - TempAttachment2.WorldPosition).Magnitude < 0.01 then
table.remove(TempAttachmentList, table.find(TempAttachmentList, TempAttachment2))
table.remove(SectionInformation.Values.ConnectableWallAttachments, table.find(SectionInformation.Values.ConnectableWallAttachments, WallAttachment))
local ChosenWall = RNGd(WallPathValues, SectionInformation.Values.Weight, WallConnectionRngTable)
local Result2 = WallPlacementCheck(WallAttachment, TempAttachment2, ChosenWall, WallPathValues)
if Result2 then
SectionInformation.Values.Weight -= WallPathValues[ChosenWall].Cost
for Wall, Num in pairs(WallConnectionRngTable.RollsSinceLastRolled) do
if ChosenWall ~= Wall then
WallConnectionRngTable.RollsSinceLastRolled[Wall] += 1
WallConnectionRngTable.MultipleRolls[Wall] = 0
else
WallConnectionRngTable.RollsSinceLastRolled[Wall] = 0
WallConnectionRngTable.MultipleRolls[Wall] += 1
end
end
end
end
end
end
end
local function CheckForWallToPathConnection(SectionInformation, TempWallAttachmentList, WallPathValues)
local AllAttachments = SectionInformation.Values.AllAttachments
local HalfWaited = false
local WallConnectionRngTable = SectionInformation.Values.RollTables.WallConnectionRolls-- Checks if any wall attachment connects to a path, will roll wall (happens pretty rarely)
for Num, TempWallAttachment in ipairs(TempWallAttachmentList) do
if Num >= #TempWallAttachmentList/2 and not HalfWaited then task.wait(); HalfWaited = true end
for Num2, Attachment2 in ipairs(AllAttachments) do
if (TempWallAttachment.WorldPosition - Attachment2.WorldPosition).Magnitude < 0.01 then
table.remove(TempWallAttachmentList, table.find(TempWallAttachmentList, TempWallAttachment))
AllAttachments[Attachment2] = nil
local ChosenWall = RNGd(WallPathValues, SectionInformation.Values.Weight, WallConnectionRngTable)
local Result2 = WallPlacementCheck(TempWallAttachment, Attachment2, ChosenWall, WallPathValues)
if Result2 then
SectionInformation.Values.Weight -= WallPathValues[ChosenWall].Cost
for Wall, Num in pairs(WallConnectionRngTable.RollsSinceLastRolled) do
if ChosenWall ~= Wall then
WallConnectionRngTable.RollsSinceLastRolled[Wall] += 1
WallConnectionRngTable.MultipleRolls[Wall] = 0
else
WallConnectionRngTable.RollsSinceLastRolled[Wall] = 0
WallConnectionRngTable.MultipleRolls[Wall] += 1
end
end
end
end
end
end
end
local function Rolled(RollTable, Chosen)
for Path, Num in pairs(RollTable.RollsSinceLastRolled) do
if Chosen ~= Path then
RollTable.RollsSinceLastRolled[Path] += 1
RollTable.MultipleRolls[Path] = 0
else
RollTable.RollsSinceLastRolled[Path] = 0
RollTable.MultipleRolls[Path] += 1
end
end
end
local function Pathical(SectionInformation : table, Section : string, PathInfo : table, WallConnectionInfo : table, UseWall : boolean)
local SectionValues = SectionModule[Section]
local TempAttachmentList = {}
local TempWallAttachmentList = {}
local TempPathSections = {}
local TempFloorAttachments = {}
local TempRoofAttachments = {}
local TEMPattachmentToTable = {
["pathconnection"] = TempAttachmentList,
["wallconnection"] = TempWallAttachmentList,
["pathsection"] = TempPathSections,
["floorconnection"] = TempFloorAttachments,
["roofconnection"] = TempRoofAttachments
}
local AllAttachments = SectionInformation.Values.AllAttachments
local AllWallAttachments = SectionInformation.Values.AllWallAttachments
local ConnectableWallAttachments = SectionInformation.Values.ConnectableWallAttachments
local ConnectableAttachments = SectionInformation.Values.ConnectableAttachments
local FloorAttachments = SectionInformation.Values.FloorAttachments
local RoofAttachments = SectionInformation.Values.RoofAttachments
local PathSections = SectionInformation.Values.PathSections
local PathRolls = SectionInformation.Values.RollTables.PathRolls
local StartingPosition = SectionInformation.Values.StartingPosition
local MaxDistance = SectionValues.MaxDistance
local PathOverlapParams = OverlapParams.new()
PathOverlapParams.FilterType = Enum.RaycastFilterType.Include
PathOverlapParams.FilterDescendantsInstances = {SectionHolder}
local ChosenPath = RNGd(PathInfo, SectionInformation.Values.Weight, PathRolls)
local PathModel = PathInfo[ChosenPath].Instance:Clone()
for Num, inst in ipairs(PathModel:GetDescendants()) do
local LwName = inst.Name:lower()
local attachmentTable = TEMPattachmentToTable[LwName]
if attachmentTable then
table.insert(attachmentTable, inst)
end
end
local Cf, Size = PathModel:GetBoundingBox()
local BoundingBox = Useful.BoundBox(Cf, Size, PathModel)
for Attachment, AttachmentInfo in pairs(if UseWall then ConnectableWallAttachments else ConnectableAttachments) do
for TempAttachmentNumber, TempAttachment in ipairs(TempAttachmentList) do
PathModel.PrimaryPart.CFrame = TempAttachment.WorldCFrame
local Attached = PathPlacementCheck(Attachment, TempAttachment, PathModel, BoundingBox, PathOverlapParams, UseWall)
if Attached then
if not UseWall then
ConnectableAttachments[Attachment] = nil
table.remove(AllAttachments, table.find(AllAttachments, Attachment))
table.remove(TempAttachmentList, table.find(TempAttachmentList, TempAttachment))
else
ConnectableWallAttachments[Attachment] = nil
table.remove(AllWallAttachments, table.find(AllWallAttachments, Attachment))
table.remove(TempAttachmentList, table.find(TempAttachmentList, TempAttachment))
end
CheckForPathToPathConnection(SectionInformation, TempAttachmentList, AllAttachments)
CheckForPathToWallConnection(SectionInformation, TempAttachmentList, WallConnectionInfo)
CheckForWallToPathConnection(SectionInformation, TempWallAttachmentList, WallConnectionInfo)
Useful.AddToTable(PathSections, TempPathSections)
Useful.AddToTable(FloorAttachments, TempFloorAttachments)
Useful.AddToTable(RoofAttachments, TempRoofAttachments)
Rolled(PathRolls, ChosenPath)
for i, v in ipairs(TempAttachmentList) do
if (StartingPosition - v.WorldPosition).Magnitude < MaxDistance then
ConnectableAttachments[v] = {["FailedAttaches"] = 0}
end
table.insert(AllAttachments, v)
end
for i, v in ipairs(TempWallAttachmentList) do
if (v.WorldPosition - StartingPosition).Magnitude < MaxDistance then
ConnectableWallAttachments[v] = {["FailedAttaches"] = 0}
end
table.insert(AllWallAttachments, v)
end
return true, ChosenPath, PathModel, Attachment
else
AttachmentInfo["FailedAttaches"] += 1
if AttachmentInfo.FailedAttaches >= 5 then
if UseWall then
ConnectableWallAttachments[Attachment] = nil
print("Broke Wall Attachment")
else
ConnectableAttachments[Attachment] = nil
end
end
end
end
end
return false, ChosenPath, PathModel
end
local function RolledRoom(SectionInformation, ChosenPath, PathModel, PathInfo, WallAttachment)
local SectionFolder = SectionInformation.Values.SectionFolder
SectionInformation.Values.CurrentPaths += 1
PathModel.Parent = SectionFolder.Paths
SectionInformation.Values.Weight -= PathInfo[ChosenPath].Cost
if WallAttachment then
local waValue = WallAttachment.Adornee
if waValue.Value ~= nil then
waValue.Value:Destroy()
waValue.Value = nil
end
end
end
local function PlaceWall(SectionInformation, Attachment : Attachment, PathSection : Part)
local WallInfo = SectionInformation.Information.Walls
local WallRolls = SectionInformation.Values.RollTables.WallRolls
local PathSectionPosition = PathSection.Position
local ChosenWall = WallInfo[RNGd(WallInfo, SectionInformation.Values.Weight, WallRolls)].Instance:Clone()
local WallCFrame, WallSize = ChosenWall:GetBoundingBox()
local LookAt = Vector3.new(
PathSectionPosition.X,
Attachment.WorldPosition.Y,
PathSectionPosition.Z
)
local CFrame1 = CFrame.lookAt(Attachment.WorldPosition, LookAt)
if ChosenWall.PrimaryPart then
ChosenWall:PivotTo(CFrame1)
return true, ChosenWall
else
warn(ChosenWall.Name:lower() .. " has no primary part set")
ChosenWall:Destroy()
return false
end
end
--
local GenerationModule = {}
GenerationModule.StartGeneration = function()
print("D")
local SectionsTable = {}
for Section, SectionInformation in pairs(SectionGenerationValues) do
local SectionFolder = game.ServerStorage.bsf:Clone()
SectionFolder.Name = tostring(Section)
SectionsTable[Section] = {
["Information"] = SectionInformation,
["Values"] = {
["GenerationStatus"] = "NotGenerated",
["GenerationPercentage"] = 0,
["CurrentPaths"] = 0,
["ConnectableAttachments"] = {},
["ConnectableWallAttachments"] = {},
["AllWallAttachments"] = {},
["PathSections"] = {},
["AllAttachments"] = {},
["RoofAttachments"] = {},
["FloorAttachments"] = {},
["Weight"] = 0,
["Walls"] = {},
["SectionFolder"] = SectionFolder
}
}
AllSections[Section] = SectionsTable[Section]
end
for Section, SectionInformation in pairs(SectionsTable) do
if #CurrentGeneratingSections >= MaxSectionGeneration then
repeat task.wait() until #CurrentGeneratingSections < MaxSectionGeneration
end
if not SectionInformation.Information.Special then
table.insert(CurrentGeneratingSections, Section)
local StartTime = os.clock()
local GenerationCoroutine = coroutine.create(function()
local SectionFolder = SectionInformation.Values.SectionFolder
SectionFolder.Parent = SectionHolder
local SectionValues = SectionModule[Section]
-- Infos
local PathInfo = SectionInformation.Information.Paths
local WallConnectionInfo = SectionInformation.Information.WallConnections
local WallInfo = SectionInformation.Information.Walls
local FloorInfo = SectionInformation.Information.Floors
local RoofInfo = SectionInformation.Information.Roofs
-- Attachments & Pathsections
local AllAttachments = SectionInformation.Values.AllAttachments
local ConnectableAttachments = SectionInformation.Values.ConnectableAttachments
local ConnectableWallAttachments = SectionInformation.Values.ConnectableWallAttachments
local FloorAttachments = SectionInformation.Values.FloorAttachments
local RoofAttachments = SectionInformation.Values.RoofAttachments
local PathSections = SectionInformation.Values.PathSections
local AllWallAttachments = SectionInformation.Values.AllWallAttachments
local attachmentToTable = {
["pathconnection"] = ConnectableAttachments,
["wallconnection"] = ConnectableWallAttachments,
["pathsection"] = PathSections,
["floorconnection"] = FloorAttachments,
["roofconnection"] = RoofAttachments
}
-- Generation Information
local FirstWeightRoll = SectionValues.FirstWeightRoll
local MinWeightRoll = SectionValues.MinWeightRoll
local MaxWeightRoll = SectionValues.MaxWeightRoll
local MaxDistance = SectionValues.MaxDistance
local CurrentPaths = SectionInformation.Values.CurrentPaths
local TotalPaths = random(SectionValues.miniumRooms, SectionValues.maxiumRooms)
local RollTables = {
["PathRolls"] = {
["RollsSinceLastRolled"] = {},
["MultipleRolls"] = {}
},
["WallConnectionRolls"] ={
["RollsSinceLastRolled"] = {},
["MultipleRolls"] = {}
},
["WallRolls"] = {
["RollsSinceLastRolled"] = {},
["MultipleRolls"] = {}
},
["FloorRolls"] = {
["RollsSinceLastRolled"] = {},
["MultipleRolls"] = {}
},
["RoofRolls"] = {
["RollsSinceLastRolled"] = {},
["MultipleRolls"] = {}
},
}
SectionInformation.Values.RollTables = RollTables
local PathRolls = RollTables.PathRolls
local WallConnectionRolls = RollTables.WallConnectionRolls
local WallRolls = RollTables.WallRolls
local FloorRolls = RollTables.FloorRolls
local RoofRolls = RollTables.RoofRolls
local function SetupInfo(InfoTable, RollTable)
for Thing, _ in pairs(InfoTable) do
RollTable.RollsSinceLastRolled[Thing] = 0
RollTable.MultipleRolls[Thing] = 0
end
end
SetupInfo(PathInfo, PathRolls)
SetupInfo(WallConnectionInfo, WallConnectionRolls)
SetupInfo(WallInfo, WallRolls)
SetupInfo(FloorInfo, FloorRolls)
SetupInfo(RoofInfo, RoofRolls)
local StartingPath = PathInfo[RNGd(PathInfo, FirstWeightRoll, PathRolls)].Instance:Clone()
StartingPath.Parent = SectionFolder.Paths
CurrentPaths += 1
StartingPath:PivotTo(CFrame.new(0,100,0))
SectionInformation.Values.StartingPosition = StartingPath.PrimaryPart.Position
for Num, inst in ipairs(StartingPath:GetDescendants()) do
local lwName = inst.Name:lower()
if inst:IsA("Attachment") and lwName == "pathconnection" then
ConnectableAttachments[inst] = {["FailedAttaches"] = 0}
elseif inst:IsA("Attachment") and lwName == "wallconnection" then
ConnectableWallAttachments[inst] = {["FailedAttaches"] = 0}
else
local attachmentTable = attachmentToTable[lwName]
if attachmentTable then
table.insert(attachmentTable, inst)
end
end
end
while true do
local Result, ChosenPath, PathModel = Pathical(SectionInformation, Section, PathInfo, WallConnectionInfo, false)
if Result then
RolledRoom(SectionInformation, ChosenPath, PathModel, PathInfo)
else
PathModel:Destroy()
end
local RemainingAttachments = Useful.GetDictonaryNumber(ConnectableAttachments)
if RemainingAttachments == 0 then
warn("No Remaining attachble attachments, attempting to use wall attachments.")
local Result_w, ChosenPath_w, PathModel_w, WallAttachment = Pathical(SectionInformation, Section, PathInfo, WallConnectionInfo, true)
if Result_w then
RolledRoom(SectionInformation, ChosenPath_w, PathModel_w, PathInfo, WallAttachment)
else
warn("Unable to attach to any walls, stopping operation.")
break
end
end
print(math.clamp((SectionInformation.Values.CurrentPaths/TotalPaths)*100, 0, 100) .. "% Complete on generating paths, Current Floor Weight: " .. SectionInformation.Values.Weight)
if SectionInformation.Values.CurrentPaths >= TotalPaths then
for Attachment, AttachmentInfo in pairs(ConnectableAttachments) do
if not table.find(AllAttachments, Attachment) then table.insert(AllAttachments, Attachment) end
end
for Attachment, AttachmentInfo in pairs(ConnectableWallAttachments) do
if not table.find(AllWallAttachments, Attachment) then table.insert(AllWallAttachments, Attachment) end
end
break
end
SectionInformation.Values.Weight += Randomizer:NextNumber(MinWeightRoll,MaxWeightRoll)
end
-- Work on
local WallAttachTable = {
["NonWallAttachment"] = AllAttachments,
["WallAttachment"] = AllWallAttachments
}
local FloorSections = {}
local RoofSections = {}
local BaseFloorPart = nil
local BaseRoofPart = nil
for Index, AttachmentTable in pairs(WallAttachTable) do
for AttachmentNumber, Attachment : Attachment in ipairs(AttachmentTable) do
if Wall_Delay_TimeNum >= Wall_Delay_Number then task.wait(); Wall_Delay_TimeNum = 0 else Wall_Delay_TimeNum += 1 end
local pcallSuccedded, Error = pcall(function()
if not Attachment.Adornee.Value then
local Sucess, Wall = PlaceWall(SectionInformation, Attachment, Attachment.Parent)
if Sucess then
Wall.Parent = SectionFolder.Walls
if SectionInformation.Values.Walls[Wall.PrimaryPart.Position.Y] then
table.insert(SectionInformation.Values.Walls[Wall.PrimaryPart.Position.Y], Wall)
else
SectionInformation.Values.Walls[Wall.PrimaryPart.Position.Y] = {Wall}
end
else
local WallRetryNumber = 0
repeat
WallRetryNumber += 1
Sucess, Wall = PlaceWall(SectionInformation, Attachment, Attachment.Parent)
task.wait()
until Sucess or WallRetryNumber >= 3
if Sucess then
Wall.Parent = SectionFolder.Walls
if SectionInformation.Values.Walls[Wall.PrimaryPart.Position.Y] then
table.insert(SectionInformation.Values.Walls[Wall.PrimaryPart.Position.Y], Wall)
else
SectionInformation.Values.Walls[Wall.PrimaryPart.Position.Y] = {Wall}
end
else
warn("Couldn't Generate Wall For Attachment: " .. Attachment)
end
end
end
end)
if not pcallSuccedded and Error then
print(Error)
end
end
end
print(SectionInformation.Values.Walls)
end)
print("D2")
coroutine.resume(GenerationCoroutine)
end
end
end
GenerationModule.__index = GenerationModule
return GenerationModule