New: Simple Temperature

Simple Temperature 🔗

This mod aims to provide a survival temperature mechanic for Luanti in a somewhat intuitive way. It doesn't provide a scientifically accurate temperature behavior, but instead tries to implement it the way that "makes sense".

Work-In-Progress 🔗

This mod is a Work-In-Progress. It may contain bugs and any part of the mod can be suddenly changed. Don't use it on live servers.

How to use 🔗

The temperature isn't represented by any real life units, but simply as an arbitrary scale from 0 to 100. Upon reaching either end of the scale, player begins to take damage at a rate of 1 HP per 3 seconds.

With hudbars installed, temperature is displayed on player's HUD as a bar. Unlike other bars, this one shouldn't be fully filled as it represents temperature from very cold to very hot, with midpoint being in the middle.

This bar represents player's internal temperature and this temperature will change towards current environment temperature. The speed at which it changes is determined by many factors like humidity, player being submerged, armor, etc.

There is also another hidden characteristic called "heat modifier". It is primarily based on biome-sourced humidity but also influenced by other factors. This modifier influences how fast player's temperature changes towards target temperature.

The main influencing factors are:

Biome-based temperature 🔗

Biomes are the most obvious source of different temperatures. On elevations from -256 to 256 environmental temperature is weighted primarily by biome temperature, tapering off in favor of height-based temperature further from midpoint between those two elevations. Temperature and humidity are sourced directly from mapgen data.

Height-based temperature 🔗

Second source of temperature is height. Based on settings, when moving further away from biome height limits, temperature starts to get influences primarily by height. With default settings, it reaches coldest point at elevation 1024 and contributes -30 points towards target heat. On the other side, hottest point is at -16384 nodes where target temperature has +60 points added to it. Note that biome temperature still takes precedence and despite height temperature overlaps with biome limits, it only starts to take effect when moving further from them.

Time of the day 🔗

Surface (biome-based) temperature is also affected by the time of the day. With default settings, it gets colder during the night, with minimum temperature reaching -20 points (with default settings) contributed towards target heat at midnight and slowly tapers off towards the midday, where it reaches 0.

Liquid nodes 🔗

This mod registers some common node groups as "liquid" nodes. Such nodes will change your target temperature very quickly as their heat multiplier is always 1. Target temperature of such nodes can be either positive or negative. Examples of such liquids are water, which will cool you down by -20 points or lava, which will heat you up by 100 points.

Radiant nodes 🔗

Similarly to liquid nodes, there's also "radiant" nodes, or nodes that emit heat. They influence target temperature by simply standing near them, with target heat being influenced by distance towards each node and their amount. Note that amount of nodes have diminishing returns, so placing 8 torches to warm up will not fry the player. Target heat of each node or group can also be negative. Examples of such nodes are "torch" group with a target heat of 15, so a single torch can warm you up by 15 points if standing very close to it. Other groups like "fire" or "lava" are also registered.

Shelter 🔗

If not disabled in settings, standing 8 blocks or below any ceiling will provide a "shelter". In such a shelter biome and height temperature aren't taken in account.

Override zones 🔗

This mod also provides so-called "override zones". This is intended for mods that create their own custom map layers, like nether or df_caverns. Override zones span vertically and take precedence over any other factors, except liquid and radiant nodes. Temperature and heat multiplier in such zones are constant and defined by zones themselves. Examples of such zones are nether, which is a constant high temperature in nether layer or df_caverns, which also has a constant high temperature in magma ocean layer.

Armor integration 🔗

If 3d_armor is installed, by default this mod will also use player's protection values to reduce influence of all other heat modifiers. Armor values are used directly and multiplied by 1.25 (by default). Armor modifier takes prededence over any other modifiers and influences how fast player changes body temperature towards environment temperature. Armor protection is capped at 95, so even with armor value over 100, players will still get 5% of their actual heat multiplier. For example, default protection value of nether armor from 3d_armor is 75 for a full set. Multiplied, by 1.25 we get 93.75 which corresponds to a 93.75% reduction of heat transfer speed. Other mods may add armor with higher protection values and this value will be capped at 95%.

Settingtypes 🔗

Mod provides configuration options, accessible either in Luanti client settings or by putting configuration options and their values directly into your minetest.conf.

Full list of options, along with their documentation and possible values is available in settingtypes.txt in this repository.

Integration with other mods (API) 🔗

Mod provides these public functions:

--------------------------------------------------------------------------------

simple_temperature.register_liquid_node(name, add_temp):

- name, string, itemstring of an item, or, preferably, group;
- add_temp, float, can be negative, amount of heat this node or group
adds or subtracts.

Function registers a new liquid node or group.

--------------------------------------------------------------------------------

simple_temperature.register_temperature_node(name, add_temp)

- name, string, itemstring of an item, or, preferably, group;
- add_temp, float, can be negative, amount of heat this node or group
adds or subtracts.

Function registers a new radiant node or group.

--------------------------------------------------------------------------------

simple_temperature.register_override_zone = function(target_temp,
heat_multiplier, y_min, y_max)

- target_temp, float, target temperature for override zone;
- heat_multiplier, float, target heat multiplier for override zone;
- y_min, int, minimum Y for override zone;
- y_max, int, maximum Y for override zone.

Note that zones can't intersect and the function will not register
such a zone.

--------------------------------------------------------------------------------

simple_temperature.get_stats_at = function(pos)

- pos, table with x, y, z fields, position at which get the stats at.

Function fully recalculates target heat and multiplier parameters for pos
and returns them in the following table:

{ heat = ..., heat_multiplier = ... }

Note: avoid calling this function often as it can be constly. Consider using
the function described below as it also stores cached version of stats for the
player since the last update interval.

--------------------------------------------------------------------------------

simple_temperature.get_player_stats(name):

- name, string, name of the player.

Function returns full player context for given player in the following table:

{
ref = ..., - player ObjectRef;
temperature = ..., - player's own body temperature;
ext_stats = ..., - cached version of table from get_stats_at(pos)
worn_armor_mult = ..., - multiplier based on worn armor.
}

--------------------------------------------------------------------------------

License And Credits 🔗

All code and assets in this repository are made by Fruitsnack, unless stated or implied otherwise in:

"License And Credits" section in README (this section);

Individual file headers;

Git commit history;

Merge requests and other means of contribution (i.e. by mailing patches).

Code and text files that are made by Fruitsnack are licensed under AGPL-3.0-only.
Full text of the license is available in LICENSE-AGPL-3.0-ONLY in this repository, or, alternatively, here.

Assets and media files that are made by Fruitsnack are licensed under CC-BY-SA-4.0.
Full text of the license is available in LICENSE-CC-BY-SA-4.0 in this repository, or, alternatively, here.

screenshot.png was made by Fruitsnack using Pixelify-Sans font by Stefie Justprince, licensed under OFL-1.1.
Full text of the license is available in LICENSE-OFL-1.1 in this repository, or, alternatively, here.

Simple Temperature - Temperature as a survival mechanic for Luanti
Copyright (C) 2025 Fruitsnack

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License version 3 as
published by the Free Software Foundation.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.

You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.