Before I get to parts of discussion, let me explain that I was chemical related university dropout(who did study at least basic chemistry as well as heat transfer) as well as a programmer who did glance over how comestibles are working and freezing right now. So let me try to convert this into more manageable, programmable form of realistic freezing system quick and dirty.
But first, what is freezing of an item? I am going to say it is liquid in whatever we are talking froze.
So if we are ever going to make multiple types of liquid freeze, liquid type must be defined first.
Assuming 1 ATM environment,
Property of liquid(it can be liquid or solid):
Name (we will use “Water”)
Liquid ID (l_water)
Freezing/melting Temperature (0 degrees celcius)
Heat capacity (energy it takes to change a degree celcius/kelvin per kilogram, and for liquid water it is 4.187 kJ/kgK )
Latent heat for freezing/thawing the liquid (AKA Enthalpy of fusion. this is amount of energy change for freezing or thawing, for water it is 334KJ/kg)
Name (we will use “Frozen water”)
Liquid ID (s_water)
Freezing/melting Temperature (0 degrees celcius)
Heat capacity (energy it takes to change a degree celcius/kelvin per kilogram, and for solid water it is 2.108 kJ/kg K )
Latent heat for freezing/thawing the liquid (AKA Enthalpy of fusion. this is amount of energy change for freezing or thawing, for water it is 334KJ/kg)
Above can all be hard coded if we are never going to deal with other liquids freezing.
identification if something is liquid or solid can also be hard coded.
weight of water or other properties should not matter as long as every value in every entries are realistic.
New property of comestibles:
Liquid ID (primary liquid of comestible - say, a bread. And for bread majority of liquid is liquid water, so this will be l_water)
Percentage value of liquid in comestible (Wikipedia says about 40%, so 0.4 it is)
We are going to ignore every other property of this bread to make calculations quick and faster.
We are also assuming that there is no such thing as “Half frozen” item, since such things do not exist in the game yet.
I have seen frozen item acting differently from liquid items, so I am also going to assume that frozen items are completely different item that are just switched out into solid ones with expiration date.
To sum up every value so far, we only need track Temperature of the item. Temperature of the item can be calculated from how much energy it currently has, Every other values can be calculated from it. We already have tickers that tracks how thawed items are(I think it was experimented with shelf thawing experiment) we do not need additional value. Now let’s see how much simplification we can get out of OP’s equations.
Incredibly quick, dirty and unrealistic way:
We ignore everything unless temperature is below freezing point for liquid, and above freezing point for solid.
OP’s equation from above.
Q = -ΔT × I × A × Δt
Let me simplify this because that is easier thing to do. Using a bread which has value of
Weight of bread = 0.06 kg
Percentage value of liquid in comestible = 0.4
Bread area = A = V^2/3 = 0.094L^2/3 = 0.0096 m^2
Q = -ΔT × I(some constant, fixed value) × 0.0096 m^2 × (Δt is 6 seconds, assuming single tick)
-ΔT is temperature difference, so how can this be calculated? Simple.
In current “Quick and dirty calculation” method we will just always assume bread is at 0 degrees Celsius.
We don’t even need to convert to kelvin because they cancel out. Yay.
ΔT = (0 for water’s current temperature - environment temperature in celcius) + (kelvin conversion - kelvin conversion)
Therefore ΔT = environment temperature in celcius
So currently,
Q = environment temperature in celcius x I(some constant, fixed value) × Bread area x 6 seconds
Now let’s tweak the equation so it calculate the temperature change.
Since we only need to calculate how much energy is needed to Freeze this bread, we just need to freeze all water inside the bread.
So Q = energy needed to freeze bread, so:
Q = Latent heat for l_water x Bread weight x liquid percentage =
Now I am going to cheat here. Since I want to keep only single value for calculation we will just track energy of water in temperature, so we will just assume at certain temperature of water, it is suddenly all freeze to ice. This temperature can easily be calculated by Latent heat/Heat capacity, and for l_water it is (334KJ/kg) / (4.187 kJ/kgK) = approximately 80 degrees. This means -80 degree liquid water have same energy as 0 degrees ice, and we will assume at -80 degrees liquid water will suddenly turn to ice(item temperature is always assumed to be 0 so calculation should not matter much for this equation).
Temperature change for bread assuming state does not change = Q/(Heat capacity x Bread weight x liquid percentage)
Temperature change for bread assuming state does not change = Q/(Heat capacity x Bread weight x liquid percentage) = -(environment temperature in celcius) x I(some constant, fixed value) × (Bread area x 6 seconds, also fixed) / (Heat capacity for liquid water x Bread weight x liquid percentage)
Well that was easy.
Unit calculation = K = K * (W/(m^2 K)) * s * m^2 / (J/kgK * kg) = K
In programming terms, C++(rusty and therefore could be wrong):
double tempdiff = comestibles.getliquid().getfreemeltpoint() - environment temperature in celcius;
// if liquid
if (comestibles.getliquid().substr(0,1) = 'l')
{
//calculation for liquid -> solid
if (tempdiff > 0)
{
comestibles.addtemp(-tempdiff * I(some constant, fixed value) * pow (comestibles.getarea(), 0.666) * 6 / (comestibles.getliquid().getheatcap()) / comestibles.getweight() / comestibles.getliquidpercent());
// change state if calculation says sufficient energy/temperature point is reached.
if (comestibles.gettemp() < -(comestibles.getliquid().getlatantheat()/comestibles.getliquid().getheatcap()))
{
item_tags.insert( "FROZEN" );
}
}
else
{
comestibles.settemp(comestibles.getliquid().getfreemeltpoint());
}
}
else
{
//calculation for solid -> liquid
if (tempdiff < 0)
{
comestibles.addtemp(-tempdiff * I(some constant, fixed value) * pow (comestibles.getarea(), 0.666) * 6 / (comestibles.getliquid().getheatcap()) / comestibles.getweight() / comestibles.getliquidpercent());
// change state if calculation says sufficient energy/temperature point is reached.
if (comestibles.gettemp() > comestibles.getliquid().getlatantheat()/comestibles.getliquid().getheatcap())
{
item_tags.delete( "FROZEN" );
}
}
else
{
comestibles.settemp(comestibles.getliquid().getfreemeltpoint());
}
}
So by few multiplication and division and few if statements, status change proposed by OP can be easily implemented with lots of cut corners, although this code will make 200L melt a lot less quick than 1L, make freezing temperature dependent as well as more realistic.
I was going to write longer ones but I got too tired at this point. We will see how this one goes