I’ve been down that rabbit hole too, so many demos & zero code you can actually pull into your game but I did find quite a few repo’s that are pretty useful 
we have a chunked, greedy meshing world with perlin terrain, async chunk loading, hidden-face culling and block destruction mineblox although a bit more complicated to set up.
or a pure-lua heightmap generator (rivers, lakes, forests) domain warped perlin noise RTerrainGenerator which is very simple.
If you wanna learn how to do it yourself, there are some examples.
Single Voxel example which shows you how to spit out a 4x4x4 voxel, create voxel terrain

or we could simply make our own with Roblox’s own WriteVoxel() function like in the previous example.
code for it, incase you are interested;
local region = Region3.new(
Vector3.new(0, 0, 0),
Vector3.new(64, 32, 64)
)
local function generateSuperMultiTerrain(regionInput)
assert(typeof(regionInput) == "Region3", "Expected a Region3!")
local RES = 4
local STEP = 2
local aligned = regionInput:ExpandToGrid(RES)
local size = aligned.Size / RES
local mats, occs, water = {}, {}, {}
for x = 1, size.X do
mats[x], occs[x], water[x] = {}, {}, {}
for y = 1, size.Y do
mats[x][y], occs[x][y], water[x][y] = {}, {}, {}
end
end
for sx = 1, size.X, STEP do
for sy = 1, size.Y, STEP do
for sz = 1, size.Z, STEP do
local r = math.random()
local mat
if r < 0.25 then
mat = Enum.Material.Sand
elseif r < 0.50 then
mat = Enum.Material.Cobblestone
elseif r < 0.75 then
mat = Enum.Material.Grass
else
mat = Enum.Material.Mud
end
local occ = 1
for dx = 0, STEP-1 do
for dy = 0, STEP-1 do
for dz = 0, STEP-1 do
local x, y, z = sx+dx, sy+dy, sz+dz
if x <= size.X and y <= size.Y and z <= size.Z then
mats[x][y][z] = mat
occs[x][y][z] = occ
water[x][y][z] = 0
end
end
end
end
end
end
end
return {
SolidMaterial = mats,
SolidOccupancy = occs,
LiquidOccupancy = water,
}
end
local content = generateSuperMultiTerrain(region)
workspace.Terrain:WriteVoxelChannels(region, 4, content)
I hope this helps you out to some extent, happy developing! 