Issues with chunk loading

so i’ve made a script that successfully loads and unloads tilemap chunks as needed as the camera sees them
the issue is that sometimes the chunks load in twice, which usues up more resources and inflates the (limited) tilemap count.
i’m really lost on why it’s doing this, the for loops should catch them existing, yet they seem to not sometimes?

chunk managment code here:

	--let's figure out the screen bounds (in terms of chunks)
	local pcy=programdata.ents[1].y/(64*_CHUNKSIZE)
	local cdy=(1080/(64*2*_CHUNKSIZE))
	local pcx=programdata.ents[1].x/(64*_CHUNKSIZE)
	local cdx=((runtime.width/runtime.windowscale)/(64*2*_CHUNKSIZE))

	local whitelistchunks={}
	for y=math.floor(pcy-cdy),math.floor(pcy+cdy),1 do
		for x=math.floor(pcx-cdx),math.floor(pcx+cdx),1 do
			for i=1,#loadedchunks do
				if loadedchunks[i] and loadedchunks[i][1]==x and loadedchunks[i][2]==y then goto noload end
			end
			loadchunk(x, y)
			::noload::
			whitelistchunks[#whitelistchunks+1]={x,y}					
		end
	end


	for i=1,#loadedchunks do
		local v=loadedchunks[i]
		if not v then goto next end

		for i2=1,#whitelistchunks do
			local v2=whitelistchunks[i2]
			if v[1]==v2[1] and v[2]==v2[2] then
				goto next
			end
		end

		if v[3] then go.delete(v[3],true) end
		loadedchunks[i]=nil
		::next::
	end

the loadchunk() function:

function loadchunk(cx,cy)
	local newchunk=collectionfactory.create("/camera#mapchunk",vmath.vector3(_CHUNKSIZE*_WORLDTILESIZE*cx,_CHUNKSIZE*_WORLDTILESIZE*cy,0))[hash"/mapchunk"]
	local tmp=msg.url(nil,newchunk,"chunk")
	if not go.exists(tmp) then return end
	for l=1,#_MAPLAYERS do
		local lay=_MAPLAYERS[l]

		for c=1,#lay.chunks do
			local chunk=lay.chunks[c]
			if chunk.x==cx*_CHUNKSIZE and chunk.y==-1*cy*_CHUNKSIZE then
				for x=1,_CHUNKSIZE do
					for y=1,_CHUNKSIZE do
						tn,tt=extracttile(chunk.data[x+((_CHUNKSIZE-y)*16)])
						tilemap.set_tile(tmp, lay.name,x,y , tn,tt)
					end
				end 
				break
			end
		end
	end
	loadedchunks[#loadedchunks+1]={cx,cy,newchunk}
end

screenshot of debug info in game: (entries 8 and 11, 16 and 18, 15 and 17)

switching this

			for i=1,#loadedchunks do
				if loadedchunks[i] and loadedchunks[i][1]==x and loadedchunks[i][2]==y then goto noload end
			end

to this

			for i,v in pairs(loadedchunks) do
				if v and v[1]==x and v[2]==y then goto noload end
			end

seems to have stopped it?????
this makes no sense, why does it suddenly not happen when using pairs() to iterate instead of length???? all of my indicies are integers.

i want to avoid using using pairs if i can’t help it, and this makes no sense to me.

I’m no Lua expert, but I remember reading about there being quirks of that # operator.

If you’re adding and removing elements, potentially leaving holes in the “array” (table), it may return things you aren’t expecting.

Some interesting examples of when it will & will not return what you expect in this post.

hmmph, it’s frustratingly inconsistent. There’s no pattern to when it decides a hole warrants stopping the length of the table.

i notice that the engines provides a function table.maxn which does #'s job but more consistently.
what’s the performance of maxn versus #?

Yes, you should not count on the length operator behaving correctly if the array has a hole in it.