How do I make a cave generation system?

I’ve been trying to make a mining game and I’ve gotten the mining, inventory, and random ore chance to work, however I cannot get the cave generation to work.

How would I accomplish generating a cave that also doesn’t get in the way of already generated blocks, and how would I make it randomized?

You could start here as it is a full working system. Would be rather tough to answer your question in the forum as it is rather involved. I will also add that cave generation can be tricky and not very performant. Games like Mining Simulator 2 removed their cave generation and it may be because of the performance issues.

I looked through a lot of that kits cave generation and the scripting in this is hard for me to read (could be either that it’s messy or more likely I’m inexperienced with that kind of stuff) but the math.noise stuff in there doesn’t make sense at all to me. I’ll try taking a second look and seeing if I can decipher what it’s trying to do.

The code still doesn’t make sense after looking at it for multiple hours. I’ve tried looking everywhere but nowhere on the dev forum is there truly a source for cave gen besides this kit- which is incompatible with my game.

Yeah the usual methods using perlin noise or perlin worms to generate caves isn’t for the faint of heart if you can’t just use code that is already out there. You could maybe take some time and hand generate a couple different caves on your own and then save their structure and put them in at random spots in your mine.

If you’re using blocks for your mining game, a quick solution would be to randomly pick a few blocks randomly and delete all blocks in a randomly-sized sphere around those selected blocks to create caverns.

Here is somewhat of an example:

local blocks = workspace.BlocksFolder

local blockWhitelist =
blockWhitelist.FilterType = Enum.RaycastFilterType.Whitelist
blockWhitelist.FilterDescendantsInstances = blocks

local r =

for i = 1, r:NextInteger(5, 20) do
	local list = blocks:GetChildren()
	local randomBlock = list[r:NextInteger(1, #list)]
	local nearbyBlocks = workspace:GetPartBoundsInRadius(
		r:NextInteger(randomBlock.Size*2, randomBlock.Size*10),
	for _,blockInRadius in ipairs(nearbyBlocks) do

It’s not as fancy as a noise function but it should run faster if optimization is what you’re looking for.

Hope this helps!

1 Like