Automatic Tile Updating

Hey everyone,

I’ve been struggeling on this one thing for a bit of time now. You probably all know Clash of Clans, if not, it’s whatever. My problem is, that i dont know how i could script a automatic “wall” update algorithm.

The basic’s I already have:

→ presets for the walls

A building system.

And this:

function updateWalls(wall)

	local wallsNextTo = {} -- with max 4 walls


	-- insert walls into table if they are next to the wall placed
	for index, wallToCheck in pairs(workspace.Walls:GetChildren()) do
		if wallToCheck ~= wall then
			local distance = (wallToCheck.PrimaryPart.Position - wall.PrimaryPart.Position).Magnitude

			if distance == 4 then
				table.insert(wallsNextTo, wallToCheck)
				--print(distance, wallToCheck, "Position X: " .. wallToCheck.Base.Position.X, "Position Z: " .. wallToCheck.Base.Position.Z)
			end
		end
	end
end


workspace.Walls.ChildAdded:Connect(updateWalls)

Now my question is:

What would be the best possible way to find out which piece of wall goes where and how would i update the wall, just by replacing it? Like this:

Thanks for your help

1 Like

you could check neighbouring walls, and change the model respectively, with raycast or if you have a grid system, use it

how would any of these ways work?

Every time you place down a wall, cast 4 rays around it. If it hits any walls, update the walls.

To update walls you can do some sort of checking system. One idea is to make a table of all the walls as the index, which contains a table value of the necessary walls around it to make this certain wall. My explanation might not be top tier, but here’s a visual example:

local Walls = --> the location of all the walls
local wallTab = {
    [Walls.WallExampleOne] = {
        "Left", --> when checking, there must be a left wall
        "Right", --> when checking, there must be a right wall
        "Top", --> etc.
    },
     [Walls.WallExampleTwo] = {
        "Left",
        "Top",
    },
    --> etc.
}

To check for walls, you can use a grid system if you have one, or raycast around the wall:

local function getNeighboringWalls(position: Vector3) --> Vector3 position of where the wall is placed
    local leftRay = workspace:Raycast(position, Vector3.new(-5, 0, 0), whateverParams)
    local rightRay = --> cast a ray on the right side
    local topRay = --> cast a ray on the top side
    local bottomRay = --> cast a ray on the bottom side
    
    return leftRay, rightRay, topRay, bottomRay --> returns rays
end

To check which wall to use, use the wallTab table. We will then match the left, right, top, and bottom sides:

local function getWallNeeded(position: Vector3) --> Vector3 position of where the wall is placed
    local left, right, top, bottom = getNeighboringWalls(position)

    for Wall, needed in pairs(wallTab) do --> going through the [wallTab] table
        --[[
            Notice how we match every wall. This is to prevent walls with less required surrounding
            walls from being chosen on accident. For example, if one Wall1 only requires a left wall
            and Wall2 requires a left AND right wall, Wall1 might be chosen by accident. If we match
            every wall, we will also match the things the specified wall SHOULDN'T have.
        --]]
        if left and not table.find(needed, "Left") --> if there's a left wall but this wall shouldn't have a left wall next to it
            or table.find(needed, "Left")  then --> if there isn't a left wall but a left wall needs to be present
            continue --> go to next wall
        end
        if right and not table.find(needed, "Right")
            or table.find(needed, "Right")  then
            continue
        end
        --> repeat checks for top and bottom
        
        return Wall --> if all checks are met, return the correct wall
    end
end

Use getWallNeeded to get the correct wall when placing one:

Wall.Placed:Connect(function(positionPlaced: Vector3)
    local WallToUse = getWallNeeded(positionPlaced)
    
    --> go through neighboring walls and update them
    local left, right, top, bottom = getNeighboringWalls(positionPlaced)
    --> replace left, right, top, and bottom walls if there is one
end)
1 Like

thats also a good way! Ty but i already figured something out on my own! And i needed a way to implemement T-Segments for the walls as well.

Looks something like this! Color just for reference.

I probably used too many lines of code for that but its working!

(this is just for the T-Piece)

2 Likes

you can use :GetPartsInBoundingBox though, however i dont know which is faster.