The vec3 class is the vector type the API uses for positions, rotations, velocities and axes: three numbers, x, y and z, with the usual methods and operators. ss.vec3 creates a plain vector. The vectors the objects hand out for their fields are live vectors, which share the methods and operators and write through to the game. The axes and units are described under Coordinates and angles.

Static members#

These elements are static to the class itself and can be accessed like so:

local v = ss.vec3(1, 2, 3)

Static functions#

FunctionReturn ValuesDescription
ss.vec3( number x, number y, number z ) vec3 vector Creates a new vector object with the given values for x, y and z.

Instance members#

Instance members must be accessed through a reference to a specific vec3 object.

local ahead = car.position + car.forward * 40
ss.log(ahead:distance(other.position))
car.position = ahead
WARNING: Attempting to call instance members statically will result in an error!

Instance Methods#

What is a method?

FunctionReturn ValuesDescription
unpack() number x, number y, number z Returns the three components as three values.
copy() vec3 vector Returns a plain vec3 with the same values. On a live vector, the copy no longer writes through.
table() table Returns the components as a table, { x =, y =, z = }.
length() number length Returns the length of the vector.
normalized() vec3 vector Returns a unit vector in the same direction.
dot(vec3 other) number dot Returns the dot product with the other vector.
cross(vec3 other) vec3 vector Returns the cross product with the other vector.
distance(vec3 other) number distance Returns the distance to the other vector. A vector with a nil component results in an error here, as a Nemesis car's position does while the car has no body; check x first.

Instance Fields#

TypeFieldRead-only?Description
number x No The x component. On a rotation vector, pitch names the same component.
number y No The y component. On a rotation vector, yaw names the same component.
number z No The z component. On a rotation vector, roll names the same component.

Operators#

TypeFieldDescription
vec3 a + b The component-wise sum.
vec3 a - b The component-wise difference.
vec3 -a The negation.
vec3 a * n The vector scaled by a number.
vec3 a / n The vector divided by a number.
boolean a == b Component-wise equality.
string tostring(a) The three components as text, for print and ss.log.

Operators return plain copies, never live vectors. This is what makes car.position + car.forward * 40 a point and car.position = that a move.

Live vectors#

A live vector is what a vehicle, a prop or an actor hands out for position, rotation, velocity, angular_velocity, forward, up and right. Reading a component reads the game. Setting a component of a writable field (car.position.y = 5) reads the whole vector, replaces that component and writes it back; setting a component of a read-only field results in an error. copy() returns a plain vector that does not change, which matters when the object moves while a loop runs over the value.

Vector-like values#

Anything vector-like is accepted where a vector is expected, in an assignment or as an argument: three numbers, a vec3 or a live vector, { x =, y =, z = }, { pitch =, yaw =, roll = } for a rotation, or { 1, 2, 3 }.

Example#

local car = ss.vehicle
car.position = { x = 10, y = 0.5, z = -40 }
car.rotation = { pitch = 0, yaw = 90, roll = 0 }
car.velocity = { 0, 0, 30 }
car:impulse(ss.vec3(0, car.mass * 5, 0))

local ahead = car.position + car.forward * 40        -- a point 40 m ahead of the car
ss.log(ahead:distance(ss.vehicles[1].position), car.forward:dot(car.velocity:normalized()))