The way my terrain generator works is use perlin noise and make a matrix with the results. Depending on the distance, however, some weird shapes are created, such as this one:
Not knowing the code, its really hard to say, but just from looking I would think however you are âfillingâ the terrain, you might be off a little on a float value or something to where it is not filling the terrain all the way to the bottom, or, where it looks like two columns lower and upper terrain collide, the half filled lower terrain is making a gap before the filling of the upper terrain.
The only way I could think to filter from this pic, is to read the entire column, and once you hit âsolidâ reading down the column, make sure all voxels that are non empty (occumancy 0) are full, (100% occupancy), as you go down, stopping only when you hit an empty and resetting the conditions
The way this works is it gets a matrix (multiple tables of different Y values for every X) and just does Terrain:FillBlock() for each coordinate. I believe this may be terrain just trying to fill empty space caused by Perlinâs noise? Ideally, I would have some criteria to âfillâ the parts of the matrix that cause this. Idk what criteria that could be though, and thatâs where I am lost.
From the image it looks like you have a âstartâ and âstopâ to each column, where you put grass at the start and fill with rock the rest of the way.
So how are you getting multiple âstartâ (grass) areaâs if you just have a matrix of X locations with Y values, or does each X have multiple Y locations where a column starts?
No, no!
Instead, what I am doing is checking for each element in the matrix, if the two coordinates above them on the Y axis are empty! If they are, Iâll generate grass, instead.
oh ok, so its a matrix where each X has a table of Y cells, where you can determine âspacesâ and add grass. I was thinking of it as a linear table with X elements and each element was a Y height value.
So, it looks like it is putting grass, thinking the area has 2 empty cells above it. (is the grass filling one of those empty cells?) Make sure the grass is overwriting the top layer of rock when you check for two empty above.
My problem is not really the grass. Instead, it is forming those squares. I dont know the circunstances in which similar stuff happens. The grass has nothing to do with it, it is mainly decoration.
I suppose I donât really understand what is the âproblemâ with the squares, considering you allow for spaces between layers (having some terrain above and below an empty area)
So is the problem that the empty space (the squares) is just so small, that you would like to fill it in? Or is it that yo donât want empty space created if its not accessible (its an island of empty space) , or is it just the âsharpnessâ of the squares? would you like them to be more âsmoothâ of an opening?
I suppose I am just trying to understand how the squares are wrong, or why they shouldnât be there. What would you like the correct result to look like in that situation?
I think that when you look to the image, you can see the squares look wrong. I would just like to know how to fill them in or kind of âdisableâ their existance. Not only is the space small, but it looks really weird. That is what I am trying to prevent.
Well some thoughts on this⌠First, if you are checking for 2 spaces of air above ground, when putting grass, this should not happen as there is only one space of air above those grass patches, (making the space look really small and âsquareâ) I feel like the grass is overwriting one of the spaces of air, making it have only 1 space of air, or, the code where you check for 2 spaces of air is incorrect and its only checking for 1 space of air.
Another thing to think about, is since you have a matrix of values, you can parse it for small spaces (<= 2 spaces of air high) and see if those spaces have air or solid in the columns left and right. If its solid left and right, just fill in those cells. I would do this sort of check before I check for grass.
Also you could keep a variable that keeps a range of âopenâ space start and end of each column, and if you find space in the next column and it doesnât match up with any previous space start and end of the column before, then you know its an island of air most likely and you can fill it.
function map.Fill(list)
local copy = list
local Filtered = false
for x, yey in pairs(copy) do
local zeros = 0
for y, val in pairs(yey) do
if val == 0 then
zeros += 1
else
if zeros > 0 and zeros <= 4 then
Filtered = true
for i=1, zeros do
copy[x][y - i] = 1
end
zeros = 0
end
end
end
end
for y=1, #copy[1] do
local zeros = 0
for x, val in pairs(copy) do
if val == 0 then
zeros += 1
else
if zeros > 0 and zeros <= 4 then
Filtered = true
for i=1, zeros do
copy[x-i][y] = 1
end
zeros = 0
end
end
end
end
return copy, Filtered
end
This is still not working.
Should I read diagonals as well?
function map.Fill(list)
local copy = list
local threshold = 4
local filtered = false
local coollist = {{2,2}, {-2,2}, {2,-2}, {-2,-2}, {-2,0}, {2,0}, {0,-2}, {0,2}}
for x, yey in pairs(copy) do
for y, val in pairs(yey) do
if val == 1 then
for _, combo in pairs(coollist) do
local v = 1
local suc, er = pcall(function()
v = copy[x+combo[1]][y+combo[2]]
if v == nil then
error("rip")
end
end)
if v == 1 and suc then
filtered = true
copy[x+combo[1]][y+combo[2]] = 1
copy[x + combo[1]/math.max(1, math.abs(combo[1]))][y + combo[2]/math.max(1, math.abs(combo[2]))] = 1
end
end
end
end
end
return copy, filtered
end
It seems to be filtering this problem just fine. Thanks for the support.