"How does the room temperature equalization system work internally?"
District = connected regions of the same type (Normal/Fence/ImpassableFreeAir).
Room = districts connected via portal regions (doors).
A room can contain multiple districts.
Verse/Room.cs:1-937 Verse/RegionAndRoomUpdater.cs:1-409
Every 120 ticks (~2 seconds game time, offset 7), Verse/MapTemperature.cs:1-254 calculates the temperature for each room on the map. The actual calculation is delegated to Verse/RoomTempTracker.cs:1-325, which adds up 4 equalization sources per room.
TempDiffFromOutdoorsAdjusted at extreme differentials
(>100°C difference: factor ×5 → ×1). Prevents extreme oscillation.
On room rebuild, equalizeCells are re-collected and Shuffle() is called:
equalizeCells.Shuffle() consumes Rand calls.
If rooms are rebuilt at different times on different clients
→ different Rand sequence → Desync.
Heat flows through walls to neighboring rooms. equalizeCells = cells that are 2 walls away in adjacent rooms. 20% of cells are processed per tick interval (cycleIndex rotates).
Note: Identical for ALL wall materials — wood insulates the same as granite!
Verse/RoomTempTracker.cs:WallEqualizationSlow equalization with outdoor temperature through thin roof.
At 100% ThinRoof and 20°C difference: ~0.12°C per interval. Very slow.
Verse/RoomTempTracker.cs:EqualizeTemperatureOpen cells without roof. 14× faster than ThinRoof!
0.0007 / 0.00005 = 14× faster than ThinRoof. At 50% open and 20°C diff: ~1.68°C per interval.
Verse/RoomTempTracker.cs:EqualizeTemperatureThickRoof cells pull temperature towards 15°C. Only acts as cooling — if room >15°C no effect. On underground maps: 40× faster equalization.
Target temperature: 15°C (TemperatureTuning.DeepUndergroundTemperature)
Verse/RoomTempTracker.cs:EqualizeTemperatureDoors have their own equalization rules:
| Door Type | Behavior | Interval |
|---|---|---|
| Open Door | EqualizeTemperaturesThroughBuilding — average of both sides | 34 Ticks |
| Closed Door | EqualizeTemperaturesThroughBuilding — slower | 375 Ticks |
| Isolated Door (surrounded only by doors) | Normal WallEqualization instead | 120 Ticks |
| Vent Building | EqualizeTemperaturesThroughBuilding × 14 rate | Same as door |
Verse/GenTemperature.cs:EqualizeTemperaturesThroughBuilding
| Property | Condition | Meaning |
|---|---|---|
UsesOutdoorTemperature | ≥25% no roof OR TouchesMapEdge | Temperature = Outdoor (no equalization) |
PsychologicallyOutdoors | ≥300 open roof cells OR (MapEdge + ≥50% open) | Pawns feel "outdoors" |
OutdoorsForWork | >100 open cells OR >25% open | Workplace evaluation |
IsHuge | >60 Regions | Stats are NOT calculated |
ProperRoom | !TouchesMapEdge + min. 1 Normal region | Actual indoor room |
| Method | Formula | Purpose |
|---|---|---|
PushHeat(cell, energy) |
Room.Temperature += energy / CellCount |
Fire, explosions, campfire |
ControlTemperatureTempChange |
delta = min(targetDiff, energy/CellCount), clamped to sign |
Heater/Cooler target temperature control |
EqualizeTemperaturesThroughBuilding |
Average temperature of adjacent rooms × rate × vacuum factor | Doors, vents (rate: door=1.0, vent=14.0) |
Verse/GenTemperature.cs:1-533
ComfortableTemperatureRange = pawn stat ± 10°C buffer (SafeTemperatureRange).
Outside of that → Hypothermia/Heatstroke hediffs.When a wall/door is built or removed:
Verse/RegionAndRoomUpdater.cs:1-409
| Constant | Value | Meaning |
|---|---|---|
MinTemperature | -273.15°C | Absolute zero |
MaxTemperature | 1000°C | Temperature cap |
DefaultTemperature | 21°C | Starting temperature |
DeepUndergroundTemperature | 15°C | Mountain target temperature |
RoomEqualizeInterval | 120 Ticks | ~2 seconds (offset 7) |
WallEqualizeFactor | 0.00017f | Per wall cell, all materials equal |
ThinRoofFactor | 5E-05f | Thin roof equalization |
NoRoofFactor | 0.0007f | Open roof (14× ThinRoof) |
UndergroundFactor | 0.002f | Underground map (40× normal) |
Vent_TempEqualizeRate | 14.0 | Vent = 14× door |
Door Open Interval | 34 Ticks | Door open equalize interval |
Door Closed Interval | 375 Ticks | Door closed equalize interval |
Refrigeration | <10°C | Food preserved |
Freezing | <0°C | Food frozen |
Seasonal Amplitude | 3-28°C | Depending on latitude (curve) |
Verse/TemperatureTuning.cs:1-45
3 sources, in priority order:
| Priority | Source | When |
|---|---|---|
| 1 | Biome.constantOutdoorTemperature | Biomes with fixed temp (e.g. Underground) |
| 2 | PocketMap.temperature | Pocket maps (Anomaly DLC) |
| 3 | World.tileTemperatures | Normal: latitude + season + sun cycle |
Sun cycle: Cosine, 7°C amplitude, peak at 0.32 daytime (approx. 19:40).
Season: Cosine, 3-28°C amplitude depending on latitude.
Verse/GenTemperature.cs:OffsetFromSunCycle, OffsetFromSeasonCycle
If you modify the temperature system, these systems are directly impacted:
The temperature system is fully captured. All relevant files (Room.cs, RoomTempTracker.cs, GenTemperature.cs, MapTemperature.cs, TemperatureTuning.cs, RegionAndRoomUpdater.cs) have been analyzed.
Building_Vent.cs — Vent building internals (how TickRare → EqualizeTemperatures is called)Building_Cooler.cs — Cooler logic (intake/output side, EnergyPerTick)CompTempControl.cs — Shared comp for Heater/Cooler UI and TargetTemp