Lua Utility Functions

Change of base formula for math.log() expressions:

local function log_base(base, expression)
	return math.log(expression) / math.log(base)

Check if value is between min and max:

local function is_within_range(value, min, max)
    return min <= value and value <= max

Calculate Manhattan distance between two points:

local function manhattan_distance(from, to)
    return vmath.vector3(to.x - from.x, to.y - from.y, to.z - from.z)

Get the sign of a number (1 for positive numbers, -1 for negative numbers, and 0 for zero):

local function sign(n)
    return n > 0 and 1 or (n < 0 and -1 or 0)

Converts a hex string to a vector4

function hex_to_color(hex)
  local r, g, b = hex:match("#(%x%x)(%x%x)(%x%x)")
  r, g, b = tonumber(r, 16), tonumber(g, 16), tonumber(b, 16)
  return vmath.vector4(r / 255, g / 255, b / 255, 1)
1 Like

Great idea!

This is a function which I find that I often need myself. I wonder if it should be part of vmath?


Check if point is within rectangle:

local function is_within_rectangle(point_x, point_y, rect_x, rect_y, rect_width, rect_height)
    return rect_x <= point_x and point_x <= rect_x + rect_width and rect_y <= point_y and point_y <= rect_y + rect_height

I think that would be a good addition. Maybe better for the math module, but if I understand correctly, math is built into the Lua language.

Here’s a bunch of stuff I collected over the years:

Also, a good animation tool I’ve found useful are low-pass filters for creating snapping effects or smoothing out movements:


I wrote this function when I was trying to pprint some enormous tables full of subtables.

    --individually prints each line of a nested table
local function recursive_pprint(t, table_name)

    if not t then

    table_name = table_name or ""
    local type_table = "table"
    for key, value in pairs(t) do
        if type(value) == type_table then
            recursive_pprint(value, key)
            print(table_name .. ": " .. key .. ": ", value)

Awesome. I actually have something similar too. See table_util.dump() above. The cool part is that it outputs valid Lua most of the time


Accurate framerate-independent lerp with delta-time:

-- `rate` is the lerp coefficient per second. So rate=0.5 halves the difference every second.
local function lerpdt(from, to, rate, dt)
	local diff = from - to           -- Target value is just an offset. Remove it and add it back.
	return diff * (1 - rate)^dt + to -- Flip rate so it's the expected direction (0 = no change).

Thanks to this site for the correct explanation.

Normally, the rate is the lerp coefficient per second. To adjust the time frame, divide dt by the desired time.

For example, if you want to halve a value every 1/60th of a second, do:

lerpdt(from, to, 0.5, dt/(1/60))

Has been unit tested. A basic test:

from, to, rate = 10, 0, 0.25

-- Lerp over 1 second all at once:
local result = lerpdt(from, to, rate, 1)

-- Lerp iteratively with times adding up to 1:
from = lerpdt(from, to, rate, 0.75)
from = lerpdt(from, to, rate, 0.01)
from = lerpdt(from, to, rate, 0.21)
from = lerpdt(from, to, rate, 0.01)
from = lerpdt(from, to, rate, 0.01)
from = lerpdt(from, to, rate, 0.01)
-- `from` and `result` should be equal (with some floating point error).

Thanks everyone. I will change the list in the first post to include categories to improve organization.

I’m having some trouble seeing how this is different than vmath.lerp() example from the docs: API reference (vmath)

It looks to me like the new part is the rate parameter?

The function I posted is framerate-independent. It can be used continuously in update() (i.e. without having a start and end time to the interpolation).

Let’s say you have a value that you want to halve every frame. Maybe you’re remaking Nuclear Throne and you want to damp the velocity of a shotgun bullet. If you do:

function update(self, dt)
	self.velocity = vmath.lerp(0.5, self.velocity, 0)

That is wrong. It will vary quite a bit depending on your framerate.
This is also wrong:

self.velocity = vmath.lerp(0.5*dt, self.velocity, 0)

Basically, you need this any time you want to continuously move one value towards another. Camera smoothing is another good example.


One of my favorite Lua function libs:


Hmm. That looks interesting. It’s definitely not a “LERP” since that’s a linear interpolation and the result here is not linear. More rather it’s sort-of like a low-pass filter, as in a function that always tends towards the target (if you take its limit), but “lags behind” a bit hence cutting off any abrupt movements (higher frequencies). I’m happy to see I’m not the only one using low pass filters for animation, yay!

I use this version lifted off the Wikipedia article on low pass filters:

-- @tparam number cutoff_frequency The cut-off frequency (in Hz) of the filter.
-- @treturn LowPassFilter The new filter function.
function M.low_pass(cutoff_frequency)
  local RC = 1.0 / (cutoff_frequency * 2.0 * math.pi);
  return function (previous_output, input, dt)
    local alpha = dt / (dt + RC);
    return previous_output + alpha * (input - previous_output);

Yes, the clamp function is really useful. Is it part of vmath now?

1 Like

No, we haven’t made any additions to vmath.

Just a module with list of “incoming” message ids and “shortcuts” for sending standard Defold messages. You can download it from Github defold-lua-annotations releases (look for in release assets). In example for Defold v1.5.0.