Documentation

Support

Script structure

Understand the structure of a Cloud Code script and how the main function acts as the entry point.
Read time 4 minutesLast updated a day ago

The main function in a Cloud Code script that acts as the entry point of the runtime takes the form of a CommonJS wrapper. The following code snippet shows the simplest possible script: JavaScript
module.exports = async ({ params, context, logger }) => { // this script does nothing};
While this script doesn’t actually do anything, it shows the context object and asynchronous nature of the script function.

Context object

The context object contains these useful objects:
  • Params
    : This is an array of name-value pairs of the input parameters with which a script is called.
  • Context
    : This object provides additional context that is useful within a script:
    • projectId
      : The project ID to which the caller was authenticated.
    • playerId
      : The authenticated player ID.
    • accessToken
      : A JWT that can be used to call other Unity game services SDKs as the authenticated player.
    • environmentName
      : The name of the currently used Unity environment.
    • environmentId
      : The ID of the currently used Unity environment.
    • serviceToken
      : A JWT used to call other Unity game services SDKs as an authenticated Cloud Code user.
    • unityInstallationId
      : Unique identifier that identifies an installation on the client’s device. The same player can have different
      installationId
      s if they have the game installed on different devices. It is available to all Unity packages that integrate with the Services SDK Core package.
    • analyticsUserId
      : A unique string that identifies the player and is consistent across their subsequent play sessions for analytics purposes. It is the primary user identifier and it comes from the Core package.
    • correlationId
      : Unique identifier used to correlate requests.
  • Logger
    : An object that allows the script to log info, warnings, and errors.

JavaScript

module.exports = async ({ logger }) => { logger.info("This message confirms that the logging client is functional!"); logger.warning("This is a serious warning that the cheese is about to run out."); logger.error("Out of cheese :(");};
Refer to the Logging documentation for more information.

Token authentication

The
accessToken
and
serviceToken
are JWTs, provided as properties of the
context
object.
These tokens authenticate calls to other Unity Gaming Services from Cloud Code.

Token type

Origin

Data access

Usage

accessToken
Generated by the Authentication serviceRestricted to the authenticated playerThe
accessToken
is the JWT the Cloud Code call is authenticated with. It can be passed onto other UGS services to access data for the authenticated player
serviceToken
Generated by Cloud CodeAllows cross-player data accessThe
serviceToken
is Cloud Code generated token that can be used to call out to other UGS services and interact with cross-player data
Any configured Access Control rules affect the
accessToken
.
Below is an example of how to use the
accessToken
to call the Economy SDK to get the player's inventory.

JavaScript

// Player inventoryconst { InventoryApi } = require("@unity-services/economy-2.4");module.exports = async ({ params, context, logger }) => { const { projectId, playerId, accessToken } = context; const inventory = new InventoryApi({ accessToken }); const result = await inventory.getPlayerInventory({ projectId, playerId }); return result.data;};
If you want to use
serviceToken
, the same script would look like this:

JavaScript

// Player inventoryconst { InventoryApi } = require("@unity-services/economy-2.4");module.exports = async ({ params, context, logger }) => { const { projectId, playerId } = context; const inventory = new InventoryApi(context); const result = await inventory.getPlayerInventory({ projectId, playerId }); return result.data;};
Refer to Service and access tokens for an in-depth explanation of the differences between the two tokens.

Script parameters

Script parameters can be defined outside or inside the script body.

In-script parameters

In-script parameters can be added by exporting the
params
object, containing each parameter name as a key, and its type as a value.
For example:

JavaScript

module.exports.params = { echo: "Boolean" };
Alternatively, if you'd like to specify that a parameter is required, you may specify an object containing both the
type
and
required
properties.

JavaScript

module.exports = async ({ params, context, logger }) => { return { value: params["aParam"], };};module.exports.params = { aParam: { type: "String", required: true } };
By default, parameters are not required. Both formats can be combined as desired:

JavaScript

module.exports = async ({ params, context, logger }) => { var value = params["echo"] ? params["aParam"] : "default"; return { value: value, };};module.exports.params = { echo: "Boolean", aParam: { type: "String", required: true },};

Async/await

The main script function can be an asynchronous function. This means that a function can await promises, which enables the use of other Unity game service SDKs within the script. Check the Mozilla documentation describing promises. A trivial example looks like the following:

JavaScript

// Player inventoryconst { InventoryApi } = require("@unity-services/economy-2.4");module.exports = async ({ params, context, logger }) => { const { projectId, playerId } = context; const inventory = new InventoryApi(context); const result = await inventory.getPlayerInventory({ projectId, playerId }); return result.data;};

Additional packages

Your scripts can import local scripts or external packages with the
import
or
require
keywords.
Refer to the Available packages for a full list that can be imported.

JavaScript

const _ = require("lodash-4.17");module.exports = async () => { return _.random(1, 6);};

Bundling

Script bundling is a feature enabled by using the Deployment package within the Unity Editor to help manage your scripts locally, unlock additional workflows and enables common functionality to be shared across multiple scripts. Refer to the JS bundles documentation for details on how to generate bundled scripts.

JavaScript

const lib = require("./lib");module.exports = async () => { return lib.helloWorld();};module.exports.bundled = true;

Output

Script output can consist of the following types:

JavaScript

  • string
    module.exports = async () => { return "hello world";};
  • boolean
    module.exports = async () => { return true;};
  • number
    module.exports = async () => { return 3.14;};
  • object
    module.exports = async () => { return { message: "hello world", success: true, };};
Successful responses are returned from the API as JSON with the following structure:
{ "output": <SCRIPT OUTPUT>}

Error output

Errors can be thrown by scripts when something causes the invocation to fail for example, a failed service request. Catching errors within your scripts allows you to determine how the failure should be handled.

JavaScript

module.exports = async ({ logger }) => { try { let result = service.call("example"); return result; } catch (err) { logger.error("Something went wrong!", { "error.message": err.message }); throw err; }};
Error responses are returned from the API as JSON with error details containing the error type, error message and a stack trace to help identify the cause of the error.
{ "type": "problems/invocation", "title": "Unprocessable Entity", "status": 422, "detail": "Invocation Error", "instance": null, "code": 9009, "details": [ { "name": "ReferenceError", "message": "service is not defined", "stackTrace": [ "at module.exports (example-test.js:1:26)" ] } ]}