Need some feedback on my random station generation ModuleScript

I am currently in the process of creating my first Roblox game, and I was wondering if the following ModuleScript is well-optimized and organized. If not, I would like some help to make the most out of it. I also want to add some additional features, but for now, optimizing it is my top priority.

The code essentially ensures that when calling the ‘Station.Generate()’ function, a station begins to generate from scratch. It starts by randomly selecting a main room to serve as a starting point, and then at each DoorPlace of that room, another room is generated, each passing through a filter with predefined rules, until the desired number of rooms is achieved. The ‘Station.Assemble()’ function positions the station in its final place.

I would like to know if there is a way to optimize the code so that it’s not a mess.

With regard to how I could improve the script to make it more efficient, I have already optimized it myself to the best of my abilities (as far as I know), so that’s why I came to ask for help.

Well, as I mentioned before, I would like to organize and optimize it. Additionally, I would like to add functionality to provide the Script with a room that is guaranteed to be generated in the station, as well as being able to confirm if there are enough rooms of a certain type (which I have considered doing using additional attributes or creating a new Module with room data).

Finally, here’s the code:
(sorry in advance for the comments in spanish)

local Station = {}

local ServerScriptService = game:GetService("ServerScriptService")

local Weight = require(ServerScriptService.Modules.Weight)

local random = Random.new()

local station = workspace.Map.Main.Station
local stationGenerate = workspace.Map.StationGenerate

local unusedPlaces = {}

local roomCount = 0 --Cantidad de habitaciones generadas
local waitTime = 0.5 --Tiempo de espera entre la generación de habitaciones

Station.rooms = 10 --Cantidad aproximada de habitaciones para generar

Station.stairsPossible = true --Si se pueden generar escaleras
Station.stairs = false --Si se generaron escaleras

function Station.GetRandom(isRoom, prevRoom) --Obtiene una habitación aleatoria
	local roomPool = {}
	
	if isRoom then
		for i, room in pairs(workspace.Templates.Rooms:GetChildren()) do
			-- [1] La habitación seleccionada DEBE ser diferente a la anterior
			if room.Name == prevRoom.Name then
				continue
				
			-- [2] Si se pueden generar escaleras, comprobar que sean las unicas
			elseif room.Name == "Stairs" and (not Station.stairsPossible or Station.stairs) then
				continue
				
			-- [3] Las tres primeras habitaciones tienen que tener más de dos puertas
			elseif roomCount <= 3 and room:GetAttribute("Places") < 2 then
				continue
				
			-- [...] Si la habitación es apta para generarse, añadirla a la pool
			else
				table.insert(roomPool, room)
			end
		end		
		
	else
		roomPool = workspace.Templates.Stations:GetChildren()
	end

	return Weight.GetObject(roomPool)
end

function Station.GenerateRoom(doorPlace)
	local prevRoom = doorPlace.Parent.Parent
	local chosenRoom = Station.GetRandom(true, prevRoom)
	local newRoom = chosenRoom:Clone()
	
	local doorTemplates = workspace.Templates.Doors
	local door = doorTemplates.Door
	local blockedDoor = doorTemplates.BlockedDoor
	
	local doorPlaces = newRoom:FindFirstChild("DoorPlaces")
	local placesList = doorPlaces:GetChildren()

	newRoom:PivotTo(doorPlace.CFrame)
	newRoom.Parent = stationGenerate
	
	--Identificar si hay espacio para generar la habitación
	for i, part in pairs(workspace:GetPartsInPart(newRoom.Hitbox)) do
		if part.Name == "Hitbox" and not part:IsDescendantOf(newRoom) then
			newRoom:Destroy()
			print("collide!")
			return
		end
	end
	
	--Si la habitación es especial, registrarlo en su variable para que no se generen más
	if newRoom.Name == "Stairs" then
		Station.stairs = true
	end
	
	roomCount += 1
	
	doorPlace:SetAttribute("HasRoom", true)
	
	local newDoor = door:Clone()
	newDoor:PivotTo(doorPlace.CFrame)
	newDoor.Parent = newRoom
	
	--Si la habitación tiene otras puertas, generar habitaciones en ellas
	while #placesList > 0 and roomCount < Station.rooms do
		local randomPlace = placesList[random:NextInteger(1, #placesList)]
		
		task.wait(waitTime)
		
		task.spawn(function()
			Station.GenerateRoom(randomPlace)
		end)
		
		table.remove(placesList, table.find(placesList, randomPlace))
	end
	
	print("room generated!")
end

function Station.Generate()
	local chosenRoom = Station.GetRandom(false)
	local newRoom = chosenRoom:Clone()
	
	local porch = workspace.Templates.Porches.Porch
	local blockedDoor = workspace.Templates.Doors.BlockedDoor
	local window = workspace.Templates.Windows.Window8x8
	
	local doorPlaces = newRoom:FindFirstChild("DoorPlaces")
	local placesList = doorPlaces:GetChildren()
	
	station:ClearAllChildren()
	Station.stairs = false
	unusedPlaces = {}
	roomCount = 0
	
	newRoom:PivotTo(workspace.Map.StationGeneratePart.CFrame)
	newRoom.Parent = stationGenerate
	
	roomCount += 1
	
	local newPorch = porch:Clone()
	newPorch:PivotTo(newRoom.PrimaryPart.CFrame)
	newPorch.Parent = stationGenerate
	
	--Si la habitación tiene otras puertas, generar habitaciones en ellas
	while #placesList > 0 and roomCount < Station.rooms do
		local randomPlace = placesList[random:NextInteger(1, #placesList)]
		
		task.wait(waitTime)
		
		task.spawn(function()
			Station.GenerateRoom(randomPlace)
		end)
		
		table.remove(placesList, table.find(placesList, randomPlace))
	end
	
	--Detectar si la estación terminó de generarse
	local lastRoomCount = 0
	while task.wait(waitTime * 2) do
		if roomCount > lastRoomCount then --Si se generó una habitación
			lastRoomCount = roomCount
		elseif roomCount == lastRoomCount then --Si no se generó una habitación
			print("the station has fully generated!")
			break 
		end
	end
	
	--Identificar lugares no usados
	for i, room in pairs(stationGenerate:GetChildren()) do
		local places = room:FindFirstChild("DoorPlaces")
		
		if not places then 
			continue
		end
		
		--Posicionar puertas bloqueadas
		for i, place in places:GetChildren() do
			for i, part in workspace:GetPartsInPart(place) do
				if part.Parent.Name == "DoorPlaces" then
					local newBlockedDoor = blockedDoor:Clone()
					newBlockedDoor:PivotTo(place.CFrame)
					newBlockedDoor.Parent = place.Parent.Parent

					place:SetAttribute("Blocked", true)
					part:Destroy()
					
					print("blocked!")
				end
			end
		end
		
		for i, place in pairs(places:GetChildren()) do
			local hasRoom = place:GetAttribute("HasRoom")
			local blocked = place:GetAttribute("Blocked")
			
			if not hasRoom and not blocked then
				table.insert(unusedPlaces, place)
			end
		end
	end
	
	print("unused places identified!")

	--Generar habitaciones necesarias
	
	--Posicionar ventanas
	for i, place in pairs(unusedPlaces) do
		local room = place.Parent.Parent
		
		local newWindow = window:Clone()
		newWindow:PivotTo(place.CFrame)
		newWindow.Parent = room
		
		place:SetAttribute("Windowed", true)
		
		print("windowed!")
	end
	
	print("station finished!")
end

function Station.Assemble()
	local children = stationGenerate:GetChildren()

	for i, child in pairs(children) do
		child.Parent = station
	end
	
	station.PrimaryPart = station.Porch.PrimaryPart
	station:PivotTo(workspace.Map.Main.StationPart.CFrame)
end

return Station