Gaps Appearing in Randomly Generated Terrain (Visible blocks only)

I don’t have any idea why this part of the script isn’t working in checking blocks from other chunks, even if I am sure everything here is right. The WorldBlocks dictionary has the chunk dictionaries, which are called Chunk..X..Y..Z, in which the X, Y, and Z values are the chunk’s position (16x16 in blocks). In the chunk dictionary, there are blocks which are also uniquely called by position (Block..X..Y..Z). This position is the position of the block (1x1). I am just confused how this part is not working, and if I did something wrong.

Code:

function GetBlockFromPosition(WorldBlocks,X,Y,Z)
	local ReturnValue = nil
	local CalculatedChunk = {X = math.floor(X/16),Y = math.floor(Y/16),Z = math.floor(Z/16)}
	local ChunkBlocks = WorldBlocks["Chunk"..CalculatedChunk.X..CalculatedChunk.Y..CalculatedChunk.Z]
	if ChunkBlocks then
		if ChunkBlocks["Block"..X..Y..Z] then
			ReturnValue = ChunkBlocks["Block"..X..Y..Z]
		end
	end
	return ReturnValue
end

Since you don’t have caves in your generation, you should save chunks as only X and Z
I suggest you have the chunks saved under just X and Z

Well, I will be adding caves into the generation at some point, since those seem interesting to try and generate, would I still not include Y chunk saving?

If you had the chunks as something like this:
-worldblocks
—X,Z chunks as /16(so like chunk who’s corner is at 32,64 would be chunk 2,4
—-X,Z blocks relative to chunk, so like block 35,67 would be block 3,3 of chunk 2,4
—-block value should contain Y altitude
Let’s say a block is 0,4 of chunk 3,4, then it should check the Y of block 16,4 of chunk 2,4

This should work

Oh. I though you wouldn’t have caves. In this case, that changes some things to how the generation I initially suggested should work.
Some changes to mention to what I suggested earlier:

  • I suggest you add a perlin noises cave generation below the perlin noises of mountains, it will look better
    -since I suggested to ended as far as lowest altitude was, this actually won’t work with caves
    With caves, you should instead be looking for vertical segments. Let’s say that mountain is at Y=120 highest. It should first for ant lowest of the first cave below. You could do that by, let’s say you got a cave who’s roof at an XZ location is Y=60, then now you will need it to go from 120 all way down to 60, or, instead, you can go make it from 120 to let’s say, Y=80 if 80 is lowest adjacent top surface. Then have one start from Y=60 yo let’s say, Y=70, where a highest adjacent cave ceiling is

In the case however of adjacent chunks, it shouldn’t matter if it’s a cave part of mountain part. You should be doing the same: look for lowest adjacent floor or ceiling. Note that for the ceilings, the adjacent ceiling may be lower than the ceiling of that coordinate. This is why you must look for both lower at ceiling and lowest roof adjacent. Let’s say yours has a cave at 180Y, adjacent has a part that starts at 180Y all way down to 170Y, you should end at 180Y. You should always end at the higuest ceiling found on the XZ located below the floor of that segment of that coordinate and if not, lowest floor that is adjacent and that is lower than the floor of that coordinate. When the point at wich a Pilar ends is found, repeat by getting higuest floor of a cave below that is lower than the ceiling of that Pilar, and repeat until you hit bottom

Since you plan to add caves, yes you need to save the Y of the higuest of a segment at each XZ, along with the Y of the lowest of that segment. Giving you vertical segments for each caves stacked on each other along an XZ pillar. However, chunks may keep only XZ

Alright, thanks for the info on that. One other question, when I attempt to generate chunks on a 0 axis (x or z), there are always holes that appear in the map along those chunks. Not too sure how this happens, unless this is just a bugged feature of math.noise.

It depends how you implemented it. Did you have your perlin noise or something multiply by 0?

In the code to generate the perlin noise, I do not have any multiplication in it. This is what it looks like:

function GenerateNoise(x,y,z,ChunkMultiply,NoiseScale,Amplitude,Seed)
	local XNoise = math.noise((y + ChunkMultiply.y)/NoiseScale,(z + ChunkMultiply.z)/NoiseScale,Seed)*Amplitude
	local YNoise = math.noise((x + ChunkMultiply.x)/NoiseScale,(z + ChunkMultiply.z)/NoiseScale,Seed)*Amplitude
	local ZNoise = math.noise((x + ChunkMultiply.x)/NoiseScale,(y + ChunkMultiply.y)/NoiseScale,Seed)*Amplitude
	local Density = XNoise + YNoise + ZNoise + (y+ChunkMultiply.y)
	return Density
end

(Small note: The code is based off of a tutorial on YouTube, so I may not 100% understand everything if something was wrong here)

From what I remember, having 0 as coordinate shouldn’t affect it.

But I didn’t do perlin noise cave generation for a game since about 2 years so I’m a bit rusty on it. Although I do remember that coordinates 0 was not causing issues in cave generations I’ve made

Can you try to do a print of all the parameters from that function aswell as the returned density? It might help me see why.

I assume you are using if density < a certain ammount then = air

This is what it looks like if I attempt to generate at 0,0,0 in the world:

The output seemed to have a steady pattern, however, suddenly an exact number appeared: image

(The format is XNoise,YNoise,ZNoise, and Density)

That’s weird. Other chunks generate normally?

I think it would help better to also get the x,y,z coordinates along each prints. That way we could find out wich coordinates caused problems.

The output for this is very long, so I put it in a txt file if you would like to see that. I also don’t really know what exact part to send, so I’ll just send the entire output.

x,y, and z are added at the end this time.

Output.txt (461.3 KB)

Hey it’s almost 4am and I’m in bed on mobile. Tommorow I’ll go look at my cave generator because I’m a bit rusty on it. I’ll bring that code tommorow as it might really help. I remember that my cave density was implement in a different way that didn’t have that coordinate 0 issue. It was achieving the same goal though: have no a higuer density near surface, and more caves Aw you go deeper

Alright, thank you for all the help so far, I’ll try to figure things out for now, and see how far I get with it.

I might just give you the code for it tommorow. I never actually made a game with it and it was years ago. Will actually make some use for it

I experimented a bit with noise stacking, and ended up with descent results. As you had said, the terrain does look more natural/rocky, and less wavy. I just used the generate terrain function 1 time with the regular game seed, then used math.randomseed() to generate one positive, and one negative seed with math.random() so that there would be 2 non-identical different seeds, which will always be the same with every original seed. I then use that new seed to generate 2 more sets of “density”, which multiplies that result by a number between 2-0.01x, which is determined by math.randomseed() set as the new seed, and using another math.random() to get the specific number for that seed. (This repeats twice) Once I have all 3 densities, I just add them together, and this is an example of what I get:

It does look a lot less smoother than without stacking layers, and doesn’t look too terribly uneven.

I also generated this map too, which is probably the best one I’ve seen so far:


That’s cool! Looks pretty neat

I actually managed to fix the chunks not loading in by using the greedy meshing technique. I think that parts wouldn’t register in the visible sides only script, but this method will check all blocks in one chunk, and combine them into fewer parts, so this method does not rely on the other chunks like the previous one did. I also managed to generate textures onto the blocks, using the tile method. (I created the textures)

This is what it looks like when you load chunks around 0,0: