Perlin noise chunk offset

I want to make a Minecraft like terrain gen system.
I can’t figure out how to make the chunks offset by 1 chunk and create the proper perlin noise.
I tried adding (y + offx) instead of y and (x + offx) instead of x in the noise functions but it looks wrong and there’s jagged pieces randomly.
The terrain is rendered on the client.
How do I get my chunks offset correctly?
My code:

local seed = math.random(1,100000)
function Chunk(offx,offy,offz,seed)
	local mapxsize = 16
	local mapysize = 64
	local mapzsize = 16
	local noisescale = 30
	local amp = 15
	local psize = 3

	local chunk = Instance.new("Folder",workspace.TerrainParts)
	chunk.Name = #workspace.TerrainParts:GetChildren()+1

	local id = 0

	for x = 0, mapxsize do
		for z = 0, mapzsize do
			for y = 0, mapysize do
				id += 1
				local xnoise = math.noise((y + offx) / noisescale, z / noisescale, seed) * amp
				local ynoise = math.noise((x + offx) / noisescale, z / noisescale, seed) * amp
				local znoise = math.noise((x + offx) / noisescale, y / noisescale, seed) * amp

				local density = xnoise+ynoise+znoise+y
				if density < 20 and density > 15 then
					local part = Instance.new("CFrameValue", chunk)
					part.Name = id
					part.Value = CFrame.new((x*psize)+offx*psize, (y*psize), z*psize)
					if part.Value.Position.Y >= 45 then
						
					else
						
					end
				end
			end
		end
	end
end
Chunk(0,0,0,6222)
Chunk(17,0,0,6222)
Chunk((17*2),0,0,6222)
Chunk((17*3),0,0,6222)

Thanks!

You might be doing something I’m not aware of, but I’ve always generated the density for each voxel using one 3D noise. This way, it’s very easy for it to be continuous (and not have jagged stuff).

Here is something like the function I like to use:

local noisePosX = (x + offx) / noisescale  -- Make sure offx is in units of voxels, not chunks (it looks like it is in your code, but maybe it should be 16 instead of 17)
local noisePosY = (y + offy) / noisescale
local noisePosZ = (z + offz) / noisescale
local seedYAddition = seed * math.pi -- The seed is applied to the y so that different worlds are different. If you decide to apply it to the x, z instead, you can also make it so every world exists in every other world but far away (kind of cool).  The math.pi is just to make it not exactly match up with the voxels.

-- Generate the (continuous+smooth) density for the chunk
local density = math.noise(noisePosX, noisePosY + seedYAddition, noisePosZ)

-- Make density in the range [0, 1]
density = (density + 1) / 2
density = math.clamp(density, 0, 1)

-- An example function to determine if the voxel is solid
isSolid = density < (y / mapysize)  -- As the y increases, it becomes less and less likely for the voxel to be solid

One tip from Minecraft’s generation, you can first generate what should be solid, then “paint” on block types from there (e.g. if it’s the first solid block in the column, make it grass or sand (depending on the height), otherwise make it stone).


Here is what that type of density generation looked like from an old project of mine: