> xmath-usage
Provides xmath API reference and in-place math optimization patterns for Defold. Use when writing performance-critical math code, optimizing vector/quaternion/matrix operations, or when the user mentions xmath, zero-allocation math, or reducing Lua GC pressure.
curl "https://skillshub.wtf/indiesoftby/defold-agent-config/xmath-usage?format=md"Using xmath for Zero-Allocation Math in Defold
Prerequisite: Verify xmath Dependency
Before applying any guidance from this skill, you MUST confirm that the project uses xmath. Check the game.project file for a dependency URL containing thejustinwalsh/defold-xmath (e.g. dependencies#N = https://github.com/thejustinwalsh/defold-xmath/archive/...). Alternatively, check for the presence of xmath/ in the .deps/ directory.
If neither an xmath dependency in game.project nor a local xmath module is found, do NOT apply this skill. Inform the user that the project does not use xmath and suggest adding the dependency:
[project]
dependencies#N = https://github.com/thejustinwalsh/defold-xmath/archive/refs/heads/main.zip
Core Concept: In-Place Mutation to Eliminate Heap Allocations
Standard vmath creates a new Lua object on every operation, causing constant GC pressure in hot loops:
-- BAD: vmath allocates 3 new objects every frame
function update(self, dt)
local v = self.dir * 5 * dt -- alloc #1
local pos = go.get_position() -- alloc #2
local result = pos + v -- alloc #3
go.set_position(result)
end
xmath mutates an existing variable in place — the result is written into the first argument. You allocate once, reuse forever:
-- GOOD: xmath reuses pre-allocated variables, zero allocations per frame
go.property("dir", vmath.vector3(0, 1, 0))
local v = vmath.vector3() -- allocate ONCE at module scope
function update(self, dt)
local pos = go.get_position()
xmath.mul(v, self.dir, 5 * dt) -- writes into v
xmath.add(v, pos, v) -- writes into v
go.set_position(v)
end
Key Rules
- Pre-allocate scratch variables at module scope or in
init()— never insideupdate()oron_message(). - The output variable is always the first argument — this is the fundamental calling convention difference from
vmath. - Functions return nothing — you cannot chain calls. Use a scratch variable at each step.
- Use
vmathto create initial objects —vmath.vector3(),vmath.vector4(),vmath.quat(),vmath.matrix4()to allocate scratch buffers, then usexmathto operate on them. - Type polymorphism — functions like
xmath.lerpwork forvector3,vector4, andquaternionbased on the output argument type.
Optimization Pattern
-- Scratch variables — allocated once
local temp_v = vmath.vector3()
local temp_q = vmath.quat()
function update(self, dt)
-- Instead of: local dir = vmath.normalize(target - pos)
xmath.sub(temp_v, self.target, self.pos)
xmath.normalize(temp_v, temp_v) -- can use same variable as both input and output
-- Instead of: local rot = vmath.quat_rotation_z(angle)
xmath.quat_rotation_z(temp_q, self.angle)
-- Instead of: local rotated = vmath.rotate(rot, dir)
xmath.rotate(temp_v, temp_q, temp_v)
end
Full API Reference
All functions write the result into the first argument. No return values.
Vector Operations (vector3 / vector4)
| Function | Equivalent | Description |
|---|---|---|
xmath.add(out, v1, v2) | out = v1 + v2 | Add two vectors |
xmath.sub(out, v1, v2) | out = v1 - v2 | Subtract two vectors |
xmath.mul(out, v, n) | out = v * n | Multiply vector by scalar |
xmath.div(out, v, n) | out = v / n | Divide vector by scalar |
xmath.cross(out, v1, v2) | out = cross(v1, v2) | Cross product (vector3 only) |
xmath.mul_per_elem(out, v1, v2) | out.x = v1.x * v2.x, ... | Element-wise multiplication |
xmath.normalize(out, v) | out = normalize(v) | Normalize vector |
xmath.rotate(out, q, v) | out = rotate(q, v) | Rotate vector3 by quaternion |
xmath.vector(out) | out = (0,0,0) | Reset to zero vector |
Interpolation (vector3 / vector4 / quaternion)
| Function | Equivalent | Description |
|---|---|---|
xmath.lerp(out, t, v1, v2) | out = lerp(t, v1, v2) | Linear interpolation |
xmath.slerp(out, t, v1, v2) | out = slerp(t, v1, v2) | Spherical interpolation |
Quaternion Operations
| Function | Description |
|---|---|
xmath.quat(out) | Reset to identity (0, 0, 0, 1) |
xmath.conj(out, q) | Conjugate of quaternion |
xmath.quat_axis_angle(out, axis, angle) | Quaternion from axis + angle |
xmath.quat_basis(out, x, y, z) | Quaternion from 3 basis vectors (vector3) |
xmath.quat_from_to(out, v1, v2) | Rotation quaternion from v1 to v2 |
xmath.quat_rotation_x(out, angle) | Rotation around X axis |
xmath.quat_rotation_y(out, angle) | Rotation around Y axis |
xmath.quat_rotation_z(out, angle) | Rotation around Z axis |
Matrix Operations (matrix4)
| Function | Description |
|---|---|
xmath.matrix(out [, m1]) | Reset to identity or copy from m1 |
xmath.matrix_axis_angle(out, axis, angle) | Rotation matrix from axis + angle |
xmath.matrix_from_quat(out, q) | Matrix from quaternion |
xmath.matrix_frustum(out, left, right, bottom, top, near, far) | Frustum projection matrix |
xmath.matrix_inv(out, m) | Matrix inverse |
xmath.matrix_look_at(out, eye, look_at, up) | View matrix |
xmath.matrix4_orthographic(out, left, right, bottom, top, near, far) | Orthographic projection |
xmath.matrix_ortho_inv(out, m) | Orthographic inverse |
xmath.matrix4_perspective(out, fov, aspect, near, far) | Perspective projection |
xmath.matrix_rotation_x(out, angle) | Rotation around X axis |
xmath.matrix_rotation_y(out, angle) | Rotation around Y axis |
xmath.matrix_rotation_z(out, angle) | Rotation around Z axis |
xmath.matrix_translation(out, position) | Translation matrix from vector3/vector4 |
> related_skills --same-repo
> monarch-screen-setup
Organizes screens and popups in a Defold game using Monarch screen manager. Use when creating new screens, popups, or setting up navigation between them.
> defold-skill-maintain
Maintains Defold agent skills. Use when asked to update link lists in api-fetch/docs-fetch/examples-fetch skills, create or update proto file references, or fetch proto schemas.
> defold-shaders-editing
Creates and edits Defold shader files (.vp, .fp, .glsl). Use when asked to create, modify, or configure any Defold vertex shader, fragment shader, or GLSL include file.
> defold-scripts-editing
Creates and edits Defold Lua script files (.script, .gui_script, .render_script, .editor_script) and plain Lua modules (.lua). Use when asked to create, modify, or configure any Defold script or Lua module.