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 3 months 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:
-
: This is an array of name-value pairs of the input parameters with which a script is called.
Params -
: This object provides additional context that is useful within a script:
Context- : The project ID to which the caller was authenticated.
projectId - : The authenticated player ID.
playerId - : A JWT that can be used to call other Unity game services SDKs as the authenticated player.
accessToken - : The name of the currently used Unity environment.
environmentName - : The ID of the currently used Unity environment.
environmentId - : A JWT used to call other Unity game services SDKs as an authenticated Cloud Code user.
serviceToken - : Unique identifier that identifies an installation on the client’s device. The same player can have different
unityInstallationIds if they have the game installed on different devices. It is available to all Unity packages that integrate with the Services SDK Core package.installationId - : 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.
analyticsUserId - : Unique identifier used to correlate requests.
correlationId
-
: An object that allows the script to log info, warnings, and errors.
Logger
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
These tokens authenticate calls to other Unity Gaming Services from Cloud Code.
Token type | Origin | Data access | Usage |
|---|---|---|---|
| Generated by the Authentication service | Restricted to the authenticated player | The |
| Generated by Cloud Code | Allows cross-player data access | The |
Any configured Access Control rules affect the .
accessTokenBelow is an example of how to use the to call the Economy SDK to get the player's inventory.
accessTokenJavaScript
// 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 , the same script would look like this:
serviceTokenJavaScript
// 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 object, containing each parameter name as a key, and its type as a value.
paramsFor example:
JavaScript
module.exports.params = { echo: "Boolean" };
Alternatively, if you want to specify that a parameter is required, specify an object containing both the and properties.
typerequiredJavaScript
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 or keywords.
importrequireRefer 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
stringmodule.exports = async () => { return "hello world";};booleanmodule.exports = async () => { return true;};numbermodule.exports = async () => { return 3.14;};objectmodule.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)" ] } ]}