Alright, so this is going to be a little confusing for most people out there. To say the least, I am using the math.noise feature and the PolyDraw module to generate infinite terrain. I recently added a section that should dynamically generate it with less detail the farther it is away, but when I tested the implementation, it failed to work. I know of some bugs unrelated to this that need resolved, but I want it to actually generate before I fix my oversights. Can anyone tell me why it will not run even though nothing is showing up in the output?

local PolyDraw = require(script.PolyDraw)

local SeedOffset = 65536
local ChunkSize = Vector2.new(17, 17)
local TileSize = 32
local First = true

local Chunks = {}

local function GenerateTriangles(Chunk, XOffset, YOffset, NX, NY)
	for X = 0, ChunkSize.X-1 do
		if X ~= ChunkSize.X-1 then
			for Y = 0, ChunkSize.Y-1 do
				if Y ~= ChunkSize.Y-1 then
					local A, B, C, D = Chunks[Chunk.Name][X .. ":" .. Y], Chunks[Chunk.Name][X + 1 .. ":" .. Y], Chunks[Chunk.Name][X .. ":" .. Y + 1], Chunks[Chunk.Name][X + 1 .. ":" .. Y + 1]
					local Tri1 = PolyDraw.Tri.new(Chunk, A, B, C)
					local Tri1 = PolyDraw.Tri.new(Chunk, B, C, D)
					if NX ~= 0 and NY ~= 0 and First == false then wait() end
				end
			end
		end
	end
end

local function GenerateNodes(XOffset, YOffset, NX, NY)
	local Chunk = Instance.new("Model", game.Workspace)
	Chunk.Name = XOffset .. ":" .. YOffset
	
	local Chunksize = ChunkSize	
	
	if NX == -2 or 2 then
		Chunksize.X = ((ChunkSize.X - 1)/4)+1
	elseif NX == -1 or 1 then
		Chunksize.X = ((ChunkSize.X - 1)/2)+1
	end
	
	if NX == -2 or 2 then
		Chunksize.Y = ((ChunkSize.Y - 1)/4)+1
	elseif NX == -1 or 1 then
		Chunksize.Y = ((ChunkSize.Y - 1)/2)+1
	end
	
	for X = 0, Chunksize.X-1 do
		for Y = 0, Chunksize.Y-1 do
			local Noise = math.noise((X + (XOffset * (Chunksize.X-1))) / 32 + SeedOffset, (Y + (YOffset * (Chunksize.Y-1))) / 32 + SeedOffset)
			local Node = Vector3.new((X + (XOffset * (Chunksize.X-1))) * TileSize, Noise * 350, (Y + (YOffset * (Chunksize.Y-1))) * TileSize)
			Chunks[XOffset .. ":" .. YOffset][X .. ":" .. Y] = Node
		end
	end
	GenerateTriangles(Chunk, XOffset, YOffset, NX, NY)
end

game.Players.PlayerAdded:connect(function(Player)
	repeat wait() until Player.Character
	local function OnDeath()
		local Character = Player.Character
		coroutine.resume(coroutine.create(function()
			while true do
				local LoadedChunks = {}
				local Chunk = Vector2.new(math.ceil((Character.Torso.Position.X / TileSize + (ChunkSize.X-1))/(ChunkSize.X-1))-2, math.ceil((Character.Torso.Position.Z / TileSize + (ChunkSize.Y-1))/(ChunkSize.Y-1))-2)
				print(Player.Name .. ":" .. Chunk.X .. ", " .. Chunk.Y)
				for NX = -2, 2 do
					for NY = -2, 2 do
						Chunks[Chunk.X + NX .. ":" .. Chunk.Y + NY] = {}
						GenerateNodes(Chunk.X + NX, Chunk.Y + NY, NX, NY)
						
						LoadedChunks[Chunk.X + NX .. ":" .. Chunk.Y + NY] = true
						if First == false then wait() end
					end
					wait()
				end
				for i, v in pairs(game.Workspace:GetChildren()) do
					if v:IsA("Model") and v:FindFirstChild("Humanoid") == nil then
						if LoadedChunks[v.Name] == nil then
							v:Destroy()
						end
					end
					wait()
				end
				First = false
				repeat wait() until Chunk ~= Vector2.new(math.ceil((Player.Character.Torso.Position.X / TileSize + (ChunkSize.X-1))/(ChunkSize.X-1))-2, math.ceil((Player.Character.Torso.Position.Z / TileSize + (ChunkSize.Y-1))/(ChunkSize.Y-1))-2)
			end
		end))
	end
	
	OnDeath()
	
	Player.Character.Humanoid.Died:connect(function()
		repeat wait() until Player.Character
		OnDeath()
	end)
end)

The only thing not shown here is the code for the Tri.new function, but I know for a fact that it works the way it should. All I need help with is the code from lines 31 to 41. That should determine how much terrain to load, but no terrain loads ever since I implemented this.