Math

Extra math utilities: clamping, interpolation, rounding, and more.

Core Functions

math.clamp

Signature: math.clamp(x, min, max)

Description: Restricts a value to be within a specified range.

Parameters:

  • x (number): The value to clamp.

  • min (number): The minimum allowable value.

  • max (number): The maximum allowable value.

Returns:

  • number: The clamped value (between min and max).

Example:

local health = -10
local clamped_health = math.clamp(health, 0, 100)
engine.log("Original: " .. health, 255, 255, 255, 255)
engine.log("Clamped: " .. clamped_health, 255, 255, 255, 255)
-- Output: Clamped: 0

local heat = 120
local clamped_heat = math.clamp(heat, 0, 100)
engine.log("Original: " .. heat, 255, 255, 255, 255)
engine.log("Clamped: " .. clamped_heat, 255, 255, 255, 255)
-- Output: Clamped: 100

math.lerp

Signature: math.lerp(a, b, t)

Description: Linearly interpolates between two values by a factor t.

Parameters:

  • a (number): The start value.

  • b (number): The end value.

  • t (number): The interpolation factor (usually between 0 and 1).

Returns:

  • number: The interpolated value.

Example:

local start = 0
local end_val = 100
local halfway = math.lerp(start, end_val, 0.5)
engine.log("Start: " .. start, 255, 255, 255, 255)
engine.log("End: " .. end_val, 255, 255, 255, 255)
engine.log("Halfway: " .. halfway, 255, 255, 255, 255)
-- Output: Halfway: 50

-- Create a smooth transition effect
local function animate(current, target, speed)
    return math.lerp(current, target, speed)
end

local position = 0
local target = 100
position = animate(position, target, 0.1)  -- Move 10% of the remaining distance
engine.log("New position: " .. position, 255, 255, 255, 255)

math.round

Signature: math.round(x)

Description: Rounds a number to the nearest integer.

Parameters:

  • x (number): The number to round.

Returns:

  • number: The rounded integer.

Example:

local value1 = 3.2
local value2 = 3.7
local value3 = 3.5
engine.log(value1 .. " rounded: " .. math.round(value1), 255, 255, 255, 255)
engine.log(value2 .. " rounded: " .. math.round(value2), 255, 255, 255, 255)
engine.log(value3 .. " rounded: " .. math.round(value3), 255, 255, 255, 255)
-- Output: 3.2 rounded: 3
-- Output: 3.7 rounded: 4
-- Output: 3.5 rounded: 4

math.round_up

Signature: math.round_up(x)

Description: Rounds a number upward (ceiling function).

Parameters:

  • x (number): The number to round up.

Returns:

  • number: The rounded up integer.

Example:

local value1 = 3.2
local value2 = 3.0
engine.log(value1 .. " rounded up: " .. math.round_up(value1), 255, 255, 255, 255)
engine.log(value2 .. " rounded up: " .. math.round_up(value2), 255, 255, 255, 255)
-- Output: 3.2 rounded up: 4
-- Output: 3.0 rounded up: 3

math.round_down

Signature: math.round_down(x)

Description: Rounds a number downward (floor function).

Parameters:

  • x (number): The number to round down.

Returns:

  • number: The rounded down integer.

Example:

local value1 = 3.7
local value2 = 3.0
engine.log(value1 .. " rounded down: " .. math.round_down(value1), 255, 255, 255, 255)
engine.log(value2 .. " rounded down: " .. math.round_down(value2), 255, 255, 255, 255)
-- Output: 3.7 rounded down: 3
-- Output: 3.0 rounded down: 3

math.round_to_nearest

Signature: math.round_to_nearest(x, step)

Description: Rounds a number to the nearest multiple of step.

Parameters:

  • x (number): The number to round.

  • step (number): The step size to round to.

Returns:

  • number: The rounded value.

Example:

local value = 42.32
engine.log(value .. " rounded to nearest 5: " .. math.round_to_nearest(value, 5), 255, 255, 255, 255)
engine.log(value .. " rounded to nearest 0.1: " .. math.round_to_nearest(value, 0.1), 255, 255, 255, 255)
-- Output: 42.32 rounded to nearest 5: 40
-- Output: 42.32 rounded to nearest 0.1: 42.3

math.sign

Signature: math.sign(x)

Description: Returns the sign of a number as -1, 0, or 1.

Parameters:

  • x (number): The number to get the sign of.

Returns:

  • number: -1 if negative, 0 if zero, 1 if positive.

Example:

local value1 = -42
local value2 = 0
local value3 = 128
engine.log("Sign of " .. value1 .. ": " .. math.sign(value1), 255, 255, 255, 255)
engine.log("Sign of " .. value2 .. ": " .. math.sign(value2), 255, 255, 255, 255)
engine.log("Sign of " .. value3 .. ": " .. math.sign(value3), 255, 255, 255, 255)
-- Output: Sign of -42: -1
-- Output: Sign of 0: 0
-- Output: Sign of 128: 1

math.map

Signature: math.map(x, in_min, in_max, out_min, out_max)

Description: Maps a value from one range to another.

Parameters:

  • x (number): The value to map.

  • in_min (number): The minimum of the input range.

  • in_max (number): The maximum of the input range.

  • out_min (number): The minimum of the output range.

  • out_max (number): The maximum of the output range.

Returns:

  • number: The mapped value.

Example:

local percent = 75
local health = math.map(percent, 0, 100, 0, 1000)
engine.log(percent .. "% maps to " .. health .. " health points", 255, 255, 255, 255)
-- Output: 75% maps to 750 health points

-- Convert a value from one range to another
local temperature_celsius = 25
local temperature_fahrenheit = math.map(temperature_celsius, 0, 100, 32, 212)
engine.log(temperature_celsius .. "°C = " .. temperature_fahrenheit .. "°F", 255, 255, 255, 255)
-- Output: 25°C = 77°F

math.saturate

Signature: math.saturate(x)

Description: Clamps a value between 0 and 1.

Parameters:

  • x (number): The value to saturate.

Returns:

  • number: The saturated value (between 0 and 1).

Example:

local value1 = -0.5
local value2 = 0.5
local value3 = 1.5
engine.log(value1 .. " saturated: " .. math.saturate(value1), 255, 255, 255, 255)
engine.log(value2 .. " saturated: " .. math.saturate(value2), 255, 255, 255, 255)
engine.log(value3 .. " saturated: " .. math.saturate(value3), 255, 255, 255, 255)
-- Output: -0.5 saturated: 0
-- Output: 0.5 saturated: 0.5
-- Output: 1.5 saturated: 1

Validation & Checks

math.is_nan

Signature: math.is_nan(x)

Description: Returns true if x is NaN (Not a Number).

Parameters:

  • x (number): The value to check.

Returns:

  • boolean: true if x is NaN, false otherwise.

Example:

local value1 = 0/0  -- NaN
local value2 = 42
engine.log("Is " .. tostring(value1) .. " NaN? " .. tostring(math.is_nan(value1)), 255, 255, 255, 255)
engine.log("Is " .. value2 .. " NaN? " .. tostring(math.is_nan(value2)), 255, 255, 255, 255)
-- Output: Is nan NaN? true
-- Output: Is 42 NaN? false

math.is_inf

Signature: math.is_inf(x)

Description: Returns true if x is infinite.

Parameters:

  • x (number): The value to check.

Returns:

  • boolean: true if x is infinite, false otherwise.

Example:

local value1 = 1/0  -- Infinity
local value2 = 42
engine.log("Is " .. tostring(value1) .. " Infinite? " .. tostring(math.is_inf(value1)), 255, 255, 255, 255)
engine.log("Is " .. value2 .. " Infinite? " .. tostring(math.is_inf(value2)), 255, 255, 255, 255)
-- Output: Is inf Infinite? true
-- Output: Is 42 Infinite? false

Interpolation & Range Tools

math.smoothstep

Signature: math.smoothstep(edge0, edge1, x)

Description: Performs smooth Hermite interpolation between 0 and 1 when edge0 < x < edge1.

Parameters:

  • edge0 (number): The lower edge of the interpolation range.

  • edge1 (number): The upper edge of the interpolation range.

  • x (number): The input value to interpolate.

Returns:

  • number: The smoothly interpolated value (0 to 1).

Example:

local value = 0.5
local smooth = math.smoothstep(0, 1, value)
engine.log("Value: " .. value, 255, 255, 255, 255)
engine.log("Smoothstep: " .. smooth, 255, 255, 255, 255)
-- The output will be a value that approaches 0.5 but with a smoothed curve

-- Create a smooth fade effect
local function smooth_fade(current, min, max)
    return math.smoothstep(min, max, current)
end

local position = 0.3
local fade_value = smooth_fade(position, 0, 1)
engine.log("Fade value at position " .. position .. ": " .. fade_value, 255, 255, 255, 255)

math.inverse_lerp

Signature: math.inverse_lerp(a, b, x)

Description: Computes the normalized parameter t where x lies between a and b.

Parameters:

  • a (number): The start of the range.

  • b (number): The end of the range.

  • x (number): The value to find the parameter for.

Returns:

  • number: The normalized parameter t (usually between 0 and 1).

Example:

local min = 100
local max = 200
local value = 150
local t = math.inverse_lerp(min, max, value)
engine.log("Value " .. value .. " is at position " .. t .. " between " .. min .. " and " .. max, 255, 255, 255, 255)
-- Output: Value 150 is at position 0.5 between 100 and 200

-- Find percentage of health
local max_health = 1000
local current_health = 750
local health_percent = math.inverse_lerp(0, max_health, current_health)
engine.log("Health: " .. (health_percent * 100) .. "%", 255, 255, 255, 255)
-- Output: Health: 75%

math.fract

Signature: math.fract(x)

Description: Returns the fractional part of x.

Parameters:

  • x (number): The value to get the fractional part of.

Returns:

  • number: The fractional part of x (always between 0 and 1).

Example:

local value1 = 3.75
local value2 = -2.25
engine.log("Fractional part of " .. value1 .. ": " .. math.fract(value1), 255, 255, 255, 255)
engine.log("Fractional part of " .. value2 .. ": " .. math.fract(value2), 255, 255, 255, 255)
-- Output: Fractional part of 3.75: 0.75
-- Output: Fractional part of -2.25: 0.75

math.wrap

Signature: math.wrap(x, min, max)

Description: Wraps a value so it stays within the specified range.

Parameters:

  • x (number): The value to wrap.

  • min (number): The minimum of the range.

  • max (number): The maximum of the range.

Returns:

  • number: The wrapped value.

Example:

local angle = 370  -- Degrees (past 360)
local wrapped_angle = math.wrap(angle, 0, 360)
engine.log("Original angle: " .. angle .. "°", 255, 255, 255, 255)
engine.log("Wrapped angle: " .. wrapped_angle .. "°", 255, 255, 255, 255)
-- Output: Wrapped angle: 10°

-- Wrap time of day (in hours)
local time = 25  -- 25 hours
local day_time = math.wrap(time, 0, 24)
engine.log("Time: " .. day_time .. ":00", 255, 255, 255, 255)
-- Output: Time: 1:00

Math API Usage Examples

Smooth Movement

-- Create a smooth movement system
local function smooth_move(current, target, delta_time, speed)
    local t = math.clamp(delta_time * speed, 0, 1)
    return math.lerp(current, target, t)
end

local position = 0
local target = 100
local delta_time = 0.16  -- Assuming 60 FPS
local speed = 2

position = smooth_move(position, target, delta_time, speed)
engine.log("New position: " .. position, 255, 255, 255, 255)

Health Bar Colors

-- Get color for health bar based on percentage
local function get_health_color(health_percent)
    -- Red when low, yellow in middle, green when high
    local r, g, b
    
    if health_percent < 0.5 then
        -- Interpolate from red to yellow (0% to 50%)
        local t = math.inverse_lerp(0, 0.5, health_percent)
        r = 255
        g = math.round(math.lerp(0, 255, t))
        b = 0
    else
        -- Interpolate from yellow to green (50% to 100%)
        local t = math.inverse_lerp(0.5, 1, health_percent)
        r = math.round(math.lerp(255, 0, t))
        g = 255
        b = 0
    end
    
    return r, g, b
end

local health = 75  -- percentage
local r, g, b = get_health_color(health / 100)
engine.log("Health color for " .. health .. "%: RGB(" .. r .. ", " .. g .. ", " .. b .. ")", r, g, b, 255)

Circular Motion

-- Create circular motion using math functions
local function circular_position(center_x, center_y, radius, angle_degrees)
    local angle_rad = angle_degrees * (math.pi / 180)
    local x = center_x + radius * math.cos(angle_rad)
    local y = center_y + radius * math.sin(angle_rad)
    return math.round(x), math.round(y)
end

local center_x, center_y = 400, 300
local radius = 100
local angle = 45  -- degrees

local x, y = circular_position(center_x, center_y, radius, angle)
engine.log("Position at " .. angle .. "°: (" .. x .. ", " .. y .. ")", 255, 255, 255, 255)

Last updated

Was this helpful?