Thank you for providing the visual example, it helped me immediately understand how your code works.
Before I proceed with a more formal proposal, theres one thing that I noticed in the video which I believe needs to be resolved or clarified. In your video, from 0:20 to 0:22, there was a room trying to spawn with no visible collisions blocking its path. However, none of the rooms spawned. Is this an error or intended behavior?
Moving onto the main topic: Unfortunately, solving the problem of dead ends as you want it will take a lot of ingenuity and work, as far as I can tell. I don’t think it’s impossible. However, this may only work for about half of dead end cases you want to fix.
I think it would involve:
-
adding as many connectionpoint places on your rooms as possible (even hallways). You can make two types of connectionpoints, (1) a dual type connection point, that works for the actual connection of rooms like you have currently and also for connecting a “dead end” connection point to an unused connection point in another room, and (2) a connection point SOLELY for connecting a “dead end” connection point to an unused connection point in another room.
-
Make the connection point areas (even for both types of connection points as described above) to initially have “open” or “exposed” walls, like you are currently doing for connection points. Make sure these gaps are being filled in with walls at the very end of everything if they were not used to connect rooms.
-
Do not resolve dead ends (do not close the wall off) immediately. Leave that for either what im about to say nedt will happen (connecting a dead end!
), or for the italicized sentence in point 2 to happen (dead end will happen
).
-
Implement something along the lines of this, right before the step of closing off the walls and right after all rooms have been placed:
local connectedPoints = {}
local function isConnected(point)
return connectedPoints[point] == true
end
function processConnectionPoint(TargetPoint)
if not isConnected(TargetPoint) then -- You need to identify these connected target points each time you spawn a room
local nearbyPoints = FindNearbyPoints(TargetPoint)
for _, point in pairs(nearbyPoints) do
ConnectRooms(point.Room, TargetPoint.Room) -- Algorithm to connect both points. This will be challenging to implement and will require some knowledge of geometry.
if noCollisions() then -- Do a collision check for this newly created room
connectedPoints[TargetPoint] = true
connectedPoints[point] = true
return true
end
end
end
return false
end
for _, room in pairs(AllRooms) do -- AllRooms should be every single room spawned
for _, TargetPoint in pairs(room.Points:GetChildren()) do
processConnectionPoint(TargetPoint) -- Call the function for each connection point
end
end
I may have implemented or wrote this incorrectly, but it should look something like that. The FindNearbyPoints(TargetPoint) function could look something like this:
function FindNearbyPoints(TargetPoint)
local nearbyPoints = {}
-- Iterate through all rooms or connection points, identifying ones within a certain range
for _, room in pairs(AllRooms) do
for _, point in pairs(room.Points:GetChildren()) do
if (point.Position - TargetPoint.Position).Magnitude < CONNECTION_RANGE then
table.insert(nearbyPoints, point)
end
end
end
return nearbyPoints
end
As for ConnectRooms(point.Room, TargetPoint.Room), this will require a great deal of geometry and mathematics to size a room to connect to a part. I think having a room that can dynamically change its sizes (like an xz length that can change sizes in any direction to be able to connect to another connection point) would be the way to go. Its walls would also have to size as well. If theres a connection a floor above or below (which the differences in Y between the connection parts would tell as well), perhaps the first step of this function would be to spawn the stair room you have, and then go from there to connect it to the open connection point of another room via x and z sizings of an additional fledible room part. I have a rough idea of how I could implement it in my mind, but it would take a lot of time to pan it out. Maybe if I have time in the net couple of days, I might provide something that may complete this function.
EDIT: In the FindNearbyPoints function, you may want to do a range check for the rooms (a slightly bigger range than the connecting parts check) as well as a range check for the connecting parts. This is done to increase the performance and speed of the code.
Thats all for now : )