-
Notifications
You must be signed in to change notification settings - Fork 15
Temperature Computation
This page explains how temperature computation is handled in the mod. The simulation is based on a finite-difference heat diffusion model.
Temperature is only computed for sections (16×16×16 blocks) within a
16-block radius around BlockEntity instances implementing
IHaveTemperature.
Each active section contains three data layers (more detail here):
-
TemperatureDataLayer— stores local and default temperatures. -
ConductionDataLayer— stores thermal conductivity (how fast heat diffuses). -
ResilienceDataLayer— stores the “return-to-default” rate (how fast it stabilizes to equilibrium).
These layers are retrieved using:
TemperatureDataLayer temperatureData = data.getTemperature(packedSection);
ConductionDataLayer conductionData = data.getConduction(packedSection);
ResilienceDataLayer resilienceData = data.getResilience(packedSection);
If any of the three are missing, the section is skipped for that tick.
The simulation uses a finite-difference method to approximate heat diffusion between neighboring blocks. For each block in the section:
- Compute self temperature
Tselfand conductionCself. - For each of the six directions (
+X, -X, +Y, -Y, +Z, -Z), compute:- Neighbor temperature
Tn. - Neighbor conduction
Cn. - Thermal flux contribution:
flux += (Tn - Tself) * (Cn * Cself) / (Cn + Cself); - Neighbor temperature
- If a neighbor is outside the section, cross-section access is used to get the flux.
After computing the total flux and resilience, the new temperature is calculated as:
newTemp = selfTemp + (
((defaultTemp - selfTemp) * resilience * 100) // Relaxation toward default
+ totalFlux * (1 - resilience) // Net conduction
) * DT / CAPACITY;
Where:
- resilience → Pulls the block temperature back toward its equilibrium/default temperature.
- conduction → Controls how fast temperature equalizes between neighbors.
- DT → Time step (1/20 of a second).
-
CAPACITY → Thermal capacity (very important for numerical stability, default
3e4f).
The resulting temperature is then clamped to the valid range:
Mth.clamp(newTemp, TemperatureDataLayer.MIN_TEMPERATURE, TemperatureDataLayer.MAX_TEMPERATURE);
If a block’s temperature changes significantly (ΔT > 1e−3), the section is marked as
dirty and all its boundary neighbors are also flagged for updates otherwise, the section is marked as clean (no change this tick) and will not be ticked next time.
Blocks implementing IHaveTemperature (e.g. FuelAssembly, HeatExchanger)
have an internal heat production or removal mechanism. They are exceptions to the dirty system and cause
their section to always remain dirty (ticked every update).
if (data.dynamicContains(pos)) {
IHaveTemperature be = data.getDynamic(pos);
be.addTemperature(newTemp - selfTemp);
}
-
The numerical scheme stability depends heavily on the choice of
DT and CAPACITY — lowering capacity can cause oscillations.