Venus Lua API › Core
GameObject
Scene node — hierarchy, transforms, lifecycle.
lua/venus_lua/src/lua_gameobject.rs
GameObject
A node in the 3D scene graph: a transform (position / rotation / scale), a place in the parent
→ child hierarchy, and a lifecycle (active / inactive / destroyed). Components — renderers,
colliders, lights, controllers, scripts — attach to a GameObject and read its transform.
Static calls use the type table (GameObject.Create()); instance methods use colon syntax on a
handle (gameObject:SetLocalPosition(...)).
Types
GameObject — an opaque handle (userdata) to a scene node. A handle may be null or stale
(its object destroyed); it is safe to keep and pass around. Calling a method on a null/stale handle
never raises — it degrades to a documented default. Most getters and every setter warn
(returning nil or a no-op); the hierarchy-navigation getters instead degrade silently to an
empty value (see Functions). tostring(gameObject) yields GameObject{name}, or
GameObject{NULL} if dead or unnamed.
Creation & Destruction
GameObject.Create( ) : GameObject
Creates a new, active GameObject at the origin. Returns nil and logs an error if the scene
object pool is exhausted.
GameObject.CreateInactive( ) : GameObject
Same as Create, but the object starts disabled (its components do not run until activated).
GameObject.Instantiate( GameObject source ) : GameObject
Recursively clones source and its children. Returns nil and logs a warning if source is
null.
GameObject.Get( string name ) : GameObject
Finds a GameObject by its unique name. Returns nil if no match exists (no warning — a miss is a valid result).
GameObject.Exists( GameObject object ) : boolean
Returns true if the handle refers to a live object. Safe on null/stale handles (returns
false) — this is the one call that never warns.
gameObject:Destroy( ) : void
Destroys the object (and its children) if it exists; logs a warning otherwise. The object stops
existing immediately — Exists() is false the moment this returns, and neither it nor its
children receive any further callbacks. Called from outside a callback the teardown is
synchronous; called from inside one (e.g. destroying self from Update) the teardown proper —
its components’ OnDestroy, and slot reclaim — is deferred to the end of the update cycle, so the
calling component’s own data stays valid until its callback returns. Either way, calling it on self
is safe.
Zone ownership & lifetime. A GameObject you create from Lua —
Create,CreateInactive, or a
parentlessInstantiate— is recorded as a spawned root of the zone that is loading when the
call runs. When that zone unloads, the engine destroys its spawned roots, so a Lua-created object
lives only as long as its owning zone. There is noDontDestroyOnLoadbinding. The unload
sweep destroys only handles that are still roots, so to keep an object across an unload,
SetParentit under longer-lived content (e.g. a persistent object from an earlier/session zone)
before that zone unloads — reparenting lifts it out of this zone’s sweep. Two traps: reparenting
under another object in the same zone does not save it (the whole subtree is destroyed
together), andMakeRoot()does not help — a root stays on the destroy list.
Functions
Read-only queries. Their null/stale-handle behavior falls in three groups:
- Transform & identity (
ID,Active,ActiveInHierarchy,Layer,Forward/Right/Up,
the position/rotation/scale/Euler families,TransformPointand theInverseTransform*helpers):
warn and returnnil. - Hierarchy navigation (
Parent,FindChild,FindChildRecursive,GetChild,FirstChild,
NextSibling,PreviousSibling,Children): degrade silently —nil, or an empty table for
Children, with no warning — because on a live object that same empty answer is legitimate, so a
warning would fire on correct code. - Hierarchy predicates that can tell stale from empty (
Root,ChildCount,IsChildOf,
IsRoot): warn, returning a typed sentinel —Root→nil,ChildCount→0, the two
predicates →false.
gameObject:Active( ) : boolean
The object’s own enabled flag, ignoring ancestors.
gameObject:ActiveInHierarchy( ) : boolean
true only if this object and every ancestor are active.
gameObject:Parent( ) : GameObject
The parent, or nil if the object is a scene root (a root is not an error — no warning).
gameObject:Root( ) : GameObject
The topmost ancestor (itself if already a root).
gameObject:Children( ) : table
An array (1-based) of the direct children.
gameObject:ChildCount( ) : integer
Number of direct children.
gameObject:GetChild( integer index ) : GameObject
The child at index (1-based); nil if out of range.
gameObject:FindChild( string name ) : GameObject
The direct child named name; nil if none. Direct children only — use FindChildRecursive to search the whole subtree.
gameObject:FindChildRecursive( string name ) : GameObject
Depth-first (pre-order) search of all descendants for the first one named name; nil if none. Does not consider the object itself.
gameObject:IsChildOf( GameObject parent ) : boolean
true if parent is this object’s ancestor.
gameObject:IsRoot( ) : boolean
true if the object has no parent.
gameObject:FirstChild( ) : GameObject
First direct child, or nil.
gameObject:NextSibling( ) : GameObject
Next sibling under the shared parent, or nil.
gameObject:PreviousSibling( ) : GameObject
Previous sibling, or nil.
gameObject:Forward( ) : Vector3
World-space forward axis (-Z rotated by world rotation).
gameObject:Right( ) : Vector3
World-space right axis.
gameObject:Up( ) : Vector3
World-space up axis.
gameObject:TransformPoint( Vector3 point ) : Vector3
Transforms point from local to world space (scale, rotation, translation). Accepts a Vector3
or three numbers.
gameObject:TransformVector( Vector3 vector ) : Vector3
Local → world using scale and rotation (no translation).
gameObject:TransformDirection( Vector3 direction ) : Vector3
Local → world using rotation only.
gameObject:InverseTransformPoint( Vector3 point ) : Vector3
World → local (scale, rotation, translation).
gameObject:InverseTransformVector( Vector3 vector ) : Vector3
World → local using scale and rotation.
gameObject:InverseTransformDirection( Vector3 direction ) : Vector3
World → local using rotation only.
Properties (get / set)
Setters return void and no-op with a warning on a null/stale handle.
ID
gameObject:ID( ) : string — the object’s unique name. A freshly Create()d object has no
name until SetID: until then ID() logs a warning (NotFound) and returns nil (and
tostring yields GameObject{NULL}).
gameObject:SetID( string name ) : void — sets the object’s unique name. The name must be
unique — if another live object already holds name, the rename is a silent no-op (the
object keeps its old name) and a warning is logged (reported as NotFound, though it is really a
name collision). An empty name is accepted and leaves the object nameless.
LocalPosition
gameObject:LocalPosition( ) : Vector3 — position relative to the parent.
gameObject:SetLocalPosition( Vector3 position ) : void — accepts a Vector3 or three
numbers; three numbers preserve f64 precision through the floating-origin split.
LocalRotation
gameObject:LocalRotation( ) : Quaternion — rotation relative to the parent.
gameObject:SetLocalRotation( Quaternion rotation ) : void
LocalScale
gameObject:LocalScale( ) : number — uniform local scale.
gameObject:SetLocalScale( number scale ) : void
LocalEulerAngles
gameObject:LocalEulerAngles( ) : Vector3 — local rotation as YXZ Euler angles, in
degrees.
gameObject:SetLocalEulerAngles( Vector3 degrees ) : void
WorldPosition
gameObject:WorldPosition( ) : number, number, number — the precise world position as three
f64 numbers x, y, z (not a Vector3, which would be f32-lossy at range):
local x, y, z = go:WorldPosition().
gameObject:SetWorldPosition( Vector3 position ) : void — accepts a Vector3 or three f64
numbers.
WorldRotation
gameObject:WorldRotation( ) : Quaternion
gameObject:SetWorldRotation( Quaternion rotation ) : void
WorldScale
gameObject:WorldScale( ) : number — accumulated world scale.
gameObject:SetWorldScale( number scale ) : void
EulerAngles
gameObject:EulerAngles( ) : Vector3 — world rotation as YXZ Euler angles, in degrees.
gameObject:SetEulerAngles( Vector3 degrees ) : void
Layer
gameObject:Layer( ) : integer — the render/collision layer mask: a 32-bit bitmask (fresh
objects default to 0xFFFFFFFF = all layers), not an index. A renderable is visible to a camera
only when objectMask & cameraMask ≠ 0.
gameObject:SetLayer( integer mask ) : void — sets the 32-bit layer mask.
Euler angle order variants
For each of the six rotation orders there are four accessors: world/local getter (returns a
Vector3 of degrees) and world/local setter (takes a Vector3 or three numbers of degrees).
EulerAngles / SetEulerAngles above are the default (YXZ) forms.
| Order | Get world | Get local | Set world | Set local |
|---|---|---|---|---|
| XYZ | EulerAnglesXYZ() |
LocalEulerAnglesXYZ() |
SetEulerAnglesXYZ(v) |
SetLocalEulerAnglesXYZ(v) |
| XZY | EulerAnglesXZY() |
LocalEulerAnglesXZY() |
SetEulerAnglesXZY(v) |
SetLocalEulerAnglesXZY(v) |
| YXZ | EulerAnglesYXZ() |
LocalEulerAnglesYXZ() |
SetEulerAnglesYXZ(v) |
SetLocalEulerAnglesYXZ(v) |
| YZX | EulerAnglesYZX() |
LocalEulerAnglesYZX() |
SetEulerAnglesYZX(v) |
SetLocalEulerAnglesYZX(v) |
| ZXY | EulerAnglesZXY() |
LocalEulerAnglesZXY() |
SetEulerAnglesZXY(v) |
SetLocalEulerAnglesZXY(v) |
| ZYX | EulerAnglesZYX() |
LocalEulerAnglesZYX() |
SetEulerAnglesZYX(v) |
SetLocalEulerAnglesZYX(v) |
Methods
Actions that mutate the object. All no-op with a warning on a null/stale handle.
gameObject:Activate( ) : void
Enables the object and recursively updates children.
gameObject:Deactivate( ) : void
Disables the object and recursively updates children.
gameObject:SetParent( GameObject parent ) : void
Reparents the object, keeping it in the scene. parent may be a GameObject handle or a
string name. No-op with a warning if either object is invalid or the reparent would form a cycle.
Keeps the LOCAL transform — the object moves in world space. Local position, rotation, and
scale are preserved verbatim; because they are now measured against the new parent, the
object’s world pose shifts. This is the opposite of Unity, whoseSetParent(parent)
defaults toworldPositionStays = true(world pose kept, local recomputed). There is no
world-preserving overload. To hold the world pose across a reparent, capture it first and
restore it after:local x, y, z = go:WorldPosition() local rot = go:WorldRotation() go:SetParent(newParent) go:SetWorldPosition(x, y, z) go:SetWorldRotation(rot)If the new parent has non-unit scale, also capture
go:WorldScale()beforehand and restore it
withgo:SetWorldScale(s).
gameObject:MakeRoot( ) : void
Detaches from the current parent, making the object a scene root.
gameObject:DetachChildren( ) : void
Unparents every direct child, making each a root.
gameObject:Translate( Vector3 delta ) : void
Adds delta to the object’s local position — movement in parent space (the parent’s local
frame), not along the object’s own facing. Accepts a Vector3 or three numbers.
Parent-space, not self-space.
deltais added to the local position unchanged — it is not
rotated by the object’s own rotation, so this is not Unity’s defaultTranslate(Space.Self,
which moves along the object’s own axes). For a root object (no parent) local space is world
space, soTranslatethere moves along world axes. To move along the object’s own facing at any
depth, drive the world position with the world-space axis vectors instead:local x, y, z = go:WorldPosition() local f = go:Forward() -- world-space unit axis (also Right() / Up()) go:SetWorldPosition(x + f.x * d, y + f.y * d, z + f.z * d)
gameObject:Rotate( Quaternion rotation ) : void
Applies rotation on top of the current rotation.
gameObject:RotateAround( Vector3 point, Vector3 axis, number angle ) : void
Rotates the object angle radians about the world-space axis through point. point and
axis each accept a Vector3 or three numbers. (Note: unlike the SetEulerAngles* setters,
which take degrees, this angle is radians.)
gameObject:SetPositionAndRotation( Vector3 position, Quaternion rotation ) : void
Sets world position and rotation in one call. position accepts a Vector3 or three f64
numbers (three numbers preserve precision).
gameObject:LookAt( Vector3 target ) : void
gameObject:LookAt( Vector3 target, Vector3 up ) : void
Orients the object’s forward axis toward target. The optional up biases roll (defaults to
world up). target / up accept a Vector3 or three numbers.
Example
A ScriptBehavior file returns a table of callbacks; the engine attaches it to a
GameObject and invokes those callbacks, passing the component’s self (whose
self.object is this GameObject). The local Script = {} / return Script
scaffolding is required — a bare function Script.Update(...) is not a runnable file.
-- Orbit a child marker around its parent and keep it facing the parent's origin.
-- (Adapted from data/scripts/camera_orbit.lua.)
local Script = {}
function Script.Update(self)
local go = self.object
local t = Time.Time()
local r = 5.0
-- Position relative to the parent, on a circle in the XZ plane.
go:SetLocalPosition(math.cos(t) * r, 1.5, math.sin(t) * r)
-- Face the parent's world origin (three f64 numbers, precise at range).
local px, py, pz = go:Parent():WorldPosition()
go:LookAt(px, py, pz)
end
return Script