starlit

vec3, color, bit and math

The helper types and functions we write in Lua for you, the extra math functions, and the list of standard Lua names that remain.

vec3, color, bit and the extra math functions are not part of the host. They are Lua code that we run inside your own state before your script starts. They cost your script nothing except the memory of their closures. If a script replaces one of them, only that script is affected.

vec3

vec3([x [, y [, z]]]) -> vec3

A vec3 is a table with the fields x, y and z and a metatable that gives it operators and methods. A missing argument is 0. The constructor does not check its arguments, and arithmetic on a vec3 that holds something other than numbers raises an ordinary Lua error.

Operators

expressionresult
a + b, a - ba new vec3. Both sides have to be vec3.
a * ba new vec3. b may be a number, or a vec3 for a component by component product. A number on the left works as well.
a / ba new vec3. b may be a number or a vec3 (component by component).
-aa new vec3
a == btrue if all three components are equal
tostring(a)vec3(1, 2, 3)

Methods. A method marked "in place" changes the vec3 it is called on and returns it. All others leave it alone.

methodreturnswhat it does
v:clone()new vec3a copy
v:init([x [, y [, z]]])vsets the three components, in place. Missing ones become 0.
v:unpack()x, y, zthe three components as numbers
v:length()numberlength
v:lengthsqr()numberlength squared
v:length2d()numberlength of the x and y part
v:length2dsqr()numberthe same, squared
v:dist(o)numberdistance to the vec3 o
v:distsqr(o)numberdistance squared
v:dist2d(o)numberdistance on the x and y plane
v:dist2dsqr(o)numberthe same, squared
v:in_range(o, range)booleantrue if the distance to o is range or less
v:dot(o)numberdot product
v:cross(o)new vec3cross product
v:scale(s)vmultiplies by the number s, in place
v:scaled(s)new vec3the same, as a new vec3
v:normalize()numberscales to length 1, in place, and returns the length it had. A vec3 of length 0 stays 0 and returns 0.
v:normalized()new vec3the same direction at length 1. A vec3 of length 0 gives a zero vec3.
v:lerp(o, t)new vec3v + (o - v) * t. t is not clamped.
v:floor()vrounds each component down, in place
v:ceil()vrounds each component up, in place
v:to(o)new vec3the unit vector that points from v to o
v:angles()new vec3treats v as a direction and returns vec3(pitch, yaw, 0) in degrees. Positive pitch looks down.
v:angles(pitch, yaw)vthe other way: sets v, in place, to the unit direction for these angles. A vec3 can be passed instead, its x is the pitch and its y the yaw.
v:vectors()right, uptwo new vec3: the right and up directions of a view that looks along v
v:closest_ray_point(a, b)new vec3the point on the segment from a to b that is closest to v. It stops at both ends.
v:dist_to_ray(a, dir)numberthe distance from v to the half-line that starts at a and runs along dir. It stops at a and runs on without end.
v:to_screen()vec3 or nilthe screen position as vec3(x, y, 0), or nil where game.to_screen would return nil

game.to_screen takes three numbers. To pass a vec3, unpack it: game.to_screen(v:unpack()).

local a, b = vec3(0, 0, 0), vec3(30, 40, 0)
local d = b - a
log.info(d:length())            -- 50
log.info(a:dist(b))             -- 50
log.info(tostring(d:normalized()))
local pitch_yaw = vec3(1, 0, 0):angles()
log.info(pitch_yaw.y)           -- 0

color

color([r [, g [, b [, a]]]]) -> color
color(hex) -> color

A color is a table with the fields r, g, b and a and a metatable. Draw functions accept it wherever a colour is expected, and the gradient functions require it.

The four numbers are rounded and clamped to 0 to 255. A missing channel is 255, so color() is opaque white.

A string selects the hex form. The digits are read in pairs:

stringmeaning
"C8"grey 0xC8, opaque
"FFA0"grey 0xFF with alpha 0xA0
"FFC319"red, green, blue
"AABBCCDD"red, green, blue, alpha

Any other string leaves the colour opaque white.

Operators a == b is true when all four channels are equal. tostring(c) gives color(10, 20, 30, 40).

Methods. "In place" works as for vec3.

methodreturnswhat it does
c:clone()new colora copy
c:unpack()r, g, b, athe four channels
c:init(r, g, b, a)csets the channels in place, a missing one becomes 255. c:init("AABBCCDD") takes a hex string.
c:as_fraction(r, g, b, a)csets the channels from numbers between 0 and 1, in place. A missing one is 1.
c:to_fraction()r, g, b, athe channels as numbers between 0 and 1
c:to_hex()stringRRGGBBAA in capital letters
c:as_int32(v)csets the channels, in place, from an integer packed as alpha, red, green, blue
c:to_int32()integerthe same packing: alpha in the top byte, then red, green and blue
c:lerp(o, t)new colorblends towards o. t is not clamped, the channels are.
c:alpha_modulate(a)new colora copy with the alpha set to a, 0 to 255. It replaces the alpha and does not multiply it.
c:grayscale([t])new colorblends towards the grey of the same brightness. t is 1 if left out, 0 changes nothing.
c:as_hsv(h, s, v [, a])csets the colour, in place, from hue, saturation and value, each 0 to 1. a is 0 to 1 and 1 if left out.
c:to_hsv()h, s, veach 0 to 1
c:as_hsl(h, s, l [, a])clike as_hsv, with lightness
c:to_hsl()h, s, leach 0 to 1
local red = color(255, 0, 0)
local half = red:alpha_modulate(128)
local mix = red:lerp(color("3C78FF"), 0.5)
log.info(mix:to_hex())
local rainbow = color():as_hsv(0.33, 1, 1)
log.info(rainbow.g)

bit

Bit operations on 32-bit integers. Every result is a signed 32-bit integer, from -2147483648 to 2147483647. An argument is rounded to the nearest whole number and read modulo 2^32. NaN and infinity count as 0. An argument that is not a number raises an error. Shift counts are taken modulo 32.

functionresult
bit.tobit(x)x as a signed 32-bit integer
bit.band(a, ...)bitwise and of all arguments
bit.bor(a, ...)bitwise or of all arguments
bit.bxor(a, ...)bitwise exclusive or of all arguments
bit.bnot(x)bitwise not
bit.lshift(x, n)shift left by n bits
bit.rshift(x, n)logical shift right: zeros come in from the left
bit.arshift(x, n)arithmetic shift right: the sign bit is copied
bit.rol(x, n)rotate left
bit.ror(x, n)rotate right
bit.bswap(x)reverse the four bytes
bit.tohex(x [, n])the last n hex digits of x as a string. n is 8 if left out, and is limited to 1 to 8. A negative n gives capital letters.
log.info(bit.band(0xFF, 0x0F))       -- 15
log.info(bit.lshift(1, 31))          -- -2147483648
log.info(bit.tohex(255, 2))          -- ff
log.info(bit.tohex(255, -4))         -- 00FF
log.info(bit.bswap(0x12345678) == 0x78563412)

math extras

These are added to your own math table.

functionresult
math.clamp(v, lo, hi)v limited to lo and hi. Either bound may be nil to leave that side open.
math.lerp(a, b, t)a + (b - a) * t
math.map(v, in_from, in_to, out_from, out_to [, clamp])moves v from the range in_from to in_to onto the range out_from to out_to. If clamp is true the position is limited to the ends.
math.normalize_yaw(x)the angle x in degrees wrapped to -180 to 180
math.atan2(y, x)the angle of the point x, y in radians. The same as math.atan(y, x).
math.pow(x, y)x ^ y
math.log10(x)logarithm to base 10
math.sinh(x), math.cosh(x), math.tanh(x)hyperbolic functions. math.tanh is exactly 1 above 20 and exactly -1 below -20.
math.frexp(x)m, e with x = m * 2^e and m between 0.5 and 1 in size. For 0, NaN and infinity it returns x, 0.
math.ldexp(x, e)x * 2^e
local yaw = math.normalize_yaw(190)        -- -170
local alpha = math.clamp(300, 0, 255)      -- 255
local x = math.map(5, 0, 10, 100, 200)     -- 150.0
local half = math.lerp(10, 20, 0.5)        -- 15.0
log.info(yaw .. " " .. alpha .. " " .. x .. " " .. half)

Standard library

These names of standard Lua are available. Everything else of the standard library is not. The differences in behaviour are in How scripts run.

Base functions. unpack is the same function as table.unpack.

assert error getmetatable ipairs next pairs pcall rawequal rawget rawlen rawset
select setmetatable tonumber tostring type unpack xpcall

string. The methods work on string values too, as in ("text"):upper().

string.byte string.char string.find string.format string.gmatch string.gsub
string.len string.lower string.match string.rep string.reverse string.sub string.upper

table.

table.concat table.insert table.move table.pack table.remove table.sort table.unpack

math. The standard names, 27 of them. The extras above are in addition.

math.abs math.acos math.asin math.atan math.ceil math.cos math.deg math.exp
math.floor math.fmod math.huge math.log math.max math.maxinteger math.min
math.mininteger math.modf math.pi math.rad math.random math.randomseed math.sin
math.sqrt math.tan math.tointeger math.type math.ult

utf8.

utf8.char utf8.charpattern utf8.codepoint utf8.codes utf8.len utf8.offset

previous: time, cvar, screen, log · next: Examples