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
While this script doesn’t actually do anything, it shows the context object and asynchronous nature of the script function.module.exports = async ({ params, context, logger }) => { // this script does nothing};
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
Refer to the Logging documentation for more information.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 :(");};
Token authentication
TheaccessTokenserviceTokencontextToken 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 |
accessTokenaccessTokenJavaScript
If you want to use// 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;};
serviceTokenJavaScript
Refer to Service and access tokens for an in-depth explanation of the differences between the two tokens.// 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;};
Script parameters
Script parameters can be defined outside or inside the script body.In-script parameters
In-script parameters can be added by exporting theparams
For example:
JavaScript
Alternatively, if you'd like to specify that a parameter is required, you may specify an object containing both themodule.exports.params = { echo: "Boolean" };
typerequiredJavaScript
By default, parameters are not required. Both formats can be combined as desired:module.exports = async ({ params, context, logger }) => { return { value: params["aParam"], };};module.exports.params = { aParam: { type: "String", required: true } };
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 theimportrequireJavaScript
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, };};
{ "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
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.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; }};
{ "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)" ] } ]}