Primitives
Math types every other API is built on: Vector,
Color3, CFrame, and Dim. All
immutable, arithmetic returns new instances, never mutates in
place.
local Primitives = import("Primitives")
local Vector = Primitives.Vector
local Color3 = Primitives.Color3
local CFrame = Primitives.CFrame
local Dim = Primitives.Dim
Copy struct, so passing them
around is cheap.
Vector
Three-component vector used for positions, directions, sizes, velocities, anywhere a 3D quantity makes sense. Coordinate convention is right-handed: +X right, +Y up, +Z toward the camera.
Vector also accepts a
Luau native vector
(the built-in primitive returned by vector(x, y, z)),
so these are interchangeable:
part.Size = Vector.new(1, 2, 3)
part.Size = vector(1, 2, 3)
part:LookAt(vector(0, 5, 0))
Pass whichever feels natural. Use Vector when you want
the named methods (:Lerp, :Cross, etc.) or
component getters (.X, .Magnitude); reach
for native vector when you're hot-path reading
components in a tight loop, since native vector reads happen
entirely inside the VM (~5-10× faster than crossing the FFI
boundary every time).
Constructors
Construct a new vector. Each argument is optional; omitted
axes default to 0.
Vector.new(1, 2, 3)
Vector.new(5) -- (5, 0, 0)
Vector.new() -- (0, 0, 0)
Shorthand for Vector.new(0, 0, 0).
Shorthand for Vector.new(1, 1, 1).
Convert a Luau
native vector
(the built-in primitive returned by vector(x, y, z)
and the vector.* library) into a Ruzit
Vector userdata. Useful when you've got a
native vector from a math helper or external module and
need it in the form Ruzit's APIs (BasePart.Size,
CFrame.new, etc.) accept.
Vector.FromNative(vector(1, 2, 3))
-- -> Vector(1, 2, 3)
Properties
Right-axis component.
Up-axis component.
Forward-axis component (toward the camera in the engine's right-handed convention).
Cached Euclidean length, sqrt(X² + Y² + Z²).
Computed once at construction; reads are free.
Methods & operators
Linear interpolation. t = 0 returns
self, t = 1 returns other.
Values outside [0, 1] extrapolate.
Dot product. Positive when the vectors face roughly the same direction, negative when opposite, zero when perpendicular.
Right-handed cross product, perpendicular to both inputs.
Returns a unit-length copy. If the magnitude is effectively zero the original is returned (rather than NaN-ing).
Euclidean distance between two points. Equivalent to
(v - other).Magnitude.
Convert to a Luau
native vector.
Use this in hot paths where you're reading components
repeatedly — native vector reads happen inside the VM
without crossing into Rust, which is roughly 5-10× faster
than reading v.X / v.Y /
v.Z on a userdata per access.
local nat = part.Size:ToNative()
-- nat.x, nat.y, nat.z are pure Lua reads from here on,
-- and you can pass `nat` back into any API that takes a Vector.
Component-wise addition.
Component-wise subtraction.
Scalar multiply. The scalar must be a number.
Scalar divide.
Negation. Equivalent to v * -1.
Component-wise comparisons (true only when ALL
THREE axes match). Note < is partial-order,
not magnitude-based — for length comparisons read
.Magnitude directly.
Example
local from = Vector.new(0, 0, 0)
local to = Vector.new(10, 5, 0)
-- Halfway point.
local mid = from:Lerp(to, 0.5)
-- Direction + distance.
local delta = to - from
local distance = delta.Magnitude
local dir = delta / distance -- normalised
Color3
RGB color, channels normalised to 0 .. 1. Three constructors
cover the common input formats: linear floats, 8-bit integers, and CSS
hex literals.
Constructors
Linear 0 .. 1 channels. Out-of-range values are
clamped.
Color3.new(0.18, 0.55, 0.28) -- forest green
8-bit (0 .. 255) channels. Convenient for colors
copied from a paint program. Internally divides by 255.
Color3.fromRGB is an alias.
Color3.FromRGB(46, 140, 71)
CSS-style hex literal. Accepts "#RRGGBB",
"RRGGBB", "#RGB" (each digit
doubled), or "RGB". Throws on bad lengths or
non-hex characters. Color3.fromHex is an alias.
Color3.FromHex("#2e8c47")
Color3.FromHex("ff0") -- expands to "ffff00"
Properties
Red channel, 0 .. 1.
Green channel, 0 .. 1.
Blue channel, 0 .. 1.
Methods & operators
Component-wise interpolation. Useful for fades and day/night cycles.
Channel-wise add. Result is clamped to 0 .. 1.
Channel-wise subtract. Clamped at 0.
Component-wise comparisons (true only when ALL
THREE channels match the relation).
Example
local day = Color3.FromHex("#fdf6e3")
local night = Color3.new(0.05, 0.07, 0.13)
local Process = import("Process")
Process.Heartbeat:Connect(function(_dt)
local t = (os.clock() % 60) / 60
local sky = day:Lerp(night, t)
import("Renderable").SetAmbient(sky)
end)
CFrame
A "Coordinate Frame", the engine's standard transform: a 3D position plus an orientation. Anything that lives in the world (parts, cameras, controllers, attachments) carries a CFrame.
Orientation is stored as Euler angles in radians, applied
X -> Y -> Z. For controlled rotations
CFrame.Angles(rx, ry, rz) is the canonical builder.
Constructors
Construct from a position Vector and (optional) rotation Vector. Both arguments are optional; either defaults to zero.
CFrame.new(Vector.new(0, 5, 0))
CFrame.new(Vector.new(), Vector.new(0, math.pi, 0))
Rotation-only CFrame from three Euler angles in radians.
Equivalent to CFrame.new(Vector.new(),
Vector.new(rx, ry, rz)) but reads more clearly at the
call site.
CFrame.Angles(0, math.pi / 4, 0) -- 45° yaw
Build a CFrame at eye oriented so its forward
axis points at target. up defaults
to Vector.new(0, 1, 0). The returned rotation
is in Euler form, ready to drop into a part's
CFrame or a camera.
-- Camera looks from (5, 5, 10) at the origin.
camera.CFrame = CFrame.LookAt(
Vector.new(5, 5, 10),
Vector.new(0, 0, 0)
)
Properties
World-space position.
Euler-angle orientation, radians. X is pitch,
Y is yaw, Z is roll.
Methods & operators
Position lerps linearly; rotation lerps component-wise. Adequate for short-arc animations, use spherical interpolation if you need a full half-turn between keyframes.
Compose poses. parent * child gives the child's
world transform when the child is described in the parent's
local space.
Transforms a point from the CFrame's local space into world space.
Component-wise add / subtract. Position and rotation each blend independently.
true if every component (3 position + 3
rotation) is within epsilon of the matching
component on other. Default
epsilon is 1e-5. Prefer this
over == for "is the part roughly at this
pose?" checks — direct equality on floats is brittle.
Caveat: rotation is compared as raw Euler
radians, not angular distance, so two visually identical
rotations differing by a multiple of 2π will not
FuzzyEq. Wrap your bounds yourself if that
matters.
-- Snap an animated part once it's settled near the target pose.
if part.CFrame:FuzzyEq(targetCF, 0.01) then
part.CFrame = targetCF
stop_animating()
end
Example
local Renderable = import("Renderable")
local Vector = import("Primitives").Vector
local CFrame = import("Primitives").CFrame
local part = Renderable.BasePart("Cube")
part.Size = Vector.new(1, 1, 1)
part.CFrame = CFrame.new(Vector.new(0, 2, -5))
* CFrame.Angles(0, math.pi / 4, 0)
Dim
Two-dimensional position / size, used everywhere screen-space matters: GUI element positions, mouse cursor coords, viewport sizes.
Convention follows pixel coordinates: +X is right,
+Y is down (origin at the top-left of the
window, opposite to math-class Y).
Constructors
Construct a 2D component.
Dim.new(800, 600)
Properties
Horizontal component.
Vertical component (down-positive).
Methods & operators
Linear interpolation, same shape as Vector.
Rescale this Dim from one reference size to another. Designed
for prebuilt UI: lay your panels out against a fixed reference
(say Dim.new(400, 400)) at design time, then at
runtime call :Scale(reference, Window.GetSize())
to map them onto the actual window.
reference— the design-time size the dim was authored against.target— the runtime size to map into (e.g.Window.GetSize()).maintainRatio— whentrue, both axes use the smaller of the two scale factors so the aspect ratio is preserved (good for letter-boxed UI). Defaultfalse.
Component-wise add / subtract.
Scalar multiply / divide / negate.
Component-wise comparisons (true only when BOTH
axes match the relation).
Example
local GUI = import("GUI")
local Dim = import("Primitives").Dim
local hp = GUI.Basic.Square()
hp.Size = Dim.new(200, 12)
hp.Position = Dim.new(24, 24)
-- Centre on the window.
local Window = import("Window")
local centre = Window:GetSize() / 2
hp.Position = centre - hp.Size / 2
UDim
Scale-based 2D component, the partner type to Dim.
Each axis is a fraction (typically 0..1) of a parent dimension.
Use it whenever you want a position or size to track its container
(centered button = UDim.new(0.5, 0.5)) instead of
living at fixed pixel coordinates.
Constructors
Both arguments default to 0.
Shorthand for UDim.new(0, 0).
Shorthand for UDim.new(1, 1) — full size of the parent.
One-shot scale-to-pixels. Equivalent to
UDim.new(scaleX, scaleY):ToDim(parent) but reads
more naturally when the scale values are constants. Use it
for sizing a button or tile to a fraction of a container
without first constructing a UDim value.
-- 20% × 20% of the parent.
btn.Size = UDim.FromDim(0.2, 0.2, parentSize)
Methods & operators
Resolve to absolute pixels by multiplying each axis by the
corresponding component of parent.
UDim.new(0.5, 0.25):ToDim(Dim.new(800, 600))
-- -> Dim(400, 150)
Component-wise addition / subtraction (combine offsets).
Scalar arithmetic and negation.
Component-wise comparisons (true only when BOTH axes match).
local UDim = Primitives.UDim
local Dim = Primitives.Dim
-- A button anchored to the right edge, 20% wide.
local winSize = Dim.new(win:Width(), win:Height())
local btnScale = UDim.new(0.2, 0.08)
btn.Size = btnScale:ToDim(winSize)