Integration with other Unity services

Use Cloud Code with other Unity services to extend its capabilities.

Cloud Code allows integration with the following Unity services:

  • Cloud Save
  • Economy
  • Remote Config
  • Vivox
  • Lobby

See Cloud Code Services SDKs for detailed SDK documentation and changelogs for each service.

Integrating with these other services requires you to import the necessary libraries in your script. This section shows how you can get started with integrating other Unity services with Cloud Code. For more examples of using integrations together, see Use cases and Advanced use cases.

The return objects of methods of other Unity services contain additional information about the request, for example, the headers of the request or the response. To access the payload of a response, reference the data property of the object.

Using the Cloud Save SDK

You can use the Cloud Save service to save persistent player data (such as game progress) from a game to the cloud, making it independent of player devices. Because it's cloud-based, you can access the player data anywhere and across devices, mitigating data loss when a player changes devices or re-installs a game. See Cloud Code Services SDK — Cloud Save. See Cloud Save SDK changelog.

Cloud Save integration allows you to save data from a Cloud Code script.

The following is an example of how you could use Cloud Save within a Cloud Code script.

Copy
JavaScript
const _ = require("lodash-4.17");
const {
  DataApi
} = require("@unity-services/cloud-save-1.2");

const NUMBER_OF_SIDES = 6;

module.exports = async ({ params, context, logger }) => {
  const {
projectId,
playerId
  } = context;
 
  const api = new DataApi(context);
 
  const roll = rollDice(NUMBER_OF_SIDES);

  if (roll > NUMBER_OF_SIDES) {
    // Log an error message with information about the exception
logger.error("The roll is greater than the number of sides: " + roll);
    // Return an error back to the client
    throw Error("Unable to roll dice!");
  }
 
  // Return a JSON result to the client
  const result = {
sides: NUMBER_OF_SIDES,
roll: roll,
  };
 
  const setResult = await api.setItem(projectId, playerId, {
key: "DIE_ROLL",
value: result
  });
  logger.debug(JSON.stringify(setResult.data));

  return result;
};

// Function outside of the script wrapper
function rollDice(sides) {
  return _.random(1, sides);
}

Cross-player data

By passing another player’s ID to the Cloud Save SDK, you can read and write their Cloud Save data, allowing asynchronous multiplayer interactions. This would not be possible from within the client, where users are only permitted to access their own data.

The following example shows how to provide a commendation to another player within the same Lobby. The sample code demonstrates accessing and modifying another player's data stored in Cloud Save. The otherPlayerId parameter identifies the other player.

const { DataApi } = require('@unity-services/cloud-save-1.2');
 
module.exports = async ({ params, context, logger }) => {
  const { projectId } = context;
  const { otherPlayerId } = params;
 
  // Initialize the cloud save API client
  const cloudSaveAPI = new DataApi(context);
 
  // Access the save data for the specified player
  const otherPlayerSave = await cloudSaveAPI.getItems(
    projectId,
    otherPlayerId, // or any other player ID
    "likes" // Cloud Code key
  );
 
  // Assume that player's likes is 0 if the key doesn't exist
  const otherPlayerLikes = otherPlayerSave.data.results[0]?.value || 0;
 
  // Update the data for the specified player
  cloudSaveAPI.setItem(
    projectId,
    otherPlayerId, { key: "likes", value: otherPlayerLikes + 1 }
  )
};
JavaScript

Requests originating from your players should be considered untrusted input, so be careful when accepting another player’s ID as a parameter, as in the above example. If your game has restrictions on when or how players can interact with each other (for example, if your players can opt out of multiplayer), then you need to check for those prerequisites within the script.

Using the Economy SDK

The Economy service allows you to create, manage, and publish an economy system in your game using the following resources:

  • Currencies allow a user to have an in-game balance of one or more currencies/denominations.
  • Inventory items represent a definition of a resource that is created as part of the configuration. A player can own instances of inventory items (for example, multiple copies of the same swords, shields, hats) and, unlike currencies, each instance can have its own properties.
  • A player can purchase in-game currency and inventory items with different in-game currency and inventory items (virtual purchases), or by using real money via a digital storefront.

With Cloud Code, you can manipulate currencies, inventory items, and purchases directly from a script. See Cloud Code Services SDK — Economy. See Economy SDK changelog.

Economy SDK player inventory

Copy
JavaScript
// Player inventory

const { InventoryApi } = require("@unity-services/economy-2.3");

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;
}

Economy SDK player currencies

You must first have a published currency in the Economy service for the following script to work. Then, create a script with a required parameter called currencyId, or add this parameter to an existing script.

Copy
JavaScript
// Set / Get / Increment / Decrement player balance for a currency

const { CurrenciesApi } = require("@unity-services/economy-2.3");

module.exports = async ({ params, context, logger }) => {
  const { projectId, playerId } = context;
  const { currencyId } = params;
  const currencies = new CurrenciesApi(context);
  const setBalance = await currencies.setPlayerCurrencyBalance({ projectId, playerId, currencyId, currencyBalanceRequest: { balance: 100 } });
  const decrement = await currencies.decrementPlayerCurrencyBalance({ projectId, playerId, currencyId, currencyModifyBalanceRequest: { amount: 50 } });
  const increment = await currencies.incrementPlayerCurrencyBalance({ projectId, playerId, currencyId, currencyModifyBalanceRequest: { amount: 10 } });
  const result = await currencies.getPlayerCurrencies({ projectId, playerId });
  return result.data;
}

Using Economy SDK virtual purchases

Before using the following script, you must create a virtual purchase in Economy service, and publish your new configuration. The script takes purchaseId as a string type parameter. You can find the purchaseId when you create your purchase in the Economy tab on the Unity Dashboard.

Copy

JavaScript

const { PurchasesApi, InventoryApi } = require("@unity-services/economy-2.3");

module.exports = async ({ params, context, logger }) => {
  const { projectId, playerId } = context;
  const { purchaseId } = params;
  const inventory = new InventoryApi(context);
  const purchases = new PurchasesApi(context);

  const makeVirtualPurchaseResult = await purchases.makeVirtualPurchase({ projectId, playerId, playerPurchaseVirtualRequest: { id: purchaseId } });

  const getPlayerInventoryResult = await inventory.getPlayerInventory({ projectId, playerId });

  await inventory.deleteInventoryItem({ projectId, playerId, playersInventoryItemId: makeVirtualPurchaseResult.data.rewards.inventory[0].playersInventoryItemIds[0], inventoryDeleteRequest: {} });

  return {
    makeVirtualPurchaseResult: makeVirtualPurchaseResult.data,
    getPlayerInventoryResult: getPlayerInventoryResult.data
  };
}
If you published your purchase configuration but the script is not working, you might need to refresh your playerId to get the new player configuration loaded directly from Remote Config.

Using Economy with Game Overrides

See Economy Game Overrides with Cloud Code.

Using the Remote Config SDK

Remote Config is a cloud service you can use to tune your game design without deploying new versions of your application. It consists of a set of namespaced key-value parameters, and you can optionally define a set of values that override or add to these parameters. See Cloud Code Services SDK — Remote Config. See Remote Config SDK changelog.

You can modify Remote Config settings from a Cloud Code script:

Copy
JavaScript
const { SettingsApi } = require("@unity-services/remote-config-1.1");

module.exports = async ({context, logger}) => {
  const { projectId, playerId } = context;
  const remoteConfig = new SettingsApi(context);
  const result = await remoteConfig.assignSettings({ projectId, "userId": playerId, "attributes": {"unity": {},"app": {},"user": {}}});
  return result.data;
}

Using the Vivox SDK

Vivox provides voice and text-based communication services for your game. Cloud Code allows you to generate a Vivox Token, which lets game clients to safely access Vivox service actions. See Cloud Code Services SDK — Vivox. See Vivox SDK changelog.

Copy
JavaScript
const { TokenApi } = require("@unity-services/vivox-0.1");

const VIVOX_KEY = "EXAMPLE_KEY";

module.exports = async ({ params, context, logger}) => {
  const { projectId, playerId } = context;
  
  const payload = {
    iss: "blindmelon-AppName-dev",
    exp: Date.now() + 90,
    vxa: "join",
    vxi: 1,
    f: "sip:.blindmelon-AppName-dev.beef.@tla.vivox.com",
    t: "sip:confctl-g-blindmelon-AppName-dev.testchannel@tla.vivox.com",
    sub: "sip:.blindmelon-AppName-dev.jerky.@tla.vivox.com" // optional
  };
  
  return TokenApi.generateVivoxToken(VIVOX_KEY, payload);
};

Using the Lobby SDK

Lobby allows your players to connect before or during a game session. Players create public lobbies using simple game attributes that other players can then search, discover, and join. Invite-only lobbies also allow players to create private spaces for select participants only. See Cloud Code Services SDK — Lobby. See Lobby SDK changelog.

The following is an example of how you can create, update and heartbeat a lobby using a Cloud Code script. See Wikipedia for a description of heartbeat.

Copy

JavaScript

const { LobbyApi, DataObjectVisibilityEnum } = require("@unity-services/lobby-1.1");
 
module.exports = async ({params,context,logger}) => {
    const lobbyApi = new LobbyApi(context);
   
    // Create a private lobby.
    const {data: lobby} = await lobbyApi.createLobby(
        {
            name: "my new lobby name",
            maxPlayers: 4,
            isPrivate: true,
        }
    );
   
    // Heartbeat the lobby to keep it active.
    const heartbeatResponse = await lobbyApi.heartbeat(lobby.id);
   
    // Update the lobby's name and get the updated lobby.
    const updateResponse = await lobbyApi.updateLobby(lobby.id, {name: "my updated lobby name"});
   
    // Get and return the lobby.
    const getResponse = await lobbyApi.getLobby(lobby.id);
 
    return getResponse.data;
};