# Player inventory

> Use the SDK to manage player inventory items including adding, updating, and deleting items.

The methods in the `PlayerInventory` namespace allow you to retrieve and update the player's inventory instances.

These methods will return inventory data for the currently signed in player from the Authentication SDK.

> **Note:**
>
> All the methods in this namespace can throw an [EconomyException](./exceptions#economyexception).

## GetInventoryAsync##getinventory

Retrieves the current inventory item instances associated with the currently signed in player.

This method optionally takes a `GetInventoryOptions` object. This can be used to set the number of items per fetch and for filtering.

You can filter the inventory items using a list of configuration item IDs and/or `PlayersInventoryItem` IDs. If you use these filter options then only players items that have the specified configuration item IDs and `PlayersInventoryItem` IDs will be returned.

The following sample code retrieves the first five items for the current user, and then retrieves the next five.

```cs title="C#"
// Optional, defaults to 20
GetInventoryOptions options = new GetInventoryOptions
{
    ItemsPerFetch = 5
};

GetInventoryResult inventoryResult = await EconomyService.Instance.PlayerInventory.GetInventoryAsync(options);
List<PlayersInventoryItem> firstFiveItems = inventoryResult.PlayersInventoryItems;
// do something with your items

if (inventoryResult.HasNext) {
    inventoryResult = await inventoryResult.GetNextAsync(5);
    List<PlayersInventoryItem> nextFiveItems = inventoryResult.PlayersInventoryItems;
    // do something with your items
}
```

This next sample code retrieves only the player's `SWORD` items.

```cs title="C#"
GetInventoryOptions options = new GetInventoryOptions
{
    InventoryItemIds = new List<string>() { "SWORD" }
};

GetInventoryResult inventoryResult = await EconomyService.Instance.PlayerInventory.GetInventoryAsync(options);

List<PlayersInventoryItem> listOfItems = inventoryResult.PlayersInventoryItems;

// ... etc
```

These methods return a `GetInventoryResult`.

### GetInventoryOptions

The options object for a `GetInventoryAsync` call. It has the following fields:

* `PlayersInventoryItemIds`: A list of strings. Defaults to `null`. The `PlayersInventoryItem` IDs of the items in the player's inventory that you want to retrieve.
* `InventoryItemIds`: A list of strings. Defaults to `null`. The configuration IDs of the items you want to retrieve.
* `ItemsPerFetch`: An int. Defaults to 20. Use this to set the maximum number of items to fetch per call between 1 and 100 inclusive.

### GetInventoryResult

A `GetInventoryResult` provides paginated access to the list of player's inventory items retrieved. It has the following field:

* `PlayersInventoryItems`: A `List<PlayersInventoryItem>` with the currently fetched items.

It has the following methods:

* `GetNextAsync(int itemsToFetch = 20)`: This method asynchronously fetches more results. It has one optional parameter to limit the amount of results fetched (this can be between 1 and 100 inclusive, default is 20). It will return a new result, which contains both the original items and the newly fetched items in its `PlayersInventoryItems` list. The result will be `null` if there are no more results to fetch.

## AddInventoryItemAsync

Adds an item to the player's inventory.

This method optionally takes an `AddInventoryItemOptions` object. This is used to set a custom `PlayersInventoryItemId` — if `null`, one is autogenerated. Can also be used to set a dictionary of instance data.

Returns a `PlayersInventoryItem` representing the inventory item added to the player's inventory.

```cs title="C#"
Dictionary<string, object> instanceData = new Dictionary<string, object>
{
    { "rarity", "purple" }
};

AddInventoryItemOptions options = new AddInventoryItemOptions
{
    PlayersInventoryItemId = "customID",
    InstanceData = instanceData 
};

PlayersInventoryItem createdInventoryItem = await EconomyService.Instance.PlayerInventory.AddInventoryItemAsync("SWORD", options);
```

### AddInventoryItemOptions

The options object for a `AddInventoryItemAsync` call. It has the following fields:

* `PlayersInventoryItemId`: A string. Defaults to `null`. Sets the ID of the created `PlayersInventoryItem`. If not supplied, one is generated.
* `InstanceData`: A `Dictionary<string, object>`. Used to set a dictionary of [instance data](#using-instancedata).

## DeletePlayersInventoryItemAsync

Deletes an item from a player's inventory.

This method optionally takes a `DeletePlayersInventoryItemOptions` object used to set the write lock. If a write lock is provided, it will only delete the item if the write lock is accepted by the Economy service. If no write lock is provided then the operation is forced through.

```cs title="C#"
DeletePlayersInventoryItemOptions options = new DeletePlayersInventoryItemOptions
{
    WriteLock = "writeLock"
};
EconomyService.Instance.PlayerInventory.DeletePlayersInventoryItemAsync("playersInventoryItemID", options);
```

### DeletePlayersInventoryItemOptions

The options object for a `DeletePlayersInventoryItemAsync` call. It has the following field:

* `WriteLock`: A string. Defaults to `null`. Use this to set a write lock for optimistic concurrency. See [Write Lock](./common-objects#using-the-writelock).

## UpdatePlayersInventoryItemAsync

Updates an item with new instance data.

Returns the updated players inventory item.

This method optionally takes an `UpdatePlayersInventoryItemOptions` object used to set the write lock. If a write lock is provided, it will only update the item if the write lock is accepted by the Economy service. If no write lock is provided then the operation is forced through.

```cs title="C#"
Dictionary<string, object> instanceData = new Dictionary<string, object>
{
    { "rarity", "purple" }
};

UpdatePlayersInventoryItemOptions options = new UpdatePlayersInventoryItemOptions
{
    WriteLock = writeLock 
};

PlayersInventoryItem playersInventoryItem = await EconomyService.Instance.PlayerInventory.UpdatePlayersInventoryItemAsync("playersInventoryItemID", instanceData, options);
```

### UpdatePlayersInventoryItemOptions

The options object for a `UpdatePlayersInventoryItemAsync` call. It has the following field:

* `WriteLock`: A string. Defaults to `null`. Use this to set a write lock for optimistic concurrency. See [Write Lock](./common-objects#using-the-writelock).

## PlayersInventoryItem

A `PlayersInventoryItem` represents a single unique item in a player's inventory. It contains the following fields:

* `PlayersInventoryItemId`: The ID of this unique inventory item in the players inventory.
* `inventoryItemId`: The resource ID of the inventory item configuration associated with this instance.
* `InstanceData`: Any instance data associated with this players inventory item.
* `InstanceDataDeserializable`: Any instance data associated with this players’ inventory item, as an `IDeserializable`. See [Using InstanceDataDeserializable](#using-instancedata).
* `WriteLock`: The current `writelock` string for this player's inventory item.
* `Created`: The date this player's inventory item was created. It is an [EconomyDate](./common-objects#economydate) object.
* `Modified`: The date this player's inventory item was modified. It is an [EconomyDate](./common-objects#economydate) object.

It also has the following helper method:

### GetItemDefinitionAsync

This method fetches the configuration of this player's inventory item, type of `InventoryItemDefinition`.

```cs title="C#"
PlayersInventoryItem playersInventoryItem = // ... fetch the players inventory item
InventoryItemDefinition itemDefinition = playersInventoryItem.GetItemDefinitionAsync();
```

## PlayersInventoryItemUpdated

This event can be subscribed to in order to be notified when the SDK updates a specific item in the player's inventory. The subscriber is passed the `playersInventoryItem` ID of the item that was updated.

> **Note:**
>
> This event is only called for SDK initiated actions (for example, updating player's inventory, making purchases). It will not be called for any updates from other devices / service side changes.

```cs title="C#"
EconomyService.Instance.PlayerInventory.PlayersInventoryItemUpdated += playersInventoryItemID => {
    Debug.Log($"The players inventory item that was updated was {playersInventoryItemID}");
};
```

### Using InstanceDataDeserializable##using-instancedata

Use `InstanceDataDeserializable` to add custom data for specific items in a player's inventory. It is passed in as type `object` and fetched as type `IDeserializable`. This allows you to pass in your own custom classes as instance data.

For example, a player's shield may have a durability rating. This could be set and updated using `InstanceDataDeserializable`:

```cs title="C#"
class MyInstanceData
    {
        public int Durability;
        public string Rarity;
    }

MyInstanceData myInstanceData = new MyInstanceData() { Durability = 100, Rarity = "purple"};
PlayersInventoryItem updatedItem = await EconomyService.Instance.PlayerInventory.UpdatePlayersInventoryItemAsync("playersInventoryItemId", myInstanceData);
```

You can deserialize the instance data by doing the following:

```cs title="C#"
MyInstanceData fetchedInstanceData = updatedItem.InstanceData.GetAs<MyInstanceData>();
int durability = fetchedInstanceData.Durability;
string rarity = fetchedInstanceData.Rarity;
```
