Terrain is not generated where the player is located

Hi all! Sorry for the fact that this is the second post in the last two days.


The problem is that if I start walking along one axis, then the generation goes well, but if I decide to go in the opposite direction or change the direction axis, then the generation will have to wait, and provided that generation occurs only when the player moves , then just standing around and waiting won’t work.
Please help me find the problem in my script that causes this error


Code:

local Players = game:GetService("Players")
local RS = game:GetService("ReplicatedStorage")
local assetLibrary = RS:WaitForChild("Assets")
local trees = assetLibrary:WaitForChild("Trees")
local rocks = assetLibrary:WaitForChild("Rocks")
local perlinFolder = workspace:WaitForChild("PerlinTest")
local terrain = workspace:WaitForChild("Terrain")
local periodicity = 60
local size = 100
local chunck = {}
local seed = math.random()*30
local rnd = Random.new(os.clock())
print(seed)
local amp = 80
local materials = {
	[1] = Enum.Material.Ground,
	[2] = Enum.Material.Grass,
	[3] = Enum.Material.Granite,
	[4] = Enum.Material.Sand,
	[5] = Enum.Material.Snow,
	[6] = Enum.Material.Mud,
}
local lastWait = tick()
local EXEC_TIME_LIMIT = 1/90
local smartWait = function()
	if tick() - lastWait > EXEC_TIME_LIMIT then
		task.wait()
		lastWait = tick()
	end
end

local Tree_Scale = 0.6


function SelectMaterial(x,z)
	local xNoise = x/50
	local zNoise = z/50
	local noise = math.noise(xNoise,zNoise,seed)+1
	local delta = #materials/2
	local num = math.floor(noise*delta)
	if num < 1 then
		num = 1
	elseif num > #materials then
		num = #materials
	end


	return materials[num]
end



function NoizeCount(x,z)
	local xNoise = x/50
	local zNoise = z/50
	local noise = math.noise(xNoise,zNoise,seed)*periodicity+amp 
	return noise
end

function CheckChunk(x,z)
	local ret = nil
	if chunck[x] == nil then
		chunck[x] = {}
	end
	ret = chunck[x][z]
	smartWait()
	return ret
end

function EntitySpawn(CFramePos:CFrame)
	if rnd:NextInteger(1,10000) <= Tree_Scale*100 then
		local pos = CFramePos.Position
		local params = RaycastParams.new()
		local dir =-Vector3.yAxis*50
		params.IgnoreWater = true
		local ray = workspace:Raycast(pos+Vector3.new(0,10,0),dir,params)
		warn(ray.Material)
		if ray.Material == Enum.Material.Grass then
			local treeArray = trees:GetChildren()
			local random = math.random(1,#treeArray)
			local newTree:Model = treeArray[random]:Clone()
			local cx=pos.X
			local cz=pos.Z
			local cy=pos.y

			newTree:PivotTo(CFrame.new(cx, cy + newTree.PrimaryPart.Size.Y*0.5, cz)) -- переместить
			newTree.Parent = workspace
		end
		
		if ray.Material == Enum.Material.Ground then
			local rocksArray = rocks:GetChildren()
			local random = math.random(1,#rocksArray)
			local newRock:Model = rocksArray[random]:Clone()
			local cx=pos.X
			local cz=pos.Z
			local cy=pos.y

			newRock:PivotTo(CFrame.new(cx, cy + newRock.PrimaryPart.Size.Y*3.2, cz)) -- переместить
			newRock.Parent = workspace
		end
	end
end

function WorldGenerate(posX,posZ)

	warn(posX,posZ)
	for x=posX-size,posX+size do

		for z=posZ-size, posZ+size do
			if CheckChunk(x,z) == nil then
				--print("Start generation")
				chunck[x][z] = true
				local part = Instance.new("Part",perlinFolder)
				part.Shape = Enum.PartType.Block
				part.Anchored = true
				local y = NoizeCount(x,z)
				local y1 = y - 4^2
				part.Size = Vector3.new(4,(y-y1)/2,4)
				part.Position = Vector3.new(x*4,(y+y1)/2,z*4)

				terrain:FillBlock(part.CFrame,part.Size,SelectMaterial(x,z))
				EntitySpawn(part.CFrame)
				part:Destroy()
			end
		end
		smartWait()
	end
	print("End generation")
	task.wait()
end



function CharacterMoved(character)
	local oldX = nil
	local oldZ = nil
	repeat
		if character and character.Parent then
			local coordinates = character:WaitForChild("HumanoidRootPart"):GetPivot()
			local posX = math.floor(coordinates.Position.X)
			local posZ = math.floor(coordinates.Position.Z)
			if posX ~= oldX or posZ ~= oldZ then
				warn("Генерация началась в ", posX,posZ)
				WorldGenerate(posX,posZ)
				oldX = posX
				oldZ = posZ
				smartWait()
				end
		else
			smartWait()
			return
		end
		smartWait()
	until not (character and character.Parent)
	smartWait()
end

function CharacterAdded(character)
	task.spawn(CharacterMoved,character)
end

function PlayerAdded(player:Player)
	player.CharacterAdded:Connect(CharacterAdded)
end

Players.PlayerAdded:Connect(PlayerAdded)

Video


Thanks for your help! :hearts:

Help me pleasee i don’t know how fix it(