How to achieve a procedeural cave generation?

Hi, I’ve been trying to create an endless mining game, however I want to sometimes spawn a random cave, I have read several topics on the devforum on the perlin noise cave generation, but I have only managed to achieve this:

What I wanted to achieve, is a cave similar to “Minecraft” with an empty space inside of it where the player can walk around

Using this code:

-- Settings
local caveSizeMin = 5
local caveSizeMax = 16
local caveThreshold = 0.475

-- Spawn a cave
-- entitySize is just the size of one side of an ore, since it is equal
for i = rand:NextInteger(caveSizeMin, caveSizeMax) * entitySize, 0, -entitySize do
	for j = rand:NextInteger(caveSizeMin, caveSizeMax) * entitySize, 0, -entitySize do
		for k = rand:NextInteger(caveSizeMin, caveSizeMax) * entitySize, 0, -entitySize do
			 -- entity is the ore that is broken by the player (The event is called upon breaking an ore)
			local position = entity.Position - Vector3.new(i, j, k)
			local noise = math.noise(position.x, position.y, position.z)
			if noise >= caveThreshold or noise <= -caveThreshold then
				usedPositions[position] = true -- Block spawning another ore here (air)
			else
				infiniteMine.GenerateOre(position) -- Spawn a new ore
			end
		end
	end
end

EDIT: Added print to the code, turns out is always spawns an ore, not a single block was an “air” for some reason