Skip to content

Temperature Computation

Real Ant Engineer edited this page Nov 2, 2025 · 10 revisions

🌡️ Temperature Computation System

This page explains how temperature computation is handled in the mod. The simulation is based on a finite-difference heat diffusion model.


📦 Section-Level Simulation

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.


🧮 Finite Difference Scheme

The simulation uses a finite-difference method to approximate heat diffusion between neighboring blocks. For each block in the section:

  1. Compute self temperature Tself and conduction Cself.
  2. 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)
  3. If a neighbor is outside the section, cross-section access is used to get the flux

🔥 Temperature Update Formula

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)

♻️ Section Dirty Tracking

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.


🌍 Dynamic Temperature Sources

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);
}

Clone this wiki locally