> ## Documentation Index
> Fetch the complete documentation index at: https://devdocs.xbox.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Jogo de criação, parte 3 - Codificação

> Parte 3 do tutorial do jogo de criação do PlayFab Economy V2: escreva código C# que chama a API do Economy V2 para gerenciar inventários, receitas e itens criados.

# Parte 3 - Codificação + Exemplos

Agora que você tem seu ambiente pronto e está familiarizado com o Game Manager, podemos começar a codificar nosso jogo.

## Pré-requisitos

1. [Parte 1 - Configuração do ambiente](/pt-BR/services/playfab/economy-monetization/economy-v2/tutorials/craftingGame/crafting-game-environment)
2. [Parte 2 - Usando o Game Manager](/pt-BR/services/playfab/economy-monetization/economy-v2/tutorials/craftingGame/crafting-game-game-manager)

## Etapa 1 - Definir as configurações do ambiente

A primeira coisa que recomendamos que você faça ao começar a codificar é definir as configurações do seu ambiente. Dessa forma, você pode ter certeza de que cada chamada feita terá um vínculo com seu título e usará sua Chave Secreta de Desenvolvedor específica.

Para concluir essa etapa, você pode especificar em qualquer lugar do seu código (de preferência em algum lugar fácil de encontrar) as variáveis TitleId e DeveloperSecretKey e atribuir seus valores a elas.

Faça isso adicionando duas linhas de código separadas, da seguinte forma:

```csharp theme={null}
PlayFabSettings.staticSettings.TitleId = "{Your Title ID}";
PlayFabSettings.staticSettings.DeveloperSecretKey = "{Your Developer Secret Key}";
```

## Etapa 2 - Autenticar-se

Depois de configurar o ambiente, instalar e configurar o pacote NuGet do PlayFab no seu projeto e criar seu Estúdio e seu Título, podemos começar a codificar a autenticação.

<Note>
  Há várias maneiras pelas quais um usuário pode ser autenticado. Neste exemplo, vamos usar o método **LoginWithCustomId**. Há outras maneiras de se autenticar, incluindo algumas específicas de plataforma. Para obter mais informações, acesse [Noções básicas de logon](/pt-BR/services/playfab/identity/player-identity/login/login-basics-best-practices).
</Note>

A seguir está um código de exemplo feito em C# no qual autenticamos um usuário usando o **LoginWithCustomID**, que é classificado como uma entrada anônima. Antes de chamar a API para autenticar, devemos primeiro declarar uma variável global na qual armazenamos a **EntityKey** gerada como parte do processo de entrada.

A **EntityKey** é usada para fazer qualquer tipo de chamada à API e é o que vincula cada solicitação e resposta ao usuário conectado.

A declaração da variável global EntityKey é a seguinte:

```csharp theme={null}
private static PlayFab.ClientModels.EntityKey entityKey;
```

***

Em seguida, a lógica para autenticar um usuário é:

### SDK do C\#

```csharp theme={null}
var request = new LoginWithCustomIDRequest { CustomId = username };
var loginTask = PlayFabClientAPI.LoginWithCustomIDAsync(request);
entityKey = loginTask.Result.Result.EntityToken.Entity;
```

### API

```json theme={null}
{
  "CustomId": "{{Username}}",
  "CreateAccount": false,
  "TitleId": "{{TitleId}}"
}
```

***

O código acima procura jogadores existentes vinculados ao título do seu jogo. Mas ele falha se não houver nenhum usuário com um nome de usuário correspondente. Para contornar isso, podemos adicionar um parâmetro "CreateAccount = true" ao corpo da solicitação. Isso faz com que o PlayFab crie um novo jogador se não houver correspondência para o que o usuário estiver enviando como nome de usuário. O resultado seria um código como este:

### SDK do C\#

```csharp theme={null}
var request = new LoginWithCustomIDRequest { CustomId = username, CreateAccount = true };
var loginTask = PlayFabClientAPI.LoginWithCustomIDAsync(request);
entityKey = loginTask.Result.Result.EntityToken.Entity;
```

### API

````json theme={null}
{
  "CustomId": "{{Username}}",
  "CreateAccount": true,
  "TitleId": "{{TitleId}}"
}
```

---

Após uma entrada bem-sucedida, a API retornará alguns conjuntos de dados, como o **SessionTicket**, o **PlayFab ID** do usuário e o **EntityToken**. Eles podem ser vistos na resposta direta da API, detalhada abaixo.

```json
{
    "code": 200,
    "status": "OK",
    "data": {
        "SessionTicket": "{{SessionTicket}}",
        "PlayFabId": "{{PlayFabID}}",
        "NewlyCreated": false,
        "SettingsForUser": {
            "NeedsAttribution": false,
            "GatherDeviceInfo": true,
            "GatherFocusInfo": true
        },
        "LastLoginTime": "2023-08-01T17:09:54.508Z",
        "EntityToken": {
            "EntityToken": "{{EntityToken}}",
            "TokenExpiration": "2023-08-04T21:20:35Z",
            "Entity": {
                "Id": "{{Player ID}}",
                "Type": "title_player_account",
                "TypeString": "title_player_account"
            }
        },
        "TreatmentAssignment": {
            "Variants": [],
            "Variables": []
        }
    }
}
````

***

Quando você receber o `"code":200` retornado pela API ou obtiver informações no `loginTask` do exemplo em C# acima, você estará autenticado e pronto para seguir para a próxima etapa!

## Etapa 3 - Configurar seu inventário inicial

Agora que você entrou com um jogador válido (ou criou um novo jogador), sua primeira etapa deve ser definir o inventário inicial desse jogador. Para isso, usaremos a chamada de API [ExecuteInventoryOperations](https://learn.microsoft.com/en-us/rest/api/playfab/economy/inventory/execute-inventory-operations).

<Note>
  A chamada ExecuteInventoryOperations nos permite executar várias [InventoryOperations](https://learn.microsoft.com/en-us/rest/api/playfab/economy/inventory/execute-inventory-operations) em lote no inventário do jogador. Os tipos de operações compatíveis são: - Add - Delete - Purchase - Subtract - Transfer - Update
</Note>

Para este exemplo, adicionaremos os itens correspondentes ao nosso jogo. São três instâncias de Pedra, uma instância de Creme e uma instância de Ouro (isso pressupõe que você criou mais itens; caso contrário, faça isso antes de continuar). Mas, em vez de simplesmente usar a operação **Add**, usamos a operação **Purchase** e compramos as instâncias necessárias gratuitamente.

<Note>
  Para que esta etapa funcione, você deve primeiro ter criado os itens no seu título no Game Manager.
</Note>

Os snippets abaixo mostrarão como fazer essas chamadas em massa tanto em C# quanto usando a API do PlayFab.

### SDK do C\#

Neste exemplo em C#, você pode ver que começamos definindo o purchasePrice como um valor padrão para todas as transações, porque faremos com que todas tenham preço 0.

Qualquer item pode ter vários preços, por isso a variável `purchasePrice` é do tipo `List<PurchasePriceAmount>`.

O próximo aspecto que você pode notar é que a solicitação recebe, além da lista de `InventoryOperation`, uma Entity. Para isso, criaremos uma nova usando os valores que obtivemos na entrada feita anteriormente.

Por fim, cada `InventoryOperation` recebe um valor `Purchase`, embora pudesse ser qualquer uma das disponíveis na chamada **ExecuteInventoryOperations** (Add, Delete, Purchase, Subtract, Transfer e Update). Neste caso, usamos o identificador `Purchase`, portanto precisamos de um `new PurchaseInventoryItemsOperation`.

Você também precisa deixar claro qual é o item que deseja comprar. Você faz isso usando o `InventoryItemReference`, que recebe o ID do item como único parâmetro.

Em nosso código, temos um método chamado **SearchItem(\{itemName})**, mas você pode facilmente substituí-lo por uma cadeia de caracteres que represente o ID do item. Certifique-se de associar o nome (ou ID) de cada item à quantidade correspondente.

```csharp theme={null}
var purchasePrice = new List<PurchasePriceAmount> { new PurchasePriceAmount { ItemId = freeItemId, Amount = 0 } };
var request = new ExecuteInventoryOperationsRequest 
{ 
    Entity = new PlayFab.EconomyModels.EntityKey { Id = entityKey.Id, Type = entityKey.Type },
    Operations = new List<InventoryOperation> {
        new InventoryOperation
        {
            Purchase = new PurchaseInventoryItemsOperation { 
                Item = new InventoryItemReference {AlternateId = new AlternateId { Type = "FriendlyId", Value = "Stone" } }, 
                Amount = 3, 
                PriceAmounts = purchasePrice
            }
        },
        new InventoryOperation
        {
            Purchase = new PurchaseInventoryItemsOperation {
                Item = new InventoryItemReference { AlternateId = new AlternateId { Type = "FriendlyId", Value = "Gold" } },
                Amount = 1,
                PriceAmounts = purchasePrice
            }
        },``
        new InventoryOperation
        {
            Purchase = new PurchaseInventoryItemsOperation {
                Item = new InventoryItemReference {AlternateId = new AlternateId { Type = "FriendlyId", Value = "Cream" }},
                Amount = 1,
                PriceAmounts = purchasePrice
            }
        }
    }
};
await PlayFabEconomyAPI.ExecuteInventoryOperationsAsync(request);
```

No código acima, para usar com êxito `AlternateId` e `FriendlyId` no seu código, seus itens devem ter esses valores configurados no Game Manager. Para isso, sugiro que você consulte a [Parte 2 - Usando o Game Manager](/pt-BR/services/playfab/economy-monetization/economy-v2/tutorials/craftingGame/crafting-game-game-manager), onde detalhamos as etapas que você deve seguir.

### API

Chame o ponto de extremidade da API **ExecuteInventoryOperations** com o corpo de solicitação mostrado abaixo, substituindo os IDs pelos correspondentes. Observe que `Operations` é uma matriz; você pode preenchê-la com vários tipos de operações simultaneamente.

É importante entender que, para cada chamada de API que você fizer, deverá definir um cabeçalho `X-EntityToken` com o **EntityToken** específico da sua sessão ativa ou do usuário conectado. Em outras palavras, antes de fazer qualquer chamada de API, você deve primeiro chamar **LoginWithCustomID** (neste exemplo) e, da mensagem de retorno, obter o **EntityToken** a ser usado como cabeçalho em todas as chamadas de API.

```json theme={null}
{
  "Operations": [
    {
      "Purchase": {
            "Item": {
                "Id": {Stone ID}
            },
            "Amount": 3,
            "PriceAmounts": [
                {
                "ItemId": {Free Item ID},
                "Amount": 0
                }
            ]
        }
    },
    {
      "Purchase": {
            "Item": {
                "Id": {Gold ID}
            },
            "Amount": 1,
            "PriceAmounts": [
                {
                "ItemId": {Free Item ID},
                "Amount": 0
                }
            ]
        }
    },
    {
      "Purchase": {
            "Item": {
                "Id": {Cream ID}
            },
            "Amount": 1,
            "PriceAmounts": [
                {
                "ItemId": {Free Item ID},
                "Amount": 0
                }
            ]
        }
    }
  ]
}
```

O próximo JSON é um exemplo de mensagem de retorno bem-sucedida após fazer a chamada acima. Você verá três IDs de transação distintos sendo retornados porque os IDs são atribuídos por modificação, embora isso não signifique que haja três transações separadas. Pelo contrário, ela é tratada como uma única transação, mas com três modificações; por isso, retornamos apenas um único sucesso ou falha para toda a transação, independentemente do número de modificações.

```json theme={null}
{
    "code": 200,
    "status": "OK",
    "data": {
        "IdempotencyId": {Idempotency ID},
        "TransactionIds": [
            "200",
            "201",
            "202"
        ],
        "ETag": "1/MjAy"
    }
}
```

***

## Etapa 4 - Criar um pacote

Os pacotes permitem agrupar vários itens em um único item. Para obter mais informações sobre pacotes, consulte nossa **Documentação de pacotes** neste [link](/pt-BR/services/playfab/economy-monetization/economy-v2/catalog/bundles).

Em nosso exemplo, usaremos um **Bundle** para agrupar os itens retornados pela **Cozinha**, o que nos ajuda a manter o item **Geladeira**. A ideia por trás da geladeira é ser um item não consumível ao comprar um sorvete, embora a geladeira seja um dos materiais necessários.

Uma visão geral de alto nível de como isso funciona é a seguinte. Imagine um jogador que tem um Creme e uma Geladeira no inventário. Ao acessar a loja Cozinha, esse jogador deve usar esses dois itens para comprar/fazer um Sorvete. Como a Geladeira não é consumível, o resultado esperado é um inventário com um Sorvete e uma Geladeira, tendo consumido apenas o item Creme.

A forma como lidamos com isso nos bastidores é usando um pacote com preço de uma Geladeira e um Creme, cujos itens retornados são um Sorvete e uma Geladeira. Isso significa que a Geladeira no inventário do jogador será consumida, mas a mesma transação que a consome retorna outra, dando ao jogador a impressão de que a Geladeira está sempre no inventário quando, na realidade, as instâncias da Geladeira são diferentes, mas invisíveis para o jogador.

Para criar um pacote, você deve ir até a seção **Economy** do seu título, como fez ao criar um novo item. Haverá uma guia chamada **Bundles** ao lado de **Items**, **Currency** e outras. Depois de selecioná-la, um botão azul aparece no canto superior direito da tela com o texto **New bundle**.

Isso exibirá um formulário semelhante ao de criação de um novo item, com a principal diferença de que, se você rolar para baixo, encontrará uma seção intitulada **Items**. Aqui você pode adicionar os itens que deseja que o pacote contenha, que serão transferidos para o inventário do jogador quando comprado.

Depois de clicar no botão **Add**, uma lista pesquisável de todos os itens do seu catálogo será exibida; aqui você pode selecionar os itens que deseja incluir no pacote. Assim que tiver selecionado e adicionado seus itens, você pode prosseguir para **Save and publish**, e seu pacote estará ativo e selecionável nas lojas como preço de compra.

## Etapa 5 - Criar uma loja

Seguindo nosso exemplo de jogo de criação, o jogador precisa comprar itens de uma loja. Haverá três lojas distintas (neste caso, locais): a **Máquina Científica**, o **Motor Alquímico** e a **Cozinha**.

Vamos nos concentrar na **Cozinha**. Aqui, os jogadores podem comprar um **Sorvete** (novo item que deve ser criado) pelo preço de **1 Creme** e **1 Geladeira** (novo item que deve ser criado). Esse caso específico foi escolhido porque mostra como os **Bundles** funcionam em conjunto com lojas e transações.

As lojas só podem ser criadas no [Game Manager](https://developer.playfab.com), indo até a seção **Economy** na barra de navegação à esquerda; em seguida, entre as diferentes opções de guias, escolha **Stores** e selecione o botão azul **New store**.

Isso exibe um formulário semelhante ao usado ao criar novos itens, no qual os únicos campos obrigatórios são a Data de Início e o Título que você deseja dar à sua loja. Rolando para baixo, você

## Etapa 6 - Adicionar um pacote a uma loja

Agora que você criou e publicou seu pacote e sua loja, pode adicionar o pacote como um item retornável na sua loja. Para isso, entre na sua loja, role para baixo até ver o título **Items** e selecione o botão **Add**.

Isso exibe a lista de itens do Catálogo. No lado esquerdo da barra de pesquisa, haverá um menu suspenso preenchido com os diferentes tipos de objetos, como **Items**, **UGC Items**, **Bundles** e **Subscription**. Se você escolher **Bundles**, a lista será filtrada para refletir apenas itens do tipo pacote; aqui você deverá ver o pacote que criou anteriormente. Depois de selecionar o botão **Add** ao lado do nome do pacote e, em seguida, o botão **Add** no final da janela, o pacote será adicionado como um possível item de transação para essa loja específica.

Há uma última etapa antes de continuar: definir um preço para seu pacote. Esse preço funciona como o de qualquer outro item, no sentido de que exige que o jogador tenha no inventário os itens de preço necessários antes de aceitar a compra. Para definir um preço, você pode selecionar o botão **Add new price** à direita do seu pacote e, na lista de itens, selecionar os itens que deseja que sejam o preço. Em nosso caso, queremos que o preço seja **1 Geladeira** e **1 Creme**.

Agora que seu pacote foi adicionado à sua loja e teve o preço definido adequadamente, podemos passar para a próxima etapa.

## Etapa 7 - Comprar um pacote

Depois que seu pacote e sua loja forem criados e seu pacote estiver vinculado à sua loja, você poderá comprar esse pacote e obter os itens resultantes no seu inventário.

Para comprar um pacote, da perspectiva de um jogador, você pode usar a **PurchaseInventoryItems** da API do PlayFab, que funciona não apenas com pacotes, mas também com itens individuais.

### API

No caso a seguir, queremos comprar **1 pacote** com preço de **1 Geladeira** e **1 Creme**. Vamos usar as propriedades de matriz de **PriceAmount** para definir mais de 1 item como preço. Apenas certifique-se de ter atribuído um **FriendlyId** ao seu pacote.

```json theme={null}
{
  "Item": {
    "AlternateId": {
        "Type": "FriendlyId",
        "Value": "Ice Cream and Ice Box"
    }
  },
  "Amount": 1,
  "PriceAmounts": [
    {
        "ItemId": "0d2ab329-2fc5-4ae1-9e3c-19f9fc9bbf86",
        "Amount": 1
    },
    {
        "ItemId": "e5276289-f839-4bde-acce-309ea7959e45",
        "Amount": 1
    }
  ],
  "DeleteEmptyStacks": true,
  "StoreId": "f116f1d4-64f9-4be7-9660-a3c1f021100b"
}
```

O próximo snippet é o retorno esperado após uma chamada de API bem-sucedida.

```json theme={null}
{
    "code": 200,
    "status": "OK",
    "data": {
        "ETag": "1/MjEz",
        "IdempotencyId": "d710508f-defc-4382-bbd1-a3576417b3f7",
        "TransactionIds": [
            "212",
            "213"
        ]
    }
}
```

<Note>
  Você notará na resposta que recebe 2 `TransactionIds` diferentes. Isso ocorre porque a propriedade `DeleteEmptyStacks` é tratada como uma transação adicional. No exemplo anterior, a transação 212 corresponde à compra do pacote, e a transação 213 à exclusão da pilha vazia de Creme (supondo que você tivesse apenas 1 Creme no inventário).
</Note>

### SDK do C\#

Quanto à aparência do código C#, abaixo você encontra um snippet do nosso exemplo.

```csharp theme={null}
var purchaseRequest = new PurchaseInventoryItemsRequest
{
    Entity = new PlayFab.EconomyModels.EntityKey { Id = entityKey.Id, Type = entityKey.Type },
    Item = new InventoryItemReference { Id = "34167d9f-c8d7-4e17-9a87-b6af1fc389b2" }, //bundle id
    Amount = 1,
    PriceAmounts = new List<PurchasePriceAmount>() { 
        new PurchasePriceAmount { 
            ItemId = "e5276289-f839-4bde-acce-309ea7959e45", 
            Amount = 1 
        }, //cream id and quantity
        new PurchasePriceAmount { 
            ItemId =  "0d2ab329-2fc5-4ae1-9e3c-19f9fc9bbf86", 
            Amount = 1 
        } //icebox id and quantity
    }, 
    StoreId = "f116f1d4-64f9-4be7-9660-a3c1f021100b",
    DeleteEmptyStacks = true
};

var result = await PlayFabEconomyAPI.PurchaseInventoryItemsAsync(purchaseRequest);
```

***

## Consulte também

* [Visão geral do Economy v2](/pt-BR/services/playfab/economy-monetization/economy-v2/overview)
* [Configurações](/pt-BR/services/playfab/economy-monetization/economy-v2/settings)
* [Lojas do Economy v2](/pt-BR/services/playfab/economy-monetization/economy-v2/catalog/stores#creating-a-store)


## Related topics

- [Jogo de criação, parte 1 - Configuração](/pt-BR/services/playfab/economy-monetization/economy-v2/tutorials/craftingGame/crafting-game-environment.md)
- [Jogo de criação, parte 2 - Game Manager](/pt-BR/services/playfab/economy-monetization/economy-v2/tutorials/craftingGame/crafting-game-game-manager.md)
- [Jogo de criação - Contexto](/pt-BR/services/playfab/economy-monetization/economy-v2/tutorials/craftingGame/game-context.md)
- [Criação de perfil de sustentabilidade com o PIX](/pt-BR/build/game-principles/sustainability/sustainability-pix-guide.md)
- [Usando o PlayFab Multiplayer Servers para hospedar jogos multijogador](/pt-BR/services/playfab/multiplayer/servers/using-playfab-servers-to-host-games.md)
