Text

Text extends Object, adding functions and properties to it.

A Text is an object with a text and optional background frame attached.

It may be used in two different display modes by setting its Text.Type field,
- as a TextType.World, it will behave exactly like any other object in the scene, great for creating postsigns;
- as a TextType.Screen, it will be displayed from its position in the scene always facing the camera, like an UI element - great for text bubbles.

By default, a Text is set to TextType.World.

If you were using the deprecated Object:TextBubble and Object:ClearTextBubble functions prior to 0.0.48, you may use the "textbubble.lua" module. It contains the following functions which use Text objects instead,
- import the module with tb = require("textbubble.lua")
- tb.set(object, text, duration, offset, color, backgroundColor, tail)
- tb.clear(object)

Constructors

Text ( )

Creates a Text with default properties.

local t = Text()

-- change text properties
t.Text = "Hello world!"
t.Type = TextType.Screen
t.IsUnlit = true
t.Tail = true

-- use it as a normal object in the scene
t:SetParent(Player)
t.LocalPosition = { 0, 34, 0 }

Functions

Number2integer CharIndexToCursor ( integer charIndex, boolean points optional )

Converts a given character index in Text's text string, into a 2-dimensional cursor position Number2. Additionally returns the following character index in Text's text string.

Use the optional parameter points if you are working with points scaling. For example if the text type is TextType.Screen, or if you are scaling your scene using Screen.Width and Screen.Height points values.

number GetCharacterSize ( Font font, string character, boolean points optional )

Returns the size of a character for a given font (see Text.Font). Note that this is a function of the global Text object.

Use the optional parameter points if you are working with points scaling. For example if the text type is TextType.Screen, or if you are scaling your scene using Screen.Width and Screen.Height points values.

Number2integer LocalToCursor ( Number3 localPos, boolean points optional )

Snaps a given position in Text's local space to the nearest character gap, and returns it as a 2-dimensional cursor position Number2. Additionally returns the following character index in Text's text string.

Use the optional parameter points if you are working with points scaling. For example if the text type is TextType.Screen, or if you are scaling your scene using Screen.Width and Screen.Height points values.

Inherited from Object

Hide

nil Load ( string itemName, function callback, table config optional )

Loads the given item asynchronously and calls the callback once done. The parameter itemName follows the usual naming convention user.item.

This is a function of the global Text, to be called as Object:Load(itemName, callback, config).

The config table options are as follows,
- mutable allows to create the item shapes as MutableShape instead of Shape. Default false.
- bakedLight allows to generate baked lighting for the item shapes. Default false.

nil AddChild ( Object child, boolean keepWorld optional )

Adds given Object as a child. Object extensions like Shape or MutableShape are naturally accepted too.

The keepWorld optional parameter, false by default, dictates whether to maintain the child's world or local position and rotation. Keeping world will ensure the object doesn't move in the scene, adjusting its local position/rotation accordingly; keeping local will have the object move in the scene in order to maintain an equivalent local position/rotation relative to its new parent.

It's a good practice to set child/parent relationships before setting positions, if you do not want to use the keepWorld parameter.

Note that there is a cyclic hierarchy protection that will prevent you from creating parenting loops.

local o = Object()
local myShape = Shape(Items.someuser.someitem)
o:AddChild(myShape)
nil RemoveChild ( Object child, boolean keepWorld optional )

Unsets parent/child relationship with child parameter. The child ends up being deleted if it has no other references.

The keepWorld optional parameter, false by default, dictates whether to maintain the child's world or local position and rotation. Keeping world will ensure the object doesn't move in the scene, adjusting its local position/rotation accordingly; keeping local will have the object move in the scene in order to maintain an equivalent local position/rotation relative to its new parent.

o:RemoveChild(someChildObject)
nil RemoveChildren ( boolean keepWorld optional )

Unsets parent/child relationship with all children. Individual children end up being deleted if they have no other references.

The keepWorld optional parameter, false by default, dictates whether to maintain the child's world or local position and rotation. Keeping world will ensure the object doesn't move in the scene, adjusting its local position/rotation accordingly; keeping local will have the object move in the scene in order to maintain an equivalent local position/rotation relative to its new parent.

o:RemoveChildren()
nil Recurse ( function callback, table config optional )

Iterates over all descendants of Text and calls the callback function for each.

The callback function is called with the descendant as the only argument.

The config table accepts two boolean options:
- deepFirst: if true, traverses depth-first instead of root-first. Default false.
- includeRoot: if true, includes Text in the recursion. Default true.

o:Recurse(function(descendant)
  print(descendant)
end, { includeRoot = true })
Object FindFirst ( function searchFunction, table config optional )

Returns the first descendant Object for which the search function returns true.
If no descendant is found, returns nil.

The search function is called with the descendant as the only argument.

The config table accepts two boolean options:
- deepFirst: if true, traverses depth-first instead of root-first. Default false.
- includeRoot: if true, includes Text in the recursion. Default false.

local leaf = oakTree:FindFirst(function(o) return o.Name == "leaf" end)
if leaf then
  print("found a leaf:", leaf)
end
table Find ( function searchFunction, table config optional )

Returns all descendants Objects for which the search function returns true.
If no descendant is found, returns an empty table.

The search function is called with the descendant as the only argument.

The config table accepts two boolean options:
- deepFirst: if true, traverses depth-first instead of root-first. Default false.
- includeRoot: if true, includes Text in the recursion. Default false.

local leaves = oakTree:Find(function(o) return o.Name == "leaf" end)
for i, leaf in leaves do
  print("leaf #" .. i .. ":", leaf)
end

The most efficient way to dispose of an Object for good.

Calling Destroy removes the Object and all its descendants from the World.
Metadata associated with all of these Objects also gets removed.

Once destroyed, the Objects can't be used anymore.

o:Destroy()

Get child Object at index.

if o.ChildrenCount > 0 then
  print(o:GetChild(1)) -- prints first child
end

Get Text's parent.

print(myObject:GetParent())
nil SetParent ( Object parent, boolean keepWorld optional )

Sets parent/child relationship with parent parameter. nil can be used to remove the Object from its parent.

The keepWorld optional parameter, false by default, dictates whether to maintain the child's world or local position and rotation. Keeping world will ensure the object doesn't move in the scene, adjusting its local position/rotation accordingly; keeping local will have the object move in the scene in order to maintain an equivalent local position/rotation relative to its new parent.

It's a good practice to set child/parent relationships before setting positions, if you do not want to use the keepWorld parameter.

Note that there is a cyclic hierarchy protection that will prevent you from creating parenting loops.

local o = Object()
o:SetParent(Map) -- o is now a child of the map
-- (Map is an extension of Object)
nil RemoveFromParent ( boolean keepWorld optional )

Removes the Text from its parent. Doesn't do anything if the Text has no parent.

The keepWorld optional parameter, false by default, dictates whether to maintain the child's world or local position and rotation. Keeping world will ensure the object doesn't move in the scene, adjusting its local position/rotation accordingly; keeping local will have the object move in the scene in order to maintain an equivalent local position/rotation relative to its new parent.

o:RemoveFromParent()

Converts a local position to world coordinate system.

local p = Number3(1, 2, 3)
local pInWorldCoords = myObject:PositionLocalToWorld(p)

Converts a world position to local coordinate system.

local p = Number3(1, 2, 3)
local pInLocalCoords = myObject:PositionWorldToLocal(p)

Rotates the Text in its own coordinates system.

o = Object()
-- rotate with provided Euler angle
o:RotateLocal({0, 0, math.pi / 2.0})

-- rotate along specified axis
o:RotateLocal(o.Forward, math.pi / 2.0)

Rotate the Text in the World coordinates system.

o = Object()
-- rotate with provided Euler angles
o:RotateWorld({0, 0, math.pi / 2.0})

-- rotate along specified axis
o:RotateWorld(o.Forward, math.pi / 2.0)
-- same as o:RotateLocal({0, 0, 1}, math.pi / 2.0)

Converts a rotation from local to world relative to this object.

Converts a rotation from world to local relative to this object.

Returns true if the two Objects may collide with each other.

nil ApplyForce ( Object self, Number3 value )

Apply a force to Object, taking into account its Mass.

Resets to Text's original collision box. For example, Player and Shape objects will revert to fitting their model bounding box.

nil Recurse ( function callback, table config optional )

Iterates over all descendants of Text and calls the callback function for each.

The callback function is called with the descendant as the only argument.

The config table options are as follows,
- includeRoot whether to include Text in the iteration. Default true.
- depth the maximum depth of the iteration. Default -1 (unlimited).
- deepFirst whether to iterate in depth-first order. Default false.

If you were to remove an object from its parent while recursing through it, the object removal will be delayed until the full recursion is completed.

o:Recurse(function(descendant)
  print(descendant.Name)
end, { includeRoot = true })
nil Copy ( table config optional )

Creates a copy of the object, including all its properties and current state.

To copy a composite object, you may call o:Copy({ recurse = true }). This will copy and replicate the full object hierarchy.

Properties

Anchor of the text, text.Anchor = { 0.5, 0.5 } by default, which corresponds to the middle of the text.

Color of the background frame, disabled by default. Set alpha to zero to disable.

Color of the text, black by default.

Enable and configure draw modes using this property. Setting this to nil disables all draw modes.

Currently, one draw mode is supported: { outline= }

Outline options are,
- weight as a number between 0.0 and 1.0, disabling the outline at 0.0 to the maximum weight allowed by the font at 1.0.
- color as a Color.

All these options can be set at runtime or animated individually.

Check the world Text Format Showcase to experiment with these options.

t.DrawMode = {
  outline = { weight=0.5, color=Color(10, 15, 200) }
}

The font used by Text's text message. It can be one of the following,
- Font.Pixel: a pixel font which generally scales well whatever the size. It is lit by Shape's baked lighting, and can be lit by Light objects if the text's color is opaque. Internally, transparent texts using this font are rendered within an order-independant pass.
- Font.Noto: a vector font which will look smoother, but may not always scale well when displaying extremely big texts. It is lit by Shape's baked lighting, but not by Light objects. Internally, transparent texts using this font are rendered in an alpha-blending pass.
- Font.NotoMono: same characteristics as the Font.Noto font, but with equal spacing between characters (monospace).

Font size in world units, 2.2 by default. Expressed in points if the text type is TextType.Screen.

Built-in font point sizes can be accessed by setting the following strings: "default", "small", or "big". These sizes are internally calculated based on screen density, and can be used to maximize readability accross devices.

Enable and configure text formatting using this property. Setting this to nil resets text format to default.

Supported keys: { alignment=, weight=, slant= },
- alignment can be one of "left" (default), "center", or "right".
- weight as a number between 0.0 and 2.0 (default 1.0). The weight of the font controls how light or heavy it looks. You can also use the preset values "bold", "regular" or "light", which are simply equivalent to a weight of 1.2, 1.0, and 0.9 respectively.
- slant as a number between -1.0 and 1.0 (default 0.0). The slant of the font controls how tilted the text is to the right or left. The preset values "italic" and "regular" can be used, they are equivalent to a slant of 0.2 and 0.0 respectively.

All these options can be set at runtime or animated individually.

Check the world Text Format Showcase to experiment with these options.

-- make a centered bold text
t.Format = { alignment="center", weight="bold" }

-- make a bold italic text
t.Format = { weight="bold", slant="italic" }

-- make a text using some custom weight and slant
t.Format = { weight=1.5, slant=-0.1 }
number Height read-only

Height of the Text with points scaling. Use this value if the text type is TextType.Screen, or if you are scaling your scene using Screen.Width and Screen.Height points values.

This accounts for the total size including background frame, padding, and tail.

Whether or not the Text should be visible from the back, true by default.

Whether or not the Text should ignore scene lighting, false by default.

Integer or table of integers between 1 and 12. Cameras only render objects corresponding to their layers.

Maximum distance in world units beyond which the text will disappear, 350.0 by default.

Maximum width in world units beyond which the text will automatically break line, 0 by default (disabled). Expressed in points if the text type is TextType.Screen.

Text padding over background in world units, 0.8 by default. Expressed in points if the text type is TextType.Screen.

number RawHeight read-only

Height of the Text in world units.

This accounts for the total size including background frame, padding, and tail.

number RawWidth read-only

Width of the Text in world units.

This accounts for the total size including background frame, padding, and tail.

Overrides rendering order for this text amongst other objects within its rendering pass, which is dictated by which features and font are in use. Can be set to an integer value between 0 (default) and 255. A value of 0 means no override.

Objects with overriden sort order are rendered from sort order 1 to sort order 255, ignoring any normal ordering. You may assign the same sort order to multiple objects, in which case they are rendered unordered within that shared sort order.

⚠️ Note that enabling this will disable depth testing. This is an advanced feature, and it is not recommended to use if you aren't absolutely sure of having a need for it.

Whether to display a tail under the background frame, like a text bubble, false by default.

The text to be displayed, set an empty string to hide it.

The text type can be set to TextType.World (default) or TextType.Screen.

As a TextType.World, the text will be translated, rotated, and scaled like any other object in the scene, eg. a signpost.
As a TextType.Screen, the text will be displayed in front of everything else, facing the camera from its position in the scene, eg. a text bubble above a player's head.

Note that it can be changed at any time. Some Text fields are then expressed in world units or points based on the text type.

number Width read-only

Width of the Text with points scaling. Use this value if the text type is TextType.Screen, or if you are scaling your scene using Screen.Width and Screen.Height points values.

This accounts for the total size including background frame, padding, and tail.

Inherited from Object

Hide

Text's constant acceleration in world coordinates per second squared.

⚠️ Acceleration only affects Text when Text.Physics is PhysicsMode.Dynamic.

-- Acceleration can be used to compensate gravity: 
myObject.Acceleration = -Config.ConstantAcceleration
-- myObject's acceleration is now the invert of 
-- Config.ConstantAcceleration, cancelling it.

Collision groups the Text belongs to.

⚠️ It doesn't mean the Text will collide with other Objects in these groups.

If the Text belongs to group number 3 for example, it means all Objects that have group number 3 in their Object.CollidesWithGroups property will collide with it.

By default:
- Objects collide with the Map and other Objects
- Players collide with the Map only

That can all be configured differently depending on your needs.

Collision groups are best used as buckets created for gameplay needs, for example,
- a group for "hittable" objects that can be damaged by the player's weapon
- a group for recyclable Objects that are disabled and thrown back into their pool when they reach a certain trigger collider
- a group for static scenery objects that moving objects will bump into
- a group for objects that can get hit by raycasts executed for some specific game mechanic
It may well be the case that one object belongs to several or all of these groups, depending on the gameplay associated with it.

In general, it is bad practice to assign or add all collision groups from one object to another (unless making exact copies), as it isn't future-proof if you later add more groups. Instead, you should assign individual groups depending on what this new object should contribute to in your world.

-- these are the group numbers assigned by default to Map, Player, and all Objects
local GROUP_MAP = 1
local GROUP_PLAYER = 2
local GROUP_OBJECT = 3

-- by default, this object will collide with the map and other objects
local o = Object()
o.Physics = PhysicsMode.Dynamic

-- when in doubt, print the groups of your objects
print(Map.CollisionGroups, Map.CollidesWithGroups)
print(o.CollisionGroups, o.CollidesWithGroups)

-- let's say our world needs an extra group for a gameplay mechanic, for example, a group for objects that can be hit by player's weapon (which could perform a raycast in that group)
local GROUP_HITTABLE = 4

-- here, the object would collide with anything that cares about GROUP_OBJECT or GROUP_HITTABLE, in addition to itself wanting to collide with GROUP_MAP and GROUP_PLAYER
o.CollisionGroups = { GROUP_OBJECT, GROUP_HITTABLE }
o.CollidesWithGroups = { GROUP_MAP, GROUP_PLAYER }

-- when adding new obstacle/scenery objects to our scene, you can simply re-use the GROUP_MAP as a way to say "this is part of the environment that is collidable"
-- here, maybe this object only acts as an obstacle and doesn't contribute to anything else
someBigRock.CollisionGroups = GROUP_MAP
someBigRock.CollidesWithGroups = nil

-- doing this effectively prevents all physics interaction on an object
o.CollisionGroups = nil
o.CollidesWithGroups = nil

-- note that there is redundancy with CollisionGroups and CollidesWithGroups, so you can organize your groups however seems more convenient for you
-- for example the following setups will all result in object1 and object2 colliding with each other
object1.CollisionGroups = GROUP_OBJECT
object1.CollidesWithGroups = nil
object2.CollisionGroups = GROUP_OBJECT
object2.CollidesWithGroups = GROUP_OBJECT

object1.CollisionGroups = GROUP_OBJECT
object1.CollidesWithGroups = GROUP_OBJECT
object2.CollisionGroups = GROUP_OBJECT
object2.CollidesWithGroups = nil

object1.CollisionGroups = GROUP_OBJECT
object1.CollidesWithGroups = GROUP_OBJECT
object2.CollisionGroups = GROUP_OBJECT
object2.CollidesWithGroups = GROUP_OBJECT

object1.CollisionGroups = GROUP_OBJECT
object1.CollidesWithGroups = nil
object2.CollisionGroups = nil
object2.CollidesWithGroups = GROUP_OBJECT

Collision groups the Text collides with. See Text.CollisionGroups.

By default:
- Objects collide with the Map and other Objects
- Players collide with the Map and the Objects

That can all be configured differently depending on your needs.

local object = Object()

-- It's not mandatory to change Physics value.
-- (default value is PhysicsMode.Static)
-- An object with Physics set to PhysicsMode.Static contributes 
-- to the physics simulation as a static item (can't be moved)
object.Physics = PhysicsMode.Dynamic

-- making an object collide with the Map and Players
object.CollidesWithGroups = Map.CollisionGroups + Player.CollisionGroups

-- for an Object to collide with other objects only
-- (won't collide with the map)
object.CollidesWithGroups = object.CollisionGroups

-- for Player (local player) to collide with other players and the Map
Player.CollidesWithGroups = Map.CollisionGroups + Player.CollisionGroups

-- making sure 2 objects collide with each others
-- NOTE: by default:
-- Map.CollisionGroups == {1},
-- Player.CollisionGroups == {2},
-- Object.CollisionGroups == {3}
local object1 = Object()
local object2 = Object()
object1.CollisionGroups = {5}
object2.CollisionGroups = {5}
object1.CollidesWithGroups = {1, 5} -- collides with Map + objects in group 5
object2.CollidesWithGroups = {1, 5} -- collides with Map + objects in group 5

-- would also work this way if you don't 
-- remember Map's group (which can be changed too by the way)
object1.CollidesWithGroups = Map.CollisionGroups + {5}

Sets the simulation mode for this object, it can be one of the following:
- PhysicsMode.Disabled: excluded from all physics features.
- PhysicsMode.Trigger: Text's collision box is available for casts and collision callbacks, and is passed through by other dynamic objects.
- PhysicsMode.TriggerPerBlock: if Text is a Shape, its model blocks are available for casts and collision callbacks, and is passed through by other dynamic objects.
- PhysicsMode.Static: Text's collision box is available for casts, collision callbacks, and acts as an obstacle for other dynamic objects.
- PhysicsMode.StaticPerBlock: if Text is a Shape, its model blocks are available for casts, collision callbacks, and act as obstacles for other dynamic objects.
- PhysicsMode.Dynamic: Text's world-aligned collision box is available for casts, collision callbacks, may act as obstacles for other dynamic objects, and is itself fully simulated. When setting this mode, any children that may collide with the object will be automatically set to PhysicsMode.Disabled.

By default, players are PhysicsMode.Dynamic, shapes are PhysicsMode.Static, all other objects are PhysicsMode.Disabled.

You may use Dev.DisplayColliders to visualize each object's collision settings.

⚠️ When set to PhysicsMode.Disabled, Text.Velocity & Text.Motion are set to {0,0,0}.

nil by default. Can be set to a function that will be triggered when this object begins a collision with another object.

The function is called with 3 parameters:
- the object the callback was set for,
- the other actor in the collision,
- the world normal of the hit surface.

Note: it's not necessary to use all 3 parameters.

object.OnCollisionBegin = function(self, other, normal)
  print("collision began between", self, " and ", other, " with world normal ", normal)
end

nil by default. Can be set to a function that will be triggered every frame where this object remains in contact with another object.

Like OnCollisionBegin, this function has 3 arguments: self, other, normal.

nil by default. Can be set to a function that will be triggered when the Text ends colliding with another Object.

The function is called with 2 parameters: the object the callback was set for and the other actor in the collision.

object.OnCollisionEnd = function(self, other)
  print("collision ended between", self, "and", other)
end

Position of the Text in the world.

local o = Object()
-- places the object where the local player is
o.Position = Player.Position
boolean IsOnGround read-only

true when the Text is not falling.

⚠️ IsOnGround only makes sense when Text.Physics is PhysicsMode.Dynamic.

Can be set to true for the Text to be hidden recursively, meaning Text and all of its children are hidden.

Nothing else changes, the Text remains in the scene and it keeps being affected by the simulation (collisions, etc.).

Can be set to true for the Text to be hidden individually.

Nothing else changes, the Text remains in the scene and it keeps being affected by the simulation (collisions, etc.).

Size in world units of the shadow cookie projected under the Text, default is 0.0 (disabled).
The shadow cookie, also called blob shadow, is a square texture acting as a cheap alternative to projected shadows.

If this value is strictly positive, shadow cookies will be displayed when:
- the scene has no light source,
- the scene has light sources, but they are disabled because the client is using lower quality settings

Shadow cookies can be used as a fallback to your scene shadows for players with low quality settings, of course, you can also use them instead of shadows as a design choice.

Local position of the Text relative to its parent.

All of Text's ancestors local transformations are combined to obtain the Text "world position" (Object.Position), the Object's final position.

Rotation of the Text in the world (as seen on screen).

While it usually works for simple operations (like Rotation.X = Rotation.X + someAngle), we advise you to use Number3.Rotate to rotate an object around X, Y & Z axis.

You can also set unit vectors like Text.Up, Text.Right or Text.Forward to orient your object.

local o = Object()
o.Rotation = {0, math.pi, 0}
-- o revolved half a turn on Y axis

-- another way to rotate the object:
o.Forward:Rotate({0, 0, math.pi / 2})
o.Forward = Camera.Forward

Tick is a function executed each frame when set (nil by default). Provides the Text and elapsed time in seconds as parameters.

For general purposes, you may consider using Client.Tick instead. It is functionally the same, but is executed once for your world per frame, rather than once per frame per object.

The exact number of frames per second may fluctuate and depend on the device. It is typically around 60 frames per second.

myObject.Tick = function(object, dt)
  print("elapsed:", dt, "seconds since last frame")
end

Local rotation of the Text relative to its parent.

All of Text's ancestors local transformations are combined to obtain the "world rotation" (Object.Rotation), the Object's final rotation.

Velocity of the Text in world coordinates per second.

⚠️ Velocity only affects Text when Text.Physics is PhysicsMode.Dynamic.

-- makes myObject jump:
myObject.Velocity.Y = 100

Motion is an instantaneous displacement that contributes to moving Text every frame, without changing Text.Velocity directly, and without being affected by collision responses and other forces. It is expressed in world coordinates per second.

It's very useful to quickly implement character movement. This is what's being used by default when you're moving around with your avatar (see Client.DirectionalPad). It's the reason why you can stop moving horizontally while in the air.

⚠️ Motion only affects Text when Text.Physics is PhysicsMode.Dynamic.

local speed = 10
myObject.Motion = Camera.Forward * speed
-- myObject will move in the same direction the camera is currently facing.
-- If the Camera rotates after this, it won't change where myObject is heading.

Scale of the Object, in its parent local space. Can be set to a number for a uniform scale.

Nested Object local scales are combined to obtain the "world scale" (Object.LossyScale), the Object's final scale.

-- make the object twice as big
myObject.LocalScale = 2

-- equivalent to
myObject.LocalScale = Number3(2, 2, 2)
myObject.LocalScale = { 2, 2, 2 }
-- demonstrate how scales are combined in the hierarchy
local parentObject = Object()
parentObject:SetParent(World)
parentObject.LocalScale = 2

local childObject = Object()
childObject:SetParent(parentObject)
childObject.LocalScale = 0.5

-- here, the scales would cancel each other: 2 x 0.5 = 1
print(childObject.LossyScale) -- returns (1,1,1)
Number3 LossyScale read-only

Convenience property that attempts to match the actual world scale as much as it can. Note that Objects that have multiple levels of nested rotations and scales will return a skewed lossy scale.

The mass of the Object determines how much a given force can move it and whether or not another object can be pushed by it. It cannot be zero, a neutral mass is a mass of 1.

The combined friction of 2 Objects in contact represents how much the moving Object will be able to slide along the colliding Object.

It is a rate between 0 (full slide, no friction) and 1 (maximum friction). Values equal to or lower than 0 will keep or increase momentum, like sliding on ice. Values higher than 1 means a faster stop, up to a value of 2 to ensure a full stop on contact regardless of the colliding Object's own friction.

[Object.Friction] can be set per-face by providing a table with any combination of the following keys : right, left, front, back, top, bottom, other.
For example, to set the friction on the bottom face of an object's collider to 0 and 0.2 on every other faces, you could set, object.Friction = { bottom=0, other=0.2 }.

The combined bounciness of 2 Objects in contact represents how much of the moving Object's velocity is produced after being in contact with the colliding Object, it is a rate between 0 (no bounce) and 1 (100% of the velocity bounced). Values higher than 1 are allowed and will create an increasing momentum at each bounce (try at your own risk).

[Object.Bounciness] can be set per-face by providing a table with any combination of the following keys : right, left, front, back, top, bottom, other.
For example, to set the bounciness on the side faces of an object's collider to 0.2 and 0 on top and bottom faces, you could set, object.Bounciness = { top=0, bottom=0, other=0.2 }.

All Objects have a collision box that represents the space occupied in the scene with regards to collisions. For Shapes and Players, the collision box is updated with their bounding box. For Objects, it is a 1-cube by default after physics was enabled for the first time.

Returns number of child Objects.

Up is a unit vector (vector with a length of 1). It determines which direction is "up" for the Text.

Setting it is a way to rotate the Text.

Right is a unit vector (vector with a length of 1). It determines which direction is "right" for the Text.

Setting it is a way to rotate the Text.

Forward is a unit vector (vector with a length of 1). It determines which direction is "forward" for the Text.

Setting it is a way to rotate the Text.

Left is a unit vector (vector with a length of 1). It determines which direction is "left" for the Text.

Setting it is a way to rotate the Text.

Down is a unit vector (vector with a length of 1). It determines which direction is "down" for the Text.

Setting it is a way to rotate the Text.

Backward is a unit vector (vector with a length of 1). It determines which direction is "backward" for the Text.

Setting it is a way to rotate the Text.