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.)

The Beta API

The 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.

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.

APIs that affect a wide area may be subject to distance limitations.

API restrictions at top level

APIs that can be used to scripts 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.

Handle Manipulation

Scripting interfaces such as PlayerHandle and ItemHandle are called Handles. 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.

Note that ItemHandle.send is NOT considered a Handle Manipulation. Therefore, 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.

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