Docs

These docs are made to be read by both humans and AI. They are the same docs given to your AI when it runs!

Core Objects

Ball

A ball in the world.

FieldType
id
type

'ball'

name

string

material

Visual Material texture settings.

opacity

number

0-1.

color
outline
isAlwaysOnTop

boolean

Whether to render in front even if visually blocked.

radius

number

location
movement
isWalkthrough

boolean

Whether this object can pass through other objects.

isAnchored

boolean

Whether this object is totally unmovable.

density

number

Brick

A brick in the world.

FieldType
id
type

'brick'

name

string

material

Visual Material texture settings.

opacity

number

0-1.

color
outline
isAlwaysOnTop

boolean

Whether to render in front even if visually blocked.

size
location
movement
isWalkthrough

boolean

Whether this object can pass through other objects.

isAnchored

boolean

Whether this object is totally unmovable.

density

number

Cylinder

A cylinder in the world. Its symmetry axis is local Z.

FieldType
id
type

'cylinder'

name

string

material

Visual Material texture settings.

opacity

number

0-1.

color
outline
isAlwaysOnTop

boolean

Whether to render in front even if visually blocked.

radius

number

length

number

location
movement
isWalkthrough

boolean

Whether this object can pass through other objects.

isAnchored

boolean

Whether this object is totally unmovable.

density

number

RigidGroup

A RigidGroup is a bunch of objects that move together. All Ball, Brick, and Cylinder child descendants are glued together and will move as one rigid body.

If you want to add animations, you must set followSkeletonId, use a JointAnimator to animate it, and add JointAttachment objects to glue objects to the joints. There are some AI tools to automate this.

FieldType
id
type

'rigidGroup'

name

string

followSkeletonId

ObjectId | null

The objectId of the Skeleton that this rigid group will follow.

location
movement

Group

Use this as a Folder. There is no special behavior, it is simply for organization.

FieldType
id
type

'group'

name

string

Mesh

A mesh in the world.

To animate this mesh visually, you must set followSkeletonId and use a JointAnimator to animate it.

FieldType
id
type

'mesh'

name

string

scale
meshDataId
followSkeletonId

ObjectId | null

The objectId of the Skeleton that this mesh will visually follow.

physicalObjectId

ObjectId | null

The objectId of the Ball, Brick, Cylinder, or RigidGroup that the mesh will use as a collider and visually follow.

material

Visual Material texture settings.

opacity

number

0-1.

color
outline
isAlwaysOnTop

boolean

Whether to render in front even if visually blocked.

Animation Objects

Skeleton

Use skeletons to animate all your objects. Skeletons are just a collection of Joint objects, which are just locations + rotations in space that you can glue objects to in order to animate.

FieldType
id
type

'skeleton'

name

string

Joint

Joints must go inside a Skeleton or another Joint.

The bindPose is the initial reference location that movements in an animation (JointAnimation) are relative to.

FieldType
id
type

'joint'

name

string

bindPose

Relative to the parent.

JointAttachment

Use JointAttachments to glue objects in a RigidGroup to a Joint. The objects will move physically with the joint, not just visually.

FieldType
id
type

'jointAttachment'

name

string

objectId

ObjectId | null

The objectId of the object to attach to the joint.

followJointName

string

offsetFromJoint

JointAnimator

Use this object to play an animation.

This makes a Skeleton move, based on a JointAnimation and a Clock. Multiple of these can point to the same skeleton; they blend their animations until weight reaches 100.

Start and stop an animation by saying _________

FieldType
id
type

'jointAnimator'

name

string

skeletonId

ObjectId | null

The Skeleton to animate.

jointAnimationId

ObjectId | null

Using this JointAnimation.

clockId

ObjectId | null

The Clock that lets you pause/play it.

priority

number

Higher priority animations are blended first.

weight

number

0-100.

JointAnimation

This is how you define an animation. This object contains a JointKeyframe child for each frame in the animation. Those keyframe objects have a JointPose child that says how to offset each Joint relative to its bindPose.

You play this animation using a JointAnimator.

FieldType
id
type

'jointAnimation'

name

string

duration

number

interpolationStyle

JointKeyframe

A child of JointAnimation.

FieldType
id
type

'jointKeyframe'

name

string

time

number

JointPose

A child of JointKeyframe.

FieldType
id
type

'jointPose'

name

string

jointName

string

relativePose

Other Objects

Clock

A clock is just an internal helper object that tells us how far along we are in an JointAnimator or Sound. Clock lives on the client. It can use either client time or estimated server time as its reference.

FieldType
id
type

'clock'

name

string

reference

The time reference at which the clock started, or null when it is paused.

shouldLoop

boolean

Whether it should loop when done.

speed

number

A multiplier onto the normal speed.

Material

An image or "texture" that is shown on an object. Albedo is the main texture. The other fields are optional PBR properties.

FieldType
id
type

'material'

name

string

albedoTextureDataId

DataId | null

This is the main texture to place on the object. Four values (RGBA) per pixel.

metallicTextureDataId

DataId | null

Optional metallic information. One value per pixel.

roughnessTextureDataId

DataId | null

Optional roughness information. One value per pixel.

normalTextureDataId

DataId | null

Optional normal information. Three values (XYZ) per pixel.

alphaMode

Says how to handle the underlying object's transparency. Only relevant when albedoTextureDataId has transparency in it.

Player

You can never create a Player object yourself. It is automatically created and deleted when a player joins and leaves. It is important for you to set the head and controls, or the player won't be able to see or move.

FieldType
id
type

'player'

name

string

username

string

userid

string

headObjectId

ObjectId | null

The objectId of the Ball, Brick, Cylinder, or RigidGroup the player's camera will follow.

controlsObjectId

ObjectId | null

The objectId of the Ball, Brick, Cylinder, or RigidGroup this player controls. Only one player can control this object at a time. If you set two to the same thing, the last one wins, and the previous one is cleared.

physicsControls

Physics constants used when the player moves.

Script

Every Script is either a Server or Client script.

  • Client scripts run on every client and can only do a limited set of things like show UI and play animations.
  • Server scripts run on the server so can do elevated things like access storage and leaderboards.

Imports:

  • Simply write import { functionName } from './scriptName' to use scripts as modules.
  • You can use setTimeout() and setInterval(). Scripts expose all web APIs except fetch.
  • Scripts and their path names are set once, when the script is created.

Server-Client:

  • You should communicate between the server and client by calling functions across the network.
  • Write 'use server' at the top of a Server script to make all exports accessible to Client scripts.
  • Write 'use client' at the top of a Client script to make all exports accessible to Server scripts.
    • Exports should be async functions.
    • The first argument to client functions must be the player's user id.
  • You should validate server function inputs and client function return values.

UI:

  • We expose React-like syntax to draw UI on the screen.
  • You may only use <div>, text, arrays, null, className, onClick, and onHover primitive props on divs.
  • You can use common Tailwind class names. Do not use style props or unsupported HTML tags.
  • useState() works like usual.
  • createState() works for state that comes from outside react, eg for 'use client' functions. This is similar to useSyncExternalStore.
    • Write createState(initialValue). The .get() function automatically subscribes the relevant React components to re-render when .set() is called.

Managing Objects:

  • Only the server can create objects.
  • With few exceptions, only the server can modify objects (exceptions: player locations, animation clocks, etc).
  • All objects in the world are replicated to all users. You cannot create an object on just one client.
FieldType
id
type

'script'

name

string

objectLocation

Sound

FieldType
id
type

'sound'

name

string

soundDataId

The sound to play.

clockId

ObjectId | null

The Clock that lets you pause/play it.

volume

number

WorldLighting

Controls the whole world's sun, ambient lighting, sky color, and skybox. The sunOrientation points from the world toward the sun and uses degrees.

FieldType
id
type

'worldLighting'

name

string

sunOrientation
sunColor
sunIntensity

number

ambientTopColor
ambientBottomColor
ambientIntensity

number

skyColor

The background sky color behind the world.

skyboxTextureDataId

DataId | null

An equirectangular skybox TextureData id. Transparent pixels reveal skyColor.

skyboxTextureOpacity

number

0 means the skybox texture is hidden. 1 means the skybox texture is fully visible.

Scripting

stopScript

Use await stopScript() to hang the script forever, so use it only when you want to stop all further execution of a script. Do not use this at the end of a script unconditionally, as it will hang the script, and any imports of it.

()

=>

Promise<never>

tick

Use await tick() to await for the next physics step. You must use this in infinite while loops, otherwise the script will stall and be killed.

()

=>

Promise<void>

FullLiveObjectJS

Scripts usually deal with this object type.

It contains all the fields of either a Ball, Brick, Clock, Cylinder, Group, Joint, JointAnimation, JointAnimator, JointAttachment, JointKeyframe, JointPose, Material, Mesh, Player, RigidGroup, Script, Skeleton, or Sound.

And it contains the following additional fields:

FieldType
getChild

name: string

=>
getChildren

name?: string

=>
parent

ObjectInfo

This is a helper type. It contains all the fields of either a Ball, Brick, Clock, Cylinder, Group, Joint, JointAnimation, JointAnimator, JointAttachment, JointKeyframe, JointPose, Material, Mesh, Player, RigidGroup, Script, Skeleton, Sound, or WorldLighting, excluding their id and name fields.

PlayerService

This service exposes methods for managing players in the game.

Example usage: game.playerService.getAllPlayers().

FieldType
getAllPlayers

()

=>

(FullLiveObjectJS & { type: "player" })[]

Only callable by a Server Script.

addJoinListener
=>

void

Only callable by a Server Script.

removeJoinListener
=>

void

Only callable by a Server Script.

addLeaveListener
=>

void

Only callable by a Server Script.

removeLeaveListener
=>

void

Only callable by a Server Script.

PlayerJoinHandler

=>

void

PlayerLeaveHandler

userid: UserId,

playerObjectId: ObjectId

=>

void

ObjectService

This service exposes methods for reading and modifying objects.

If you only want to operate on one object and not its children, simply write object.propery = value, and don't use the modifiers here.

FieldType
getObjectById

objectId: ObjectId

=>

Returns the object with this ObjectId.

getObjectByName

name: string

=>

Returns any object with this name.

getObjectsByName

name: string

=>

Returns all the objects with this name.

getObjectsByType

objectType: ObjectInfo["type"]

=>

Returns all the objects with this type.

createObject

name: string,

objectInfo: ObjectInfo,

parentId: ObjectId

=>

Creates an object. Only callable by a Server Script.

deleteObject

objectId: ObjectId

=>

void

Deletes the object with this ObjectId, and all of its children. Only callable by a Server Script.

cloneObject

objectId: ObjectId,

cloneName: string

=>

Clones the object and all its children, returning the clone. Remember to move the clone afterwards so it doesn't overlap. In cases where an ObjectId must only be pointed to by one object, the clone wins and the original's field is cleared. Only callable by a Server Script.

createJointAttachmentsInRigidGroup

skeletonId: ObjectId,

rigidGroupId: ObjectId

=>

Only callable by a Server Script.

scaleObject

objectId: ObjectId,

scaleMultiplier: number,

centerPoint: Vec3

=>

void

This scales the object and all children by the multiplier with respect to the center point. Note that repeatedly calling this will grow/shrink the object multiple times. Only callable by a Server Script.

rotateObject

objectId: ObjectId,

rotation: Vec3

=>

void

Rotates the object by this offset in degrees around each axis, bringing children with it. Only callable by a Server Script.

moveObjectBy

objectId: ObjectId,

offset: Vec3

=>

void

Moves the object by this offset, bringing children with it. Only callable by a Server Script.

moveObjectTo

objectId: ObjectId,

position: Vec3

=>

void

Moves the object to this exact position, bringing children with it. Only callable by a Server Script.

setObjectWalkthrough

objectId: ObjectId,

isWalkthrough: boolean

=>

void

Gives the object and all children the given isWalkthrough value. Only callable by a Server Script.

setObjectAnchored

objectId: ObjectId,

isAnchored: boolean

=>

void

Gives the object and all children the given isAnchored value. Only callable by a Server Script.

setObjectDensity

objectId: ObjectId,

density: number

=>

void

Gives the object and all children the given density value. Only callable by a Server Script.

AnimationService

This service exposes methods for smoothly transitioning between animations.

FieldType
changeWeight

animatorId: ObjectId,

targetWeight: number,

durationMs: number,

easing?: Easing

=>

void

Only callable by a Client Script.

Easing

"Linear" | "EaseInOut" | "EaseIn" | "EaseOut"

CollisionService

  • collisionService fires even when isWalkthrough=true.
  • collisionService is very granular even in RigidGroups, and will fire using a subitem's object_id.
FieldType
addCollisionListener
=>

void

removeCollisionListener
=>

void

addCollisionStopListener
=>

void

removeCollisionStopListener
=>

void

CollisionListener

=>

void

GuiService

The guiKey can be anything; it is a string you pick to identify the GUI root.

FieldType
show

guiKey: string,

rootRenderable: GuiRootRenderable,

anchor?: GuiAnchor | undefined

=>

void

Example: game.guiService.show("my-key", <MyComponent />, "top-left")

hide

guiKey: string

=>

void

Example: game.guiService.hide("my-key")

useState

Only callable by a Client Script.

initialState: T | (() => T)

=>

[T, (nextState: T | ((prevState: T) => T)) => void]

createState

Only callable by a Client Script.

initialState: T

=>

{ get: () => T; set: (nextState: T | ((prevState: T) => T)) => void; }

GuiAnchor

| "topLeft" | "top" | "topRight" | "left" | "center" | "right" | "bottomLeft" | "bottom" | "bottomRight"

GuiRootRenderable

GuiRenderable

This is the equivalent to a React Node.

The typical usage is <MyComponent />.

You can also use strings, numbers, booleans, null, and undefined.

Reference

ObjectLocation

"Server" | "Client"

ClockReference

FieldType
startedAtMs

number

The wall-clock ms at which the clock started in timeReference.

timeReference

Whether startedAtMs is client time or estimated server time.

BallPrimitiveSettings

FieldType
radius

number

CylinderPrimitiveSettings

FieldType
radius

number

length

number

BrickPrimitiveSettings

FieldType
size

BallMaterialSettings

FieldType
materialInfoId

The objectId of the Material to use.

tileSizeU

number

tileSizeV

number

CylinderMaterialSettings

FieldType
materialInfoId

The objectId of the Material to use.

tileSizeU

number

tileSizeV

number

BrickMaterialSettings

FieldType
materialInfoId

The objectId of the Material to use.

tileSizeU

number

tileSizeV

number

MeshMaterialSettings

FieldType
materialInfoId

The objectId of the Material to use.

JointInterpolationStyle

The interpolation style of the animation. Use Step for a stop-motion effect.

"Step" | "Linear" | "EaseInOut"

AlphaMode

This only applies to Material objects whose albedoTextureDataId have transparency. Default is Opaque.

  • Opaque means to render the underlying object as solid, meaning show the base color in the transparent areas.
  • Mask makes the underlying object either opaque or invisible in areas, based on the transparency cutoff.
  • Blend intuitively makes the object transparent where the material is transparent. More expensive to render.

"Opaque" | "Blend" | { Mask: { cutoff: number } }

PlayerPhysicsControls

FieldType
jumpHeight

number

Target number of blocks to which the player will jump. Internally we use this to figure out what impulse to apply.

stepHeight

number

The max obstacle height that the player will be teleported vertically onto, instead of getting stuck on.

speed

number

Movement speed.

acceleration

number

Movement acceleration.

Vec3

FieldType
x

number

y

number

z

number

ObjectId

Every object in the world gets a unique id that you can use to reference it. It's just a number. These object ids may change between compile time and runtime. We automatically convert most object ids, but you should not hard-code object ids into scripts as we can't parse those until runtime.

number

DataId

"Data" generally means large assets that are uploaded and given an id, like mesh data and texture data. Objects reference them using their data id.

number

UserId

The unique id of the user. This will never change, so you should use it when tracking players. It is preferred over the player's username or the Player object's id.

string

Location3D

This is called "location", but really means both position and rotation. In other words, the full information needed to place the object in 3D at snapshot in time. Can be global or local depending on context.

FieldType
position

Distance along x, y, z.

rotation

Degrees around x, y, z.

Movement3D

Speed information of an object. The derivative of Location3D.

FieldType
velocity

Distance per second along x, y, z.

angularVelocity

Degrees per second around x, y, z.

PhysicsToggles3D

A helper type.

FieldType
isWalkthrough

boolean

Whether this object can pass through other objects.

isAnchored

boolean

Whether this object is totally unmovable.

density

number

Color3

RGB color.

FieldType
r

number

Red on a scale of 0-1.

g

number

Green on a scale of 0-1.

b

number

Blue on a scale of 0-1.

OutlineEffect

Use this to add an outline around an object. You must set both the color and the width of the outline.

FieldType
color
width

number

Width in pixels. Max 8px.

VisualSettings

A helper type.

FieldType
opacity

number

0-1.

color
outline
isAlwaysOnTop

boolean

Whether to render in front even if visually blocked.

PhysicsInfo3D

A helper type.

FieldType
location
movement

Orientation3D

A helper type.

FieldType
theta

number

Degrees around the vertical direction. Starts at Z and goes clockwise around Y. This is what changes when you look left or right.

phi

number

Degrees with respect to the horizon (XZ plane). Upwards is positive. This is what changes when you look up or down.