From ba14a2b12dd0ef3b171d5092e8237e4c570a205c Mon Sep 17 00:00:00 2001 From: efrec Date: Wed, 19 Nov 2025 16:55:54 -0500 Subject: [PATCH 1/8] add hidden modoption wreckage_metal_ratio This isn't the most neat code since it keeps the wreck metal% default value in two places. I didn't want to move that value default entirely into the modoption logic, though. --- gamedata/alldefs_post.lua | 15 +++++++++++---- modoptions.lua | 13 +++++++++++++ 2 files changed, 24 insertions(+), 4 deletions(-) diff --git a/gamedata/alldefs_post.lua b/gamedata/alldefs_post.lua index d3e699229cf..d06f248e6f9 100644 --- a/gamedata/alldefs_post.lua +++ b/gamedata/alldefs_post.lua @@ -41,6 +41,15 @@ end -- DEFS POST PROCESSING ------------------------- +local modOptions = Spring.GetModOptions() + +local wreckMetalRatio = 0.6 +local heapMetalRatio = 0.25 +if modOptions.wreckage_metal_ratio then + wreckMetalRatio = modOptions.wreckage_metal_ratio -- 0.2 to 0.8 + heapMetalRatio = (wreckMetalRatio + 0.25) / 3 -- 0.15 to 0.35 +end + --[[ Sanitize to whole frames (plus leeways because float arithmetic is bonkers). The engine uses full frames for actual reload times, but forwards the raw value to LuaUI (so for example calculated DPS is incorrect without sanitisation). ]] @@ -75,8 +84,6 @@ local function processWeapons(unitDefName, unitDef) end function UnitDef_Post(name, uDef) - local modOptions = Spring.GetModOptions() - local isScav = string.sub(name, -5, -1) == "_scav" local basename = isScav and string.sub(name, 1, -6) or name @@ -920,14 +927,14 @@ function UnitDef_Post(name, uDef) if uDef.featuredefs.dead then uDef.featuredefs.dead.damage = uDef.health if uDef.metalcost and uDef.energycost then - uDef.featuredefs.dead.metal = math.floor(uDef.metalcost * 0.6) + uDef.featuredefs.dead.metal = math.floor(uDef.metalcost * wreckMetalRatio) end end -- heaps if uDef.featuredefs.heap then uDef.featuredefs.heap.damage = uDef.health if uDef.metalcost and uDef.energycost then - uDef.featuredefs.heap.metal = math.floor(uDef.metalcost * 0.25) + uDef.featuredefs.heap.metal = math.floor(uDef.metalcost * heapMetalRatio) end end end diff --git a/modoptions.lua b/modoptions.lua index b2e0486da82..42180af5b79 100644 --- a/modoptions.lua +++ b/modoptions.lua @@ -505,6 +505,19 @@ local options = { section = "options", }, + { + key = "wreckage_metal_ratio", + name = "Unit Wreck Metal Percentage", + desc = "Percent of unit metal that is left in its wrecks (and heaps)", + hidden = true, + type = "number", + section = "options", + def = 0.6, + min = 0.2, + max = 0.8, + step = 0.05, + }, + { key = "coop", name = "Cooperative mode", From be9585216a146616134e8ba0c7186742dac66462 Mon Sep 17 00:00:00 2001 From: efrec Date: Wed, 19 Nov 2025 16:56:10 -0500 Subject: [PATCH 2/8] nudge reclaim highlight min feature metal based on modoption --- luaui/Widgets/gui_reclaim_field_highlight.lua | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/luaui/Widgets/gui_reclaim_field_highlight.lua b/luaui/Widgets/gui_reclaim_field_highlight.lua index 634c1f7c216..45539af19ac 100644 --- a/luaui/Widgets/gui_reclaim_field_highlight.lua +++ b/luaui/Widgets/gui_reclaim_field_highlight.lua @@ -74,6 +74,10 @@ local checkFrequency = 0.66 -- Update rate, in seconds local epsilon = 300 -- Clustering distance - increased to merge nearby fields and prevent overlaps local minFeatureValue = 9 +if Spring.GetModOptions().wreckage_metal_ratio then + local ratio = Spring.GetModOptions().wreckage_metal_ratio / 0.6 -- 0.3333 to 1.25 + minFeatureValue = minFeatureValue * (ratio ^ 1 / 3) -- gravitate strongly toward 1 +end -- Maximum cluster size in elmos - clusters larger than this will be split into sub-clusters local maxClusterSize = 3000 -- Adjust this value: smaller = more sub-clusters, larger = fewer but bigger fields From 8669f66ccf0d928de99d380e10d4ac4fd5e97ad4 Mon Sep 17 00:00:00 2001 From: efrec Date: Thu, 20 Nov 2025 12:23:00 -0500 Subject: [PATCH 3/8] should be 0.15, not 0.25, and clamp to limits instead of commenting limits --- gamedata/alldefs_post.lua | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/gamedata/alldefs_post.lua b/gamedata/alldefs_post.lua index d06f248e6f9..cfb5a67337d 100644 --- a/gamedata/alldefs_post.lua +++ b/gamedata/alldefs_post.lua @@ -45,9 +45,12 @@ local modOptions = Spring.GetModOptions() local wreckMetalRatio = 0.6 local heapMetalRatio = 0.25 -if modOptions.wreckage_metal_ratio then - wreckMetalRatio = modOptions.wreckage_metal_ratio -- 0.2 to 0.8 - heapMetalRatio = (wreckMetalRatio + 0.25) / 3 -- 0.15 to 0.35 + +if modOptions.wreckage_metal_ratio ~= 0.6 then + -- An actual f(x): [0,1] -> [0,1/3], with f(0.6)=0.25 would be a hermite polynomial or something + local low, mid, high = 0, 1 / 3, 1 -- so ignore that and do something over-simple, because, gamedev + wreckMetalRatio = math.clamp(modOptions.wreckage_metal_ratio, low, high) + heapMetalRatio = math.clamp((wreckMetalRatio + 0.15) / 3, low, mid) end --[[ Sanitize to whole frames (plus leeways because float arithmetic is bonkers). From 6af95d4010b993ef4344e6aeb4ec68a8177bf98c Mon Sep 17 00:00:00 2001 From: efrec Date: Thu, 20 Nov 2025 12:24:10 -0500 Subject: [PATCH 4/8] doc our kind of bad modoption min/max values --- modoptions.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modoptions.lua b/modoptions.lua index 42180af5b79..46955efbad7 100644 --- a/modoptions.lua +++ b/modoptions.lua @@ -513,8 +513,8 @@ local options = { type = "number", section = "options", def = 0.6, - min = 0.2, - max = 0.8, + min = 0, -- see usage in alldefs_post for actual bounds + max = 1, step = 0.05, }, From 317cb9fc28e89d147ebb49e32e5dfa652e551a3a Mon Sep 17 00:00:00 2001 From: efrec Date: Thu, 20 Nov 2025 12:36:12 -0500 Subject: [PATCH 5/8] less lame comment --- modoptions.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modoptions.lua b/modoptions.lua index 46955efbad7..728c044aa69 100644 --- a/modoptions.lua +++ b/modoptions.lua @@ -513,7 +513,7 @@ local options = { type = "number", section = "options", def = 0.6, - min = 0, -- see usage in alldefs_post for actual bounds + min = 0, -- see usage in alldefs_post when changing actual bounds max = 1, step = 0.05, }, From a105f337ad7774b1918be395331482b972b6a4c9 Mon Sep 17 00:00:00 2001 From: efrec Date: Thu, 20 Nov 2025 13:06:54 -0500 Subject: [PATCH 6/8] simplified modoptions: wreck_metal_ratio and heap_metal_ratio --- gamedata/alldefs_post.lua | 11 ++--------- modoptions.lua | 19 ++++++++++++++++--- 2 files changed, 18 insertions(+), 12 deletions(-) diff --git a/gamedata/alldefs_post.lua b/gamedata/alldefs_post.lua index cfb5a67337d..b40b420382e 100644 --- a/gamedata/alldefs_post.lua +++ b/gamedata/alldefs_post.lua @@ -43,15 +43,8 @@ end local modOptions = Spring.GetModOptions() -local wreckMetalRatio = 0.6 -local heapMetalRatio = 0.25 - -if modOptions.wreckage_metal_ratio ~= 0.6 then - -- An actual f(x): [0,1] -> [0,1/3], with f(0.6)=0.25 would be a hermite polynomial or something - local low, mid, high = 0, 1 / 3, 1 -- so ignore that and do something over-simple, because, gamedev - wreckMetalRatio = math.clamp(modOptions.wreckage_metal_ratio, low, high) - heapMetalRatio = math.clamp((wreckMetalRatio + 0.15) / 3, low, mid) -end +local wreckMetalRatio = math.clamp(modOptions.wreck_metal_ratio, 0, 1) +local heapMetalRatio = math.clamp(modOptions.heap_metal_ratio, 0, wreckMetalRatio) --[[ Sanitize to whole frames (plus leeways because float arithmetic is bonkers). The engine uses full frames for actual reload times, but forwards the raw diff --git a/modoptions.lua b/modoptions.lua index 728c044aa69..c880d814157 100644 --- a/modoptions.lua +++ b/modoptions.lua @@ -506,9 +506,9 @@ local options = { }, { - key = "wreckage_metal_ratio", - name = "Unit Wreck Metal Percentage", - desc = "Percent of unit metal that is left in its wrecks (and heaps)", + key = "wreck_metal_ratio", + name = "Wreck Metal Percent", + desc = "Percent of unit metal that is left in its wrecks", hidden = true, type = "number", section = "options", @@ -518,6 +518,19 @@ local options = { step = 0.05, }, + { + key = "heap_metal_ratio", + name = "Heap Metal Percent", + desc = "Percent of unit metal that is left in its heaps", + hidden = true, + type = "number", + section = "options", + def = 0.25, + min = 0, + max = 1, -- bounded in alldefs_post to wreck_metal_ratio + step = 0.05, + }, + { key = "coop", name = "Cooperative mode", From 594eee1a978d608a4ffc219549d90b42f3773f13 Mon Sep 17 00:00:00 2001 From: efrec Date: Thu, 20 Nov 2025 13:11:11 -0500 Subject: [PATCH 7/8] handle zeroes and low reclaim amounts in reclaim field highlight --- luaui/Widgets/gui_reclaim_field_highlight.lua | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/luaui/Widgets/gui_reclaim_field_highlight.lua b/luaui/Widgets/gui_reclaim_field_highlight.lua index 45539af19ac..0260dbcd048 100644 --- a/luaui/Widgets/gui_reclaim_field_highlight.lua +++ b/luaui/Widgets/gui_reclaim_field_highlight.lua @@ -74,9 +74,9 @@ local checkFrequency = 0.66 -- Update rate, in seconds local epsilon = 300 -- Clustering distance - increased to merge nearby fields and prevent overlaps local minFeatureValue = 9 -if Spring.GetModOptions().wreckage_metal_ratio then - local ratio = Spring.GetModOptions().wreckage_metal_ratio / 0.6 -- 0.3333 to 1.25 - minFeatureValue = minFeatureValue * (ratio ^ 1 / 3) -- gravitate strongly toward 1 +do + local ratio = Spring.GetModOptions().wreck_metal_ratio / 0.6 -- 0 to 1.25 + minFeatureValue = minFeatureValue * (0.75 + ratio * 0.25) -- gravitate toward 1 end -- Maximum cluster size in elmos - clusters larger than this will be split into sub-clusters From 6072e5147df8efa46b51101e6d820de4081e1b72 Mon Sep 17 00:00:00 2001 From: efrec Date: Thu, 20 Nov 2025 13:14:45 -0500 Subject: [PATCH 8/8] move math in comment to code, again --- luaui/Widgets/gui_reclaim_field_highlight.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/luaui/Widgets/gui_reclaim_field_highlight.lua b/luaui/Widgets/gui_reclaim_field_highlight.lua index 0260dbcd048..2ae996e4cbf 100644 --- a/luaui/Widgets/gui_reclaim_field_highlight.lua +++ b/luaui/Widgets/gui_reclaim_field_highlight.lua @@ -75,7 +75,7 @@ local epsilon = 300 -- Clustering distance - increased to merge nearby fields an local minFeatureValue = 9 do - local ratio = Spring.GetModOptions().wreck_metal_ratio / 0.6 -- 0 to 1.25 + local ratio = math.clamp(Spring.GetModOptions().wreck_metal_ratio / 0.6, 0, 1.5) minFeatureValue = minFeatureValue * (0.75 + ratio * 0.25) -- gravitate toward 1 end