Creating room generation without overlap

Hey! Currently making a project inspired by Rooms, Doors, such and such but also games like Light Bulb and RED44_SATYR44.

I currently have a basic endless room generator, which works by using room templates and attaching them to the end of previous rooms by using attachments attached to the “base” of the rooms.

My main issue is trying to prevent the rooms from overlapping, which can be seen here:

I’ve been considering adding solutions like a built in “grid” in the script which keeps track of what type of room is where and keeping it from overlapping by forcing different types of rooms in order to prevent situations like that, but I’m unsure on how to implement this. Here’s what I currently have as my generation script:

local previousRoom = workspace.Start

function generateRoom()
	local random = math.random(1,3)
	local room = workspace["Room"..random]:Clone()
	
	local cframeRot = room:GetPivot() * CFrame.Angles(0,previousRoom.Base.Start.Orientation.Y,0)
	room:PivotTo(cframeRot)
	
	local cframePos = previousRoom.Base.End.WorldCFrame * room.Base.Start.CFrame:Inverse()
	room:PivotTo(cframePos)
	
	room.Parent = workspace
	previousRoom = room
end

-- temp endless generation code
while true do
	wait(1)
	generateRoom()
end

I don’t need a full blown script or anything, but an explanation or a rundown on how something like that would work would be great. Thanks!

1 Like

To solve the issue of overlap you could use Workspace:GetPartsInBox() and use Model:GetBoundingBox() to get the size and position of the box. This will give you a list of all parts are inside that box. If this list is empty, then no parts are there and you would be able to place model without fear of overlapping.

4 Likes

Here is an example script that uses a Vector3 to determine if an object is in a certain area.

local function obj_exists_in_area(vector3_obj)
    -- Get a CFrame from the Vector3 parameter.
	local cframe_for_vector3 = CFrame.new(vector3_obj)
	
    -- Returns a table of parts found within the bounds of the CFrame and Vector3.
	local parts_found = workspace:GetPartBoundsInBox(cframe_for_vector3, vector3_obj)
	
	local obj_exists = false
	
	if (parts_found == {}) then
		obj_exists = false
	else
        -- Put logic here to exclude specific parts that you don't care about overlapping.
        -- i.e. for key, value in parts_found do ... end
		obj_exists = true
	end
	return obj_exists
end

updated to be more readable

1 Like

Depending on your type of game play an algorithm change can fix this. Limiting the number of turns can prevent overlap, especially if you are generating a DOORS game instead of say a maze with dead ends and forking paths.

1 Like