Unique chunk ID

Doesn't fit in the other categories, like libraries, small fixes or modpacks.
Natha
Filter Inserter
Filter Inserter
Posts: 279
Joined: Sun Mar 15, 2015 1:48 pm
Contact:

Unique chunk ID

Post by Natha »

I hope this is the right place...

This is a helper method for all modders who store positional data. Instead of having a storage table

Code: Select all

{ [x] = { [y] = {..., ...} }
, which is bad programming and nil-checking, there is something better.
2D positions are a countable set which means you can assign each {x, y} element a natural number. I wrote a spiral function for that in LUA, based on https://web.archive.org/web/20141202041 ... miserably/:

Code: Select all

function spiral(pos)
	local x = math.abs( {table.unpack(pos)}[1])
	local y = math.abs( {table.unpack(pos)}[2])
	local a = math.max(x, y)
	local dist = 0
	
	local i = 0
	while y > x or y >= -x do -- rotate by 90° (multiply by -j) until values are in the top triangle
		p = {-y, x}
		dist = dist + 2*a
		i = i + 1
		if i == 5 then break end
	end
	dist = dist + a - x
	return dist + ((a*2)-1)^2
end
Just give a position (tile or chunk) and a unique ID you get!
User avatar
Osmo
Fast Inserter
Fast Inserter
Posts: 141
Joined: Wed Oct 23, 2024 12:08 pm
Contact:

Re: Unique chunk ID

Post by Osmo »

Alternatively use x+y*524288 :)
Since the game stores positions as fixed 32-bit numbers with 8 bits for decimal precision, that means the maximum map coordinate is 2^24. A chunk has 32 or 2^5 tiles, dividing one by the other would give a value large enough for every chunk in the game. 2^24/2^5 = 2^19 or 524288.
Natha
Filter Inserter
Filter Inserter
Posts: 279
Joined: Sun Mar 15, 2015 1:48 pm
Contact:

Re: Unique chunk ID

Post by Natha »

Osmo wrote: Sun Sep 07, 2025 11:58 pm Alternatively use x+y*524288 :)
Since the game stores positions as fixed 32-bit numbers with 8 bits for decimal precision, that means the maximum map coordinate is 2^24. A chunk has 32 or 2^5 tiles, dividing one by the other would give a value large enough for every chunk in the game. 2^24/2^5 = 2^19 or 524288.
Interesting approach. Do you ahve a source about how positions are stored?
However your calculation only works with chunk positions, as tile positions would give duplicate values
When using with chunk positions only, you can use 62501 instead of 524288, as there will only be 62500 chunks per axis.
eugenekay
Filter Inserter
Filter Inserter
Posts: 695
Joined: Tue May 15, 2018 2:14 am
Contact:

Re: Unique chunk ID

Post by eugenekay »

Natha wrote: Tue Sep 09, 2025 4:13 pmDo you ahve a source about how positions are stored?
The Factorio Wiki states that the Map is clamped to a size of +/- 1M tiles; which is just below 2^21(=2,097,152) Tiles total X/Y length... sub-tile precision can be handled using the remaining 11 Bits. Experimental teleporting to the map edge confirms that Chunk Generation stops at 31,250 (*32 tiles per chunk = 1,000,000), so this is definitely a Defined Limit; not a technical one. Because 2^15 * 2^15 = 2^30, you can comfortably fit a Chunk ID into a single 32-bit number using whatever bit-packing scheme you like.

You can decompile the Binary if you want more detail on the internal Data Structures; the Windows builds include a handy PDB Symbols file so it isn't complete nonsense. Most values are not actually Floats (due to potential rounding errors), but Integers-multiplied-by-1000-for-display. These implementation details are subject to change between Versions, so depending upon such behavior is not a great idea.

Good Luck!
Post Reply

Return to “Mod Packs / Libs / Special Interest”