Update to Factorio 2.0.60

Wed, 23 Jul 2025 14:46:54 +0300

author
Teemu Piippo <teemu.s.piippo@gmail.com>
date
Wed, 23 Jul 2025 14:46:54 +0300
changeset 16
2cdb59ae5fcf
parent 15
9dba62aa8083
child 17
df60e9144d82

Update to Factorio 2.0.60

more-descriptions/changelog.txt file | annotate | diff | comparison | revisions
more-descriptions/data-final-fixes.lua file | annotate | diff | comparison | revisions
more-descriptions/info.json file | annotate | diff | comparison | revisions
more-descriptions/locale/en/more-descriptions.cfg file | annotate | diff | comparison | revisions
--- a/more-descriptions/changelog.txt	Sat Jul 05 00:35:55 2025 +0300
+++ b/more-descriptions/changelog.txt	Wed Jul 23 14:46:54 2025 +0300
@@ -1,3 +1,15 @@
+---------------------------------------------------------------------------------------------------
+Version: 1.1.2
+Date: 2025-07-03
+  Bugfixes:
+    - Fixed mod not loading in some cases where some parts of descriptions get very long like Secretas&Frozeta.
+
+---------------------------------------------------------------------------------------------------
+Version: 1.1.1
+Date: 2025-07-03
+  Features:
+    - Added heating energy information
+
 ---------------------------------------------------------------------------------------------------
 Version: 1.1.0
 Date: 2025-06-30
--- a/more-descriptions/data-final-fixes.lua	Sat Jul 05 00:35:55 2025 +0300
+++ b/more-descriptions/data-final-fixes.lua	Wed Jul 23 14:46:54 2025 +0300
@@ -1,21 +1,65 @@
+---@type data.FeatureFlags
+feature_flags = feature_flags
+
 local function seconds(x)
 	return {"time-symbol-seconds", tostring(x)}
 end
 
-local function build_new_description(main_description, new_descriptions)
-	local new_localised_description = {
-		"",
-		main_description,
-	}
-	for i, k in pairs(new_descriptions)
+local energy_zero_table = {
+	["0W"] = 1,
+	["0kW"] = 1,
+	["0MW"] = 1,
+	["0GW"] = 1,
+	["0TW"] = 1,
+}
+
+---@type table<string, 1>
+local recipes_that_have_productivity_research = {}
+
+for _, technology in pairs(data.raw["technology"] or {})
+do
+	for _, effect in pairs(technology.effects or {})
 	do
-		if i ~= 1
+		if effect.type == "change-recipe-productivity"
 		then
-			table.insert(new_localised_description, "\n")
+			recipes_that_have_productivity_research[effect.recipe] = 1
 		end
-		table.insert(new_localised_description, k)
 	end
-	return new_localised_description
+end
+
+---@param x string
+local function energy_zero(x)
+	return x == nil or energy_zero_table[x]
+end
+
+---@param x LocalisedString
+-- localised string containing too many entries? snap it into many pieces and catenate them
+local function snap(x)
+	if type(x) == "table" and #x > 20 and x[1] == ""
+	then
+		local max_per_part = math.ceil((#x - 1) / 18)
+		local result = {""}
+		local segment = {""}
+		for k, v in pairs(x)
+		do
+			if k > 1
+			then
+				if #segment >= max_per_part + 1
+				then
+					table.insert(result, snap(segment))
+					segment = {""}
+				end
+				table.insert(segment, v)
+			end
+		end
+		if #segment > 1
+		then
+			table.insert(result, snap(segment))
+		end
+		return result
+	else
+		return x
+	end
 end
 
 local item_categories =
@@ -173,6 +217,26 @@
 	"solar-panel",
 }
 
+-- Find all entity categories that contain prototypes that can freeze.
+-- If a prototype in such a category cannot freeze, that's worth pointing out.
+-- However, it's not worth pointing out that the steel chest cannot freeze,
+-- since no container freezes (in vanilla anyway).
+local freezable_entity_categories = {}
+if feature_flags.freezing
+then
+	for _, category in pairs(entity_categories)
+	do
+		for _, entity in pairs(data.raw[category] or {})
+		do
+			if not energy_zero(entity.heating_energy)
+			then
+				freezable_entity_categories[entity.type] = 1
+				break
+			end
+		end
+	end
+end
+
 local function find_entity(name)
 	for _, entity_category in pairs(entity_categories)
 	do
@@ -184,6 +248,7 @@
 	return nil
 end
 
+-- @type table<string, string>
 local ammo_categories = {}
 
 for _, ammo in pairs(data.raw.ammo)
@@ -199,29 +264,43 @@
 	then
 		ammo_categories[ammo.ammo_category] = ammo_categories[ammo.ammo_category] .. "..."
 	end
+end	
+
+---@param proto data.Prototype
+---@param tooltip_field LocalisedString
+local function generic_add_description(proto, tooltip_field)
+	if not proto.custom_tooltip_fields
+	then
+		proto.custom_tooltip_fields = {}
+	end
+	table.insert(proto.custom_tooltip_fields, tooltip_field)
 end
 
 for _, item_type in pairs(item_categories)
 do
 	for _, item in pairs(data.raw[item_type] or {})
 	do
-        local new_descriptions = {}
 		local recycling_recipe = data.raw.recipe[item.name.."-recycling"]
 
-		local add_description = function(x)
-			table.insert(new_descriptions, x)
+		---@param tooltip_field data.CustomTooltipField
+		local function add_description(tooltip_field)
+			generic_add_description(item, tooltip_field)
 		end
 
 		local add_ammo_from_attack_parameters = function(attack_parameters)
 			if attack_parameters.ammo_category and ammo_categories[attack_parameters.ammo_category]
 			then
-				add_description{"more-descriptions-mod.gun-accepts-ammo", ammo_categories[attack_parameters.ammo_category]}
+				add_description{
+					name = {"more-descriptions-mod.gun-accepts-ammo"},
+					value = ammo_categories[attack_parameters.ammo_category]}
 			end
 			for _, category in pairs(attack_parameters.ammo_categories or {})
 			do
 				if ammo_categories[category]
 				then
-					add_description{"more-descriptions-mod.gun-accepts-ammo", ammo_categories[category]}
+					add_description{
+						name = {"more-descriptions-mod.gun-accepts-ammo"},
+						value = ammo_categories[category]}
 				end
 			end
 		end
@@ -234,9 +313,12 @@
 				table.insert(recycling_results, "[img="..result.type.."."..result.name.."]")
 			end
             add_description{
-                "more-descriptions-mod.recycling",
-                seconds(recycling_recipe.energy_required),
-				recycling_results
+                name = {"more-descriptions-mod.recycling"},
+                value = {
+					"more-descriptions-mod.recycling-results",
+					seconds(recycling_recipe.energy_required),
+					snap(recycling_results),
+				},
             }
 		end
 
@@ -246,31 +328,39 @@
 			if refining_recipe ~= nil
 			then
 				add_description{
-					"more-descriptions-mod.refining-cost",
-					tostring(refining_recipe.energy_required),
+					name = {"more-descriptions-mod.refining-cost"},
+					value = seconds(refining_recipe.energy_required),
 				}
 			elseif recycling_recipe ~= nil
 			then
-				add_description{"more-descriptions-mod.cannot-be-refined"}
+				add_description{
+					name = {"more-descriptions-mod.cannot-be-refined"},
+					value = ""}
 			end
 		end
 
 		if item.type == "ammo" and (item.reload_time or 0) > 0
 		then
 			add_description{
-				"more-descriptions-mod.reload-time",
-				seconds(tostring(item.reload_time / 60.0)),
+				name = {"more-descriptions-mod.reload-time"},
+				value = seconds(tostring(item.reload_time / 60.0)),
 			}
 		end
 
 		if item.type == "active-defense-equipment" and item.automatic
 		then
-			add_description{"more-descriptions-mod.fires-automatically"}
+			add_description{
+				name = {"more-descriptions-mod.fires-automatically"},
+				value = "",
+			}
 		end
 
 		if item.type == "armor" and item.provides_flight
 		then
-			add_description{"more-descriptions-mod.armor-provides-flight"}
+			add_description{
+				name = {"more-descriptions-mod.armor-provides-flight"},
+				value = "",
+			}
 		end
 
 		if item.type == "gun"
@@ -287,36 +377,66 @@
 				local width = math.ceil(cb[2][1] - cb[1][1])
 				local height = math.ceil(cb[2][2] - cb[1][2])
 				add_description{
-					"more-descriptions-mod.size",
-					tostring(width),
-					tostring(height),
+					name = {"more-descriptions-mod.entity-size"},
+					value = {
+						"more-descriptions-mod.size",
+						tostring(width),
+						tostring(height),
+					},
 				}
 			end
 
 			if entity.drops_full_belt_stacks
 			then
-				add_description{"more-descriptions-mod.drops-full-belt-stacks"}
+				add_description{
+					name = {"more-descriptions-mod.drops-full-belt-stacks"},
+					value = ""}
 			end
 
 			if entity.heat_buffer and entity.heat_buffer.specific_heat
 			then
 				add_description{
-					"more-descriptions-mod.specific-heat",
-					entity.heat_buffer.specific_heat,
+					name = {"more-descriptions-mod.specific-heat"},
+					value = {
+						"more-descriptions-mod.energy-per-degrees-celsius",
+						entity.heat_buffer.specific_heat,
+					},
 				}
 			elseif entity.energy_source
 				and entity.energy_source.type == "heat"
 				and entity.energy_source.specific_heat
 			then
 				add_description{
-					"more-descriptions-mod.specific-heat",
-					entity.energy_source.specific_heat,
+					name = {"more-descriptions-mod.specific-heat"},
+					value = entity.energy_source.specific_heat,
 				}
 			end
 
 			if entity.is_military_target
 			then
-				add_description{"more-descriptions-mod.is-military-target"}
+				add_description{
+					name = {"more-descriptions-mod.is-military-target"},
+					value = "",
+				}
+			end
+
+			if not energy_zero(entity.heating_energy or "0W")
+			then
+				local value = entity.heating_energy
+				if entity.type == "underground-belt" or entity.type == "pipe-to-ground"
+				then
+					value = {"more-descriptions-mod.value-per-end", value}
+				end
+				add_description{
+					name = {"more-descriptions-mod.heating-energy"},
+					value = value,
+				}
+			elseif freezable_entity_categories[entity.type]
+			then
+				add_description{
+					name = {"more-descriptions-mod.no-heating-energy"},
+					value = "",
+				}
 			end
 
 			if entity.type == "agricultural-tower"
@@ -328,30 +448,45 @@
 				local z = (2 * w * math.ceil((W - w) / 2 / w)) + w
 				-- num of growth cells extending from the edges of the tower
 				local r = math.floor(entity.radius) -- why is it double..?
-				add_description{"more-descriptions-mod.agricultural-tower-num-inputs",
-					tostring(entity.input_inventory_size)
+				add_description{
+					name = {"more-descriptions-mod.agricultural-tower-num-inputs"},
+					value = tostring(entity.input_inventory_size)
 				}
-				add_description{"more-descriptions-mod.agricultural-tower-growth-cell-size",
-					tostring(w)
+				add_description{
+					name = {"more-descriptions-mod.agricultural-tower-growth-cell-size"},
+					value = {
+						"more-descriptions-mod.size",
+						tostring(w),
+						tostring(w),
+					}
 				}
-				add_description{"more-descriptions-mod.agricultural-tower-growth-cell-count",
-					tostring(4 * r * (r + (z / w)))
+				add_description{
+					name = {"more-descriptions-mod.agricultural-tower-growth-cell-count"},
+					value = tostring(4 * r * (r + (z / w)))
 				}
-				add_description{"more-descriptions-mod.agricultural-tower-total-size",
-					tostring(z + 2 * r * w)
+				total_size = tostring(z + 2 * r * w)
+				add_description{
+					name = {"more-descriptions-mod.agricultural-tower-total-size"},
+					value = {
+						"more-descriptions-mod.size",
+						total_size,
+						total_size,
+					},
 				}
 			elseif entity.type == "ammo-turret"
 			then
 				if entity.energy_per_shot ~= nil
 				then
-					add_description{"more-descriptions-mod.energy-per-shot-fired",
-						entity.energy_per_shot}
+					add_description{
+						name = {"more-descriptions-mod.energy-per-shot-fired"},
+						value = entity.energy_per_shot}
 				end
 				add_ammo_from_attack_parameters(entity.attack_parameters)
 			elseif entity.type == "beacon"
 			then
-				add_description{"more-descriptions-mod.beacon-supply-area-distance",
-					tostring(entity.supply_area_distance)
+				add_description{
+					name = {"more-descriptions-mod.beacon-supply-area-distance"},
+					value = tostring(entity.supply_area_distance)
 				}
 			elseif entity.type == "car"
 			then
@@ -370,109 +505,159 @@
 				end
 				if immunities ~= ""
 				then
-					add_description{"more-descriptions-mod.car-immune-to-impacts", immunities}
+					add_description{
+						name = {"more-descriptions-mod.car-immune-to-impacts"},value = immunities}
 				end
 			elseif entity.type == "constant-combinator"
 			then
 				-- used by pushbutton mod
 				if (entity.pulse_duration or 0) > 60
 				then
-					add_description{"more-descriptions-mod.constant-combinator-pulse-duration",
-						seconds(entity.pulse_duration / 60.0)}
+					add_description{
+						name = {"more-descriptions-mod.constant-combinator-pulse-duration"},
+						value = seconds(entity.pulse_duration / 60.0),
+					}
 				elseif (entity.pulse_duration or 0) > 0
 				then
-					add_description{"more-descriptions-mod.constant-combinator-pulse-duration",
-						{"more-descriptions-mod.ticks", tostring(entity.pulse_duration)}}
+					add_description{
+						name = {"more-descriptions-mod.constant-combinator-pulse-duration"},
+						value = {
+							"more-descriptions-mod.ticks",
+							tostring(entity.pulse_duration),
+						},
+					}
 				end
 			elseif (entity.type == "container" or entity.type == "logistic-container")
 			then
 				if entity.inventory_type == "with_filters_and_bar"
 				then
-					add_description{"more-descriptions-mod.container-filters"}
+					add_description{
+						name = {"more-descriptions-mod.container-filters"},
+						value = "",
+					}
 				end
 			elseif entity.type == "cargo-wagon"
 			then
 				-- all cargo wagons support filters
-				add_description{"more-descriptions-mod.container-filters"}
+				add_description{
+					name = {"more-descriptions-mod.container-filters"},
+					value = "",
+				}
 			elseif entity.type == "display-panel"
 			then
-				add_description{"more-descriptions-mod.display-panel-max-text-width",
-					tostring(entity.max_text_width or 400)}
+				add_description{
+					name = {"more-descriptions-mod.display-panel-max-text-width"},
+					value = tostring(entity.max_text_width or 400),
+				}
 			elseif entity.type == "logistic-robot" or entity.type == "construction-robot"
 			then
 				if entity.speed_multiplier_when_out_of_energy > 0
 				then
-					add_description{"more-descriptions-mod.robot-speed-multiplier-when-out-of-energy",
-						tostring(entity.speed_multiplier_when_out_of_energy * 100)}
+					add_description{
+						name = {"more-descriptions-mod.robot-speed-multiplier-when-out-of-energy"},
+						value = tostring(entity.speed_multiplier_when_out_of_energy * 100),
+					}
 				else
-					add_description{"more-descriptions-mod.robot-crashes-when-out-of-energy"}
+					add_description{
+						name = {"more-descriptions-mod.robot-crashes-when-out-of-energy"},
+						value = "",
+					}
 				end
 			elseif entity.type == "inserter"
 			then
+				if entity.bulk
+				then
+					add_description{
+						name = {"more-descriptions-mod.inserter-bulk"},
+						value = tostring(entity.filter_count),
+					}
+				end
 				if entity.wait_for_full_hand
 				then
-					add_description{"more-descriptions-mod.inserter-wait-for-full-hand",
-					tostring(entity.filter_count)}
+					add_description{
+						name = {"more-descriptions-mod.inserter-wait-for-full-hand"},
+						value = "",
+					}
+				end
+				if entity.enter_drop_mode_if_held_stack_spoiled
+				then
+					add_description{
+						name = {"more-descriptions-mod.inserter-enters-drop-mode-if-held-stack-spoils"},
+						value = "",
+					}
 				end
 			elseif entity.type == "land-mine"
 			then
-				add_description{"more-descriptions-mod.land-mine-timeout",
-				seconds((entity.timeout or 120) / 60.0)}
+				add_description{
+					name = {"more-descriptions-mod.land-mine-timeout"},
+					value = seconds((entity.timeout or 120) / 60.0),
+				}
 			elseif entity.type == "radar"
 			then
 				if entity.connects_to_other_radars ~= false
 				then
-					add_description{"more-descriptions-mod.radar-connection"}
+					add_description{
+						name = {"more-descriptions-mod.radar-connection"},
+						value = "",
+					}
 				end
 			end
 			if entity.filter_count
 			then
-				add_description{"more-descriptions-mod.filter-count",
-					tostring(entity.filter_count)}
+				add_description{
+					name = {"more-descriptions-mod.filter-count"},
+					value = tostring(entity.filter_count),
+				}
 			end
 			for _, flag in pairs(entity.flags or {})
 			do
 				if flag == "no-automated-item-insertion"
 				then
-					table.insert(new_descriptions, {"more-descriptions-mod.no-automated-item-insertion"})
+					add_description{
+						name = {"more-descriptions-mod.no-automated-item-insertion"},
+						value = "",
+					}
 				end
 			end
 		end
-
-		if #new_descriptions > 0
-		then
-			local main_description = item.localised_description
-                and {"", item.localised_description, "\n"}
-                or {
-                    "?",
-                    {"", {"entity-description."..item.name}, "\n"},
-                    {"", {"item-description."..item.name}, "\n"},
-                    ""
-            }
-			item.localised_description = build_new_description(main_description, new_descriptions)
-		end
 	end
 end
 
 for _, recipe in pairs(data.raw.recipe)
 do
-	local new_descriptions = {}
-
+	---@param tooltip_field data.CustomTooltipField
+	local function add_description(tooltip_field)
+		generic_add_description(recipe, tooltip_field)
+	end
 	if recipe.allow_productivity
 	then
-		table.insert(new_descriptions, {"more-descriptions-mod.allows-productivity"})
+		add_description{
+			name = {"more-descriptions-mod.allows-productivity"},
+			value = "",
+		}
 	end
 
-	if #new_descriptions > 0
+	if recipes_that_have_productivity_research[recipe.name]
+	then
+		add_description{
+			name = {"more-descriptions-mod.recipe-has-productivity-research"},
+			value = "",
+		}
+	end
+
+	if recipe.result_is_always_fresh
 	then
-		local main_description = recipe.localised_description
-			and {"", recipe.localised_description, "\n"}
-			or {
-				"?",
-				{"", {"recipe-description."..recipe.name}, "\n"},
-				""
+		add_description{
+			name = {"more-descriptions-mod.recipe-result-is-always-fresh"},
+			value = "",
 		}
-		recipe.localised_description = build_new_description(main_description, new_descriptions)
+	end
+	if recipe.reset_freshness_on_craft
+	then
+		add_description{
+			name = {"more-descriptions-mod.recipe-result-freshness-reset"},
+			value = "",
+		}
 	end
 end
 
@@ -481,19 +666,27 @@
 do
 	for _, entity in pairs(data.raw[entity_category] or {})
 	do
-		local new_descriptions = {}
+		---@param tooltip_field data.CustomTooltipField
+		local function add_description(tooltip_field)
+			generic_add_description(entity, tooltip_field)
+		end
 
 		if entity.minable
 		then
-			table.insert(new_descriptions, {"more-descriptions-mod.mining-time",
-				seconds(entity.minable.mining_time)})
+			add_description{
+				name = {"more-descriptions-mod.mining-time"},
+				value = seconds(entity.minable.mining_time),
+			}
 		end
 
 		for _, flag in pairs(entity.flags or {})
 		do
 			if flag == "breaths-air"
 			then
-				table.insert(new_descriptions, {"more-descriptions-mod.breathes-air"})
+				add_description{
+					name = {"more-descriptions-mod.breathes-air"},
+					value = "",
+				}
 			end
 		end
 
@@ -501,48 +694,41 @@
 		then
 			if (entity.time_to_capture or 0) > 0
 			then
-				table.insert(new_descriptions, {"more-descriptions-mod.unit-spawner-time-to-capture",
-					seconds(entity.time_to_capture / 60.0)})
+				add_description{
+					name = {"more-descriptions-mod.unit-spawner-time-to-capture"},
+					value = seconds(entity.time_to_capture / 60.0),
+				}
 			end
 		end
-
-		if #new_descriptions > 0
-		then
-			local main_description = entity.localised_description
-				and {"", entity.localised_description, "\n"}
-				or {
-					"?",
-					{"", {"entity-description."..entity.name}, "\n"},
-					""
-			}
-			entity.localised_description = build_new_description(main_description, new_descriptions)
-		end
 	end
 end
 
-for _, space_location in pairs(data.raw["space-location"])
-do
-	local new_descriptions = {}
-
-	if (space_location.fly_condition or false)
-	then
-		table.insert(new_descriptions, {"more-descriptions-mod.space-location-fly-condition"})
-	end
-
-	if space_location.auto_save_on_first_trip == false -- (nil=true)
-	then
-		table.insert(new_descriptions, {"more-descriptions-mod.space-location-no-autosave"})
-	end
-
-	if #new_descriptions > 0
-	then
-		local main_description = space_location.localised_description
-			and {"", space_location.localised_description, "\n"}
-			or {
-				"?",
-				{"", {"space-location-description."..space_location.name}, "\n"},
-				""
-		}
-		space_location.localised_description = build_new_description(main_description, new_descriptions)
+if feature_flags.space_travel
+then
+	for _, category in pairs{"space-location", "planet"}
+	do
+		for _, space_location in pairs(data.raw[category])
+		do
+			---@param tooltip_field data.CustomTooltipField
+			local function add_description(tooltip_field)
+				generic_add_description(space_location, tooltip_field)
+			end
+			---@cast space_location data.SpaceLocationPrototype
+			local new_descriptions = {}
+			if (space_location.fly_condition or false)
+			then
+				add_description{
+					name = {"more-descriptions-mod.space-location-fly-condition"},
+					value = "",
+				}
+			end
+			if space_location.auto_save_on_first_trip == false -- (nil=true)
+			then
+				add_description{
+					name = {"more-descriptions-mod.space-location-no-autosave"},
+					value = "",
+				}
+			end
+		end
 	end
 end
\ No newline at end of file
--- a/more-descriptions/info.json	Sat Jul 05 00:35:55 2025 +0300
+++ b/more-descriptions/info.json	Wed Jul 23 14:46:54 2025 +0300
@@ -1,9 +1,14 @@
 {
     "name": "more-descriptions",
-    "version": "1.0.1",
+    "version": "1.2.0",
     "author": "teemu",
     "description": "Adds more information like entity size to item and recipe descriptions.",
-    "dependencies": ["? space-age", "? quality", "? promethium-quality"],
+    "dependencies": [
+        "base >= 2.0.60",
+        "? space-age",
+        "? quality",
+        "? promethium-quality"
+    ],
     "factorio_version": "2.0",
     "title": "More descriptive descriptions"
 }
\ No newline at end of file
--- a/more-descriptions/locale/en/more-descriptions.cfg	Sat Jul 05 00:35:55 2025 +0300
+++ b/more-descriptions/locale/en/more-descriptions.cfg	Wed Jul 23 14:46:54 2025 +0300
@@ -1,36 +1,49 @@
 [more-descriptions-mod]
+size=__1__×__2__
 ticks=__1__ __plural_for_parameter__1__{1=tick|rest=ticks}__
-refining-cost=[color=#fae8be][font=default-semibold]Refining cost:[/font][/color] __1__ [img=fluid.promethium-emulsion]
-recycling=[color=#fae8be][font=default-semibold]Recycling:[/font][/color] __1__ → __2__
-cannot-be-refined=[color=#fae8be][font=default-semibold]Cannot be refined[/font][/color]
-allows-productivity=[img=productivity-graphic][color=#fae8be][font=default-semibold]Allows productivity[/font][/color]
-size=[color=#fae8be][font=default-semibold]Entity size:[/font][/color] __1__ × __2__
-drops-full-belt-stacks=[color=#fae8be][font=default-semibold]Drops items as full stacks on belts[/font][/color]
-specific-heat=[color=#fae8be][font=default-semibold]Specific heat capacity:[/font][/color] __1__/°C
-reload-time=[color=#fae8be][font=default-semibold]Magazine reload time:[/font][/color] __1__
-is-military-target=[color=#fae8be][font=default-semibold]Is a military target[/font][/color]
-fires-automatically=[color=#fae8be][font=default-semibold]Fires automatically[/font][/color]
-agricultural-tower-num-inputs=[color=#fae8be][font=default-semibold]Input inventory size:[/font][/color] __1__
-agricultural-tower-growth-cell-size=[color=#fae8be][font=default-semibold]Planting cell size[/font][/color]: __1__ × __1__
-agricultural-tower-growth-cell-count=[color=#fae8be][font=default-semibold]Total planting cells[/font][/color]: __1__
-agricultural-tower-total-size=[color=#fae8be][font=default-semibold]Total farming dimensions[/font][/color]: __1__ × __1__
-armor-provides-flight=[color=#fae8be][font=default-semibold]Provides flight[/font][/color]
-energy-per-shot-fired=[color=#fae8be][font=default-semibold]Energy per shot fired[/font][/color]: __1__
-beacon-supply-area-distance=[color=#fae8be][font=default-semibold]Distribution range[/font][/color]: __1__
-car-immune-to-impacts=[color=#fae8be][font=default-semibold]Immune to impacts against:[/font][/color] __1__
-container-filters=[color=#fae8be][font=default-semibold]Allows item filters[/font][/color]
-display-panel-max-text-width=[color=#fae8be][font=default-semibold]Max. text width:[/font][/color] __1__
-mining-time=[color=#fae8be][font=default-semibold]Mining time:[/font][/color] __1__
-breathes-air=[color=#fae8be][font=default-semibold]Vulnerable to poison capsules[/font][/color]
-no-automated-item-insertion=[color=#fae8be][font=default-semibold]Cannot be automatically inserted items into[/font][/color]
-robot-speed-multiplier-when-out-of-energy=[color=#fae8be][font=default-semibold]Speed when out of energy:[/font][/color] __1__%
-robot-crashes-when-out-of-energy=[color=#fae8be][font=default-semibold]Crashes if runs out of energy[/font][/color]
-gun-accepts-ammo=[color=#fae8be][font=default-semibold]Accepts as ammo:[/font][/color] __1__
-filter-count=[color=#fae8be][font=default-semibold]Filter count:[/font][/color] __1__
-inserter-wait-for-full-hand=[color=#fae8be][font=default-semibold]Waits to fill its hand before swinging[/font][/color]
-land-mine-timeout=[color=#fae8be][font=default-semibold]Time until armed:[/font][/color] __1__
-radar-connection=[color=#fae8be][font=default-semibold]Wirelessly transmits circuit signals to other radars[/font][/color]
-constant-combinator-pulse-duration=[color=#fae8be][font=default-semibold]Stays on for:[/font][/color] __1__
-unit-spawner-time-to-capture=[color=#fae8be][font=default-semibold]Time to capture:[/font][/color] __1__
-space-location-fly-condition=[color=#fae8be][font=default-semibold]Uses a fly condition instead of a wait condition at destination[/font][/color]
-space-location-no-autosave=[color=#fae8be][font=default-semibold]No autosave for the first flight towards this location[/font][/color]
\ No newline at end of file
+promethium-emulsion-amount=__1__ [img=fluid.promethium-emulsion]
+refining-cost=Refining cost
+recycling=Recycling
+recycling-results=__1__ → __2__
+cannot-be-refined=Cannot be refined
+allows-productivity=Allows productivity modules
+recipe-has-productivity-research=Productivity can be improved with research
+recipe-result-is-always-fresh=Result is always fresh, even if ingredients spoil
+recipe-result-freshness-reset=Result is always fresh, unless ingredients spoil
+entity-size=Entity size
+drops-full-belt-stacks=Drops items as full stacks on belts
+specific-heat=Specific heat capacity
+energy-per-degrees-celsius=__1__/°C
+reload-time=Magazine reload time
+is-military-target=Is a military target
+fires-automatically=Fires automatically
+agricultural-tower-num-inputs=Input inventory size
+agricultural-tower-growth-cell-size=Planting cell size
+agricultural-tower-growth-cell-count=Total planting cells
+agricultural-tower-total-size=Total farming dimensions
+armor-provides-flight=Provides flight
+energy-per-shot-fired=Energy per shot fired
+beacon-supply-area-distance=Distribution range
+car-immune-to-impacts=Immune to impacts against
+container-filters=Allows item filters
+display-panel-max-text-width=Max. text width
+mining-time=Mining time
+breathes-air=Vulnerable to poison capsules
+no-automated-item-insertion=Cannot have items automatically inserted into
+robot-speed-multiplier-when-out-of-energy=Speed when out of energy
+robot-crashes-when-out-of-energy=Crashes if runs out of energy
+gun-accepts-ammo=Accepts as ammo
+filter-count=Filter count
+inserter-bulk=Bulk inserter
+inserter-wait-for-full-hand=Waits to fill its hand before swinging
+inserter-enters-drop-mode-if-held-stack-spoils=Swings if what it holds spoils
+land-mine-timeout=Time until armed
+radar-connection=Wirelessly transmits circuit signals to other radars
+constant-combinator-pulse-duration=Stays on for
+unit-spawner-time-to-capture=Time to capture
+space-location-fly-condition=Uses a fly condition instead of a wait condition at destination
+space-location-no-autosave=No autosave for the first flight towards this location
+heating-energy=Heating
+heating-energy-tooltip=The amount of heating this entity requires on cold planets to prevent freezing.
+no-heating-energy=Does not freeze
+value-per-end=__1__ per end
\ No newline at end of file

mercurial