Here a list of little functions I find handy. Nothing fancy or even technical but some good QoL.
Clamp
function math.clamp(a, min, max)
if min > max then
min, max = max, min
end
return math.max(min, math.min(max, a))
end
Not sure why clamp is still not part of lua but this one is a must have.
Ring
function math.ring(a, min, max)
if min > max then
min, max = max, min
end
return min + (a-min)%(max-min)
end
function math.ring_int(a, min, max)
return math.ring(a, min, max+1)
end
Like clamp but instead of clamping it loop back to the start. Useful to cycle through values, for example an index in a menu
index = math.ring_int( index + 1, 1, 4)
-> 1, 2, 3, 4, 1, 2, 3, 4 etc.
Approach
function math.approach( value, target, step)
if value==target then
return value, true
end
local d = target-value
if d>0 then
value = value + step
if value >= target then
return target, true
else
return value, false
end
elseif d<0 then
value = value - step
if value <= target then
return target, true
else
return value, false
end
else
return value, true
end
end
Got this one from the Celeste source code and it so simple but so useful. It just change a value toward a target. It returns a tuple, the new value and a boolean that says if it is on target.
Approach to infinity (but not beyond)
function math.infinite_approach(at_zero, at_infinite, x_halfway, x)
return at_infinite - (at_infinite-at_zero)*0.5^(x/x_halfway)
end
Another approach function but with this one it never reaches the target. Useful for example to balance a game mode to always increase the difficulty but have a clear ceiling. You now the lowest and highest value (at_zero, at_infinite), you specify at which point you are midway and the rest is a nice natural curve.
So for example if you want to generate new enemies that get trickier as the playtime progress. The first enemies start with just 1 health, and eventually enemies can go up to 20. We can balance that we start to see enemies with 10 health after 5 minutes.
new_enemy.health = math.infinite_approach(1, 20, 5*60, playtime_in_seconds)
Random Element in a table
function table.random( t )
if type(t)~="table" then return nil end
return t[math.ceil(math.random(#t))]
end
Just return a random element in an array. Would be even better if lua had an even better RNG.
Call function for each array element
function table.each( t, fn )
if type(fn)~="function" then return end
for _, e in pairs(t) do
fn(e)
end
end
As I said, nothing special but useful.
What are your little functions you couldn't live without anymore?