Cluster Creator Kit Script Reference

[ 日本語 / English (US) ]

cluster-script-types

The Cluster Creator Kit gives you the ability to create Items and Worlds with ease. You can also enhance your creations with advanced interactions by using JavaScript.

This document outlines the APIs that can be accessed from JavaScript. For information on Components used in the Creator Kit, refer to the Creator Kit Documentation.

Note that this document will not cover JavaScript's standard built-in objects. For a guide on general JavaScript usage, please refer to MDN's JavaScript Reference Documentation.

Special Notations in this Document

Beta

This denotes that the type or method is only available in environments where the use of Beta features are permitted.
(If they are not permitted, a ClusterScriptError will occur.)

Item

This denotes that the type or method is only available for scripts of the Scriptable Item component.

Player

This denotes that the type or method is only available for scripts of the Player Script component.

Basic Concepts

All scripts are executed within an individual Item. No script can run outside of items. Each script, within each Item, holds its own State ($.state), and will execute concurrently as long as they exist within the world space.

Items have the ability to change their appearances through the use of APIs and components. Each Item can also freely manipulate their own State. However, an item cannot read or write the State of other items. Interaction between Items are limited to exchanging information through specific APIs, and physical interplay within the world space.

To preserve the independent operation of Items and to protect the player experience, Cluster can limit the CPU time and memory allocated to each Item. This ensures that even if some Items exceed their designated resource limits, other items will remain functional and the application will maintain frame rate. However, if limits are exceeded, an exception may occur or the script execution may be temporarily suspended.

API limitations

API usages may have certain limitations.

  • Rate limitations: How frequently an item can call APIs may be limited.
  • Size limitations: String length and Sendable data sizes of API arguments may be limited.

If these limits are exceeded, ClusterScriptError will occur and operations will fail. Please refer for documents of each APIs for individual limit values.

Limit values may be different by whether the world is Creator Kit-based or World Craft. Limit value may change with prior notice.

Beta API

Beta API is only enabled in environments where the use of Beta features are permitted. It is provided for the purpose of gathering feedback on usage before the final release, to accelerate development.

For details on Beta features, Refer to the Beta features section of the Creator Kit documentation.

Top level and callbacks of ScriptableItem

APIs that can be used from ScriptableItem are classified into three types.

  • Available only at the top level.
    • This applies to APIs that registers callbacks.
    • For example, $.onStart or $.onUpdate, etc.
  • Available for callbacks only.
    • This applies to APIs that read or write states of the world space.
    • For example, $.state, $.getPosition or ItemHandle.send, etc.
  • Available at both top level and callbacks.
    • This applies to APIs that return a constant value regardless of the state of world space.
    • For example, $.subNode or new Vector3, etc.

APIs that are available only through callbacks are not supported when called at the top level. In such cases, a warning message is logged to script console.

Standard JavaScript APIs not provided by Cluster Creator Kit are available at top level. However, it is not recommended to call JavaScript APIs that return different values per call, such as Math.random() or new Date(). Instead, register callbacks and retrieve references like SubNode on top level, and place further item initialization under $.onStart.

Top level and callbacks of PlayerScript

All APIs that can be used from ScriptableItem are available at both top level and callbacks.

Handles

In ClusterScript, reference values that can be used from script and point other entities in a space instance are called Handles, and ItemHandle and PlayerHandle are example of this.

Note: There are other types with Handle in their names, such as MaterialHandle or CameraHandle. They are different from Handles described here in the sense that they are part of an item or player.

Following APIs returns values of type either ItemHandle or PlayerHandle:

You can distinguish between ItemHandle and PlayerHandle by using ItemHandle.type and PlayerHandle.type. In this case, be aware that values such as RaycastResult.handle may be null.

$.onReceive((messageType, arg, sender) => {
if (sender.type === "item") {
$.log(`message from item: ${messageType}`);
} else if (sender.type === "player") {
$.log(`message from player: ${messageType}`);
}
}, { player: true });

Alternatively, JavaScript's instanceof operator can be used to distinguish between ItemHandle and PlayerHandle.

$.onReceive((messageType, arg, sender) => {
if (sender instanceof ItemHandle) {
$.log(`message from item: ${messageType}`);
} else if (sender instanceof PlayerHandle) {
$.log(`message from player: ${messageType}`);
}
}, { player: true });

ItemId and PlayerId of PlayerScript can be distinguished in a similar manner.

Handle Manipulation

Calling methods such as set..., add..., or reset..., which all modify the handle, are considered "Handle Manipulations".

An Item can perform Handle Manipulations on other Handles up to 10 times per second. This can be exceeded momentarily, but please keep the average below this limit. If the limit is exceeded, a ClusterScriptError will occur.

ItemHandle.send has a rate limit separated from Handle Manipulations. In other words, both handle Manipulations and ItemHandle.send operations can be invoked up to 10 times per second each.

Script Execution while in World Craft

This section will provide detail on the timing of script execution and the State of Items in World Craft.

Execution Timings

Scripts will keep executing as long as they exist in the world space. Scripts will not execute if the world it resides in does not have any players present. (In the future, we may impose new measures to reduce processing load, such as temporarily suspending scripts attached to far away Items.)

  • Scripts will execute both while manipulating an Item in Craft Mode, and also while trying out an Item in the store.

States

An Item will start with an empty State in the case of the following:

  • When an Item is newly spawned into the world space
    • When an Item is created through createItem
    • When an Item is placed using Craft Mode

An Item will retain its State in the case of the following:

  • When an Item is moved/rotated in Craft Mode

When copying an Item in Craft Mode, its State is not copied over. It will start from a empty State, like other newly created items.

When onStart is called

The conditions under which onStart is called differ between World Craft and Creator Kit-developed worlds.

  • World Craft

    • onStart is executed only once when an item newly appears in the space.
      • When an item is copied, onStart is executed for the newly created item by the copy.
      • This is because the state is not duplicated when an item is duplicated.
    • Whether an item has executed onStart is saved as part of the state. Thus, onStart will not be executed again upon re-entry.
  • Published Worlds (World Craft-based)

    • When a new space starts on a World Craft-based world, the state of the space begins with the "state of World Craft at the time of publishing".
    • Therefore, for items that have executed onStart in the original World Craft, it will not be executed on the World Craft-based world.
    • For items newly created after the space starts, onStart will be executed in the same way as World Craft.
  • Creator Kit-based Worlds

    • For items placed in the world, onStart is executed when a new space starts.
    • For items newly created after the space starts, onStart is executed at the time of creation.

Collisions and Overlaps

  • "Collisions" refer to physical collisions, and are described using the Collision object. In Unity, this corresponds to collisions between non-trigger colliders.
  • "Overlaps" refer to non-phyiscal contact, and are described using the Overlap object. In Unity, this corresponds to overlaps between colliders configured as triggers.

While moving Items in Craft Mode, neither Collisions nor Overlaps will register for that Item. This applies for both newly created Items and already existing Items.

Obtaining the time, and a word of warning on time zones

Scripts in the world space may be executed from players all around the globe. Be careful not to write code that makes assumptions about your local time zone, as it may lead to unexpected behavior.

Obtaining the time in the following style may lead to unexpected behavior.

const date = new Date();
$.log(`${date.getHours()}:${date.getMinutes()}:${date.getSeconds()}`);

Instead, make sure to write scripts like the following, which explicitly specifies the time zone.

// A script to obtain the date in Coordinated Universal Time (UTC), regardless of the runtime environment
function getUTCDate() {
const date = new Date();

return {
timezone: "Etc/UTC",
hours: date.getUTCHours(),
minutes: date.getUTCMinutes(),
seconds: date.getUTCSeconds(),
};
}

// A script to obtain the date in Japan Standard Time (JST), regardless of the runtime environment
function getJSTDate() {
const date = new Date();

// Convert the date to Etc/GMT-9 (+9 hours difference)
date.setTime(date.getTime() + 3600000 * 9);

return {
timezone: "Etc/GMT-9",
hours: date.getUTCHours(),
minutes: date.getUTCMinutes(),
seconds: date.getUTCSeconds(),
};
}

// A script to obtain the date in US Eastern Standard Time (EST), regardless of the runtime environment
function getESTDate() {
const date = new Date();

// Convert the date to Etc/GMT+5 (-5 hours difference)
date.setTime(date.getTime() + 3600000 * -5);

return {
timezone: "Etc/GMT+5",
hours: date.getUTCHours(),
minutes: date.getUTCMinutes(),
seconds: date.getUTCSeconds(),
};
}

function logDate(date) {
const hours = date.hours.toString().padStart(2, "0");
const minutes = date.minutes.toString().padStart(2, "0");
const seconds = date.seconds.toString().padStart(2, "0");
$.log(`${date.timezone}: ${hours}:${minutes}:${seconds}`);
}

$.onInteract((player) => {
const dateUTC = getUTCDate();
logDate(dateUTC);

const dateJST = getJSTDate();
logDate(dateJST);

const dateEST = getESTDate();
logDate(dateEST);

// Do NOT use the below, as the results will vary depending on the runtime environment
// const date = new Date();
// $.log(`local: ${date.getHours()}:${date.getMinutes()}:${date.getSeconds()}`);
});

About the Priority of PostProcessEffects

The post-effects set for a player are represented as a Global Volume in Unity's PostProcessing. The Priority of this Volume is set to 100, which overrides any PostProcessVolume in the world with a Priority less than 100. If the settings of PostProcessEffects are not set using setValue(), or if clear() is called, the values of PostProcessVolume placed in the world will be used.

The DepthOfFieldSettings of PostProcessEffects set for PlayerHandle is subject to being overridden by the camera's depth of field.

The BloomSettings and ColorGradingSettings of PostProcessEffects set for PlayerHandle are subject to being overridden by the World Craft's light intensity and color effects.

Regarding the validity period of PlayerScript added by $.setPlayerScript.

A PlayerScript added by $.setPlayerScript is valid only while the item that has called $.setPlayerScript is still in the space. When the item is deleted, the PlayerScript assigned from the item will also be deleted.

If $.setPlayerScript is called multiple times, the PlayerScript granted by the earlier $.setPlayerScript will be deleted and overwritten by the script of the later $.setPlayerScript.

When a PlayerScript is deleted, the camera settings and button display settings configured by the PlayerScript will be reset.

As PlayerScript is a beta feature, the behavior when PlayerScript is deleted may be changed in the future.

Type Declaration Files

We provide TypeScript type declaration files on npm for those who wish to use autocompletion on their code editor apps.

https://www.npmjs.com/package/@clustervr/cluster-script-types

Generated using TypeDoc