# 일일 보상

> Implement a daily rewards system that brings players back every day.

일일 보상은 모든 장르의 게임에서 점점 더 많이 사용되는 게임 메카닉이 되고 있으며, 특히 F2P 타이틀에서 인기가 많습니다. 일일 보상은 단순한 꾸미기 스킨과 아바타부터 인벤토리 아이템과 게임 내 재화에 이르기까지 다양한 아이템을 제공함으로써 플레이어가 매일 게임에 접속하도록 유도하는 매력적인 수단입니다.

Cloud Code는 다른 Unity 서비스와 쉽게 연동할 수 있어 일일 보상 로직을 구축하는 데 탁월한 옵션입니다. [Economy](/economy.md)에서 아이템과 통화를, [Remote Config](/remote-config.md)에서 확률을 각각 정의한 다음 Cloud Code에서 기본 알고리즘을 작성할 수 있습니다. 이렇게 하면 게임 클라이언트를 업데이트하지 않고도 일일 보상 로직을 즉시 변경할 수 있습니다.

예를 들어 다음과 같은 변경 사항을 적용할 수 있습니다.

* 일부 아이템의 지급 확률 감소
* 보상으로 지급되는 아이템 수 증가
* 유효성 검사를 추가하여 플레이어가 희귀 아이템을 중복으로 받지 않도록 방지
* Remote Config 캠페인을 통해 아이템 및 확률 변경

## 설정##setup

다음 예시는 Economy에서 펫 장난감 여러 개를 인벤토리 아이템으로 정의하는 방법을 보여 줍니다. Remote Config에서 일일 보상 파라미터를 정의한 다음 Cloud Code 스크립트와 연동할 수 있습니다.

### Economy##economy

이 게임 메카닉을 만드는 첫 번째 단계는 [Economy](/economy/item-types.md)에서 보상을 인벤토리 아이템 유형으로 정의하는 것입니다.

[Unity Dashboard](https://cloud.unity.com/)로 이동하여 왼쪽 네비게이션 바에서 **Economy**를 선택합니다.

Economy에서 다음 인벤토리 아이템을 만듭니다.

1. `TOY_CHOCO` ID가 있는 `Choco` 인벤토리 아이템
2. `TOY_JOJO` ID가 있는 `Jojo` 인벤토리 아이템
3. `TOY_KIKI` ID가 있는 `Kiki` 인벤토리 아이템


**Frame:**
![](/api/media?file=/cloud-code/media/images/economy-toys.png)

> **Note:**
>
> Cloud Code 스크립트에서 Economy 구성을 사용하려면 먼저 퍼블리시해야 합니다.

### Remote Config##remote-config

Remote Config를 사용하여 `DAILY_REWARDS_VARIABLES` 키 아래에 일일 보상 파라미터를 커스텀 JSON 값으로 정의할 수 있습니다.

*JSON*

```js
{
  "rewards": [
    {"id": "TOY_CHOCO", "probability": 10},
    {"id": "TOY_JOJO", "probability": 65},
    {"id": "TOY_KIKI", "probability": 80}
  ]
}
```

> **Note:**
>
> Cloud Code 스크립트에서 사용할 수 있도록 키-값 페어를 저장합니다.

## 일일 보상 스크립트##daily-rewards-script

구성이 완료되면 가중치가 적용된 간단한 무작위 알고리즘을 통해 Economy 및 Remote Config와 상호 작용하는 간단한 스크립트를 작성하여 플레이어에게 무작위 장난감을 선물할 수 있습니다.

*JavaScript*

```js
/*
 * Retrieve the daily rewards configuration from Remote Config
 * Select a random item from the configuration and gift the item to the player in Economy
 * Note: the Economy configuration needs to be published and Remote Config values need to be saved before they are available in Cloud Code scripts.
 *
 */

const { InventoryApi } = require('@unity-services/economy-2.4');
const { SettingsApi } = require('@unity-services/remote-config-1.1');
const _ = require('lodash-4.17');

const REMOTE_CONFIG_VARIABLES_KEY = 'DAILY_REWARDS_VARIABLES';

module.exports = async ({ context }) => {
    // Initialize the Economy and Remote Config API clients using the player credentials
    const { projectId, environmentId, playerId } = context;
    const inventoryApi = new InventoryApi(context);
    const remoteConfigApi = new SettingsApi(context);

    // Fetch the daily rewards configuration from Remote Config
    const remoteConfigResponse = await remoteConfigApi.assignSettingsGet(
        projectId,
        environmentId,
        'settings',
        [REMOTE_CONFIG_VARIABLES_KEY]
    );

    // Extract the daily rewards from the response
    const dailyRewardsConfig = remoteConfigResponse?.data?.configs?.settings?.[REMOTE_CONFIG_VARIABLES_KEY];
    const dailyRewards = dailyRewardsConfig?.rewards;

    // Pick a random reward from the options
    const reward = selectRandomReward(dailyRewards);

    // Gift the reward to the player
    await inventoryApi.addInventoryItem({ projectId, playerId, addInventoryRequest: { inventoryItemId: reward.id } });
    return { reward: reward.id };
};

// Select a random item based on the probability of each option
function selectRandomReward(options) {
    if (!_.isArray(options)) {
        throw Error('Invalid daily reward options');
    }

    let sumOfProbabilities = 0;
    options.forEach((option) => {
        sumOfProbabilities += option.probability;
    });

    let random = _.random(0, sumOfProbabilities);

    for (let i = 0; i < options.length; i++) {
        if (random < options[i].probability) {
            return options[i];
        }
        random -= options[i].probability;
    }

    throw Error('Unable to select a daily reward');
}
```
