-
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 += (Tₙ -)Tself) * (Cₙ *Cself) / (Cₙ + self
- 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 the numerical stability) 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:
if (Mth.abs(selfTemp - newTemp) > 1e-3f) {
data.setDirty(packedSection);
// also mark adjacent sections dirty if boundary cells changed
}
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/removal, they are an exeption to the dirty system and make the section chunk there in always dirty.
if (data.dynamicContains(pos)) {
IHaveTemperature be = data.getDynamic(pos);
be.addTemperature(newTemp - selfTemp);
}