Abyssalite to Abyssalite thermal conductivity weirdness

Recommended Posts

Someone told me that abyssalite tiles don't thermal transfer between each other.  But that didn't sit right with me.

From what I know of ONI physics, thermal transfer doesn't happen if the amount transferred is too small (0.1 DTU in 0.2 seconds).  So, I crunched the numbers and found that, using this assumption, if you put a 0.1 Kelvin block of abyssalite next to a 3600.1 Kelvin, I should get a DTU transfer of 7.2 per 0.2 seconds between the two blocks of abyssalite (according to the Thermal Conductivity Wiki), meaning that there should be thermal transfer occurring.

This thermal transfer happens unless one of the blocks is above 15 kg (probably somewhere between 14 and 15 kg).  If the cold block is 10 g at 0.1 K and the hot block is 14 kg, there is thermal transfer.  But if the cold block is 10 g at 0.1 K and the hot block is 15 kg, there is no thermal transfer.  It is like there is a minimum temperature difference allowed for thermal conductivity to occur, but I don't know of any such limitation.

EDIT:  More weirdness, this is not symmetrical.  When the hot block is 10 g and the cold block is 15 kg, thermal transfer still happens.  There is a cap on the cold block somewhere between 100,000 kg and 500,000 kg.

Share on other sites

11 hours ago, Zarquan said:

It is like there is a minimum temperature difference allowed for thermal conductivity to occur, but I don't know of any such limitation.

I believe it is because of the game using 32 bit floating point numbers to represent temperatures.

For example starting at a temperature of 30 C, the temperature has to jump to the next representable 32 floating point number, like this:

303.149993896484375 K
303.1500244140625 K
303.150054931640625 K

To jump from 30 C to the next representable floating point number, requires enough DTUs to make a temperature change of 0.000030518, I don't know exactly how the rounding works but this is the gist of things. In any case, if either tile is not able to jump to the next temperature state, neither tile changes temperature, this is to prevent an exploit where a large tile heats or cools a small tile without itself changing temperature.

Why tile mass matters, is that the larger the tile, the smaller the temperature change is calculated and the more likely it is to fall below the threshold.

Why it's not symmetrical is the nature of floating point numbers, when the temperature is close to 0 K there is a lot of precision to work with. Like from 1.0 K the next possible value is 1.000000119, while at 303 K the jump was 0.000305, at 1 K the jump is only 0.000000119, so at 30 C, 256x as much DTU is needed to make the jump.

It is certainly strange that Abyssalite being a perfect insulator in practice is due to floating point math quirks rather than an explicitly implemented game mechanic!

Other places where this weirdness pops up includes insulating Magma cisterns. Magma tiles are big and have quite a lot of heat capacity, unless of course the magma tile is only partial, a smaller magma tile requires less DTU to change temperature. For instance with a standard "magma blade" for magma at default sandbox temperature, heat transfer with Obsidian Rock Insulated Tiles at 20 C, only starts happening when the magma tile is smaller than about 750 kg, the large magma tiles simply do not transfer heat, and the small ones do, this flies in the face of reason.

This is also observed in magma biomes, Obsidian Tiles are usually around 1000 kg, and they have 1/5th the specific heat capacity as Magma tiles, so obsidian tiles will transfer heat much more readily than the magma tiles, unless of course the magma tiles are partial.

I also did some analysis for this for Insulated Tiles in this post:

Share on other sites

They must have taken the floating point math in to account then.  Because if you take a floating point number and add or subtract a number smaller than the smallest step, you would get the same number.  The operation would have been done on both sides, so the colder one would continue to heat but the hotter one wouldn't get colder because the regular subtraction would be rounded away.  The fact that the heat transfer stops implies there is another check they would have had to manually add to prevent weird heat transfer.

I wonder if it would slow the game down a lot if they used double floats instead of floats.  That is a lot more precision.

Share on other sites

12 hours ago, Zarquan said:

This thermal transfer happens unless one of the blocks is above 15 kg (probably somewhere between 14 and 15 kg).  If the cold block is 10 g at 0.1 K and the hot block is 14 kg, there is thermal transfer.  But if the cold block is 10 g at 0.1 K and the hot block is 15 kg, there is no thermal transfer.  It is like there is a minimum temperature difference allowed for thermal conductivity to occur, but I don't know of any such limitation.

Have you checked this in the testing branch? I think I saw a bug report mentioning of lifting the minimum limit for heat transfer (I think? This is what the update mentions "Sim: Removed energy damping to allow adjacent cells in a vacuum to better balance temperature. " not sure if it's the same case) but I didn't know of a case of how it worked before.

Share on other sites

39 minutes ago, Zarquan said:

They must have taken the floating point math in to account then.  Because if you take a floating point number and add or subtract a number smaller than the smallest step, you would get the same number.  The operation would have been done on both sides, so the colder one would continue to heat but the hotter one wouldn't get colder because the regular subtraction would be rounded away.  The fact that the heat transfer stops implies there is another check they would have had to manually add to prevent weird heat transfer.

Yeah, that's what I said:

"In any case, if either tile is not able to jump to the next temperature state, neither tile changes temperature, this is to prevent an exploit where a large tile heats or cools a small tile without itself changing temperature."

It is straightforward to implement, just by checking if the result of the calculation is the original value, for both tiles, and only committing the temperature change if both have changed temperature, this check would be virtually free in terms of performance (actually doing the calculations would take a lot longer).

39 minutes ago, Zarquan said:

I wonder if it would slow the game down a lot if they used double floats instead of floats.  That is a lot more precision.

Probably not. Intrinsically 32 and 64 bit floatnig point math runs at about the same speed (internally in the FPU it's all 80 bit precision), but 32 bit floats make better use of memory bandwidth so would tend to be a little faster due to better cache utilization. But I think heat transfer is a small enough part of the simulation (with the big part being pathfinding, always pathfinding) it probably wouldn't really be noticeable either way.

It's quite possible that Klei didn't make a deliberate decision to use 32 bit floats: it's the default for Unity because 32 bit floats are ubiquitous in game engines.

Share on other sites

13 hours ago, blakemw said:

Other places where this weirdness pops up includes insulating Magma cisterns. Magma tiles are big and have quite a lot of heat capacity, unless of course the magma tile is only partial, a smaller magma tile requires less DTU to change temperature. For instance with a standard "magma blade" for magma at default sandbox temperature, heat transfer with Obsidian Rock Insulated Tiles at 20 C, only starts happening when the magma tile is smaller than about 750 kg, the large magma tiles simply do not transfer heat, and the small ones do, this flies in the face of reason.

The fact that it happens with insulated obsidian and magma implies that this could happen in other cases in real games that haven't been considered.  Part of me wonders if 999 kg steam interacts with insulated igneous rock tiles.  It should probably be fixed.

My fix would be that if the thermal transfer doesn't happen due to no change in temperature, then a count of energy change should be calculated and this energy change is applied to the temperature when it is large enough.

Alternatively, it could add up the time when this happens and essentially have the temperature change add up until there is a noticeable temperature change.  For example, if one tick doesn't create a large enough temperature change, then maybe 2 ticks will and they substitute the delta-t with 0.4.  If it takes more ticks, they just increase delta-t.

10 hours ago, blakemw said:

"In any case, if either tile is not able to jump to the next temperature state, neither tile changes temperature, this is to prevent an exploit where a large tile heats or cools a small tile without itself changing temperature."

I agree, they definitely can't get rid of the check, as you could infinitely compress several thousand tons of magma or steam in one tile and generate free power.