Hiro Inventory Sample Project

The official sample project for the Hiro Inventory system. This project demonstrates retrieving the item codex, listing inventory items, granting, consuming, and removing items through the Hiro SDK in Unity. It keeps boilerplate light so you can transplant the inventory flow into your own game.

Features

  • Browse the item codex pulled from Hiro inventory templates with names, descriptions, categories, and rarity.
  • Grant items from the codex with safeguards for max stack limits and available inventory slots.
  • Consume consumable items with an optional overconsume toggle for testing error paths.
  • Remove items from the player by issuing negative grants.
  • Color-coded inventory grid with selection details for properties, stackability, and consumable flags.
  • Wallet panel stays in sync with the Hiro economy system to show currency changes.

Installation

The installation steps and resulting folder structure will vary depending on if you downloaded the project from Github or the Unity Asset Store.

Note: This project was built with Unity 6.0+ in mind. Whilst the majority of the template is not version specific, the UI may not behave as intended on older versions of Unity.

For optimal display, set your game resolution in the Unity Editor to 1920x1080

  1. Clone or download the Sample Projects repository onto your machine.
  2. From the Unity Hub, click Add -> Add project from disk and choose the top-level UnityHiroInventory folder.
  3. You may see several warnings about Editor version incompatibility. Feel free to ignore these messages as long as you're on Unity 6 or greater. Continue on until you arrive at the main Editor UI.
  4. Open the main scene by navigating to Assets -> UnityHiroInventory -> Scenes -> Main.
  5. Hit Play.

The project connects to our demo server so you can see the features in action immediately.
Note: The server is reset on the 1st of every month at 00:00 UTC.

Folder structure

Assets/
├── UnityHiroInventory/
    ├── HeroicUI/           # UI assets and styling
    ├── Scripts/            # Main project code
    ├── UI/                 # UI Builder files
    └── ...                 # Everything else
├── Packages/               # Contains the Nakama Unity package

Code overview #

The project uses Hiro’s systems-based architecture, which provides an opinionated structure for building games with pre-configured systems.

Coordinator (HiroInventoryCoordinator.cs) #

Extends the HiroCoordinator class to set up the Nakama connection and initialize Hiro systems. It handles system lifecycle and authentication before your game logic runs. Learn more about Hiro’s deterministic startup.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
protected override Task<Systems> CreateSystemsAsync()   {
    var logger = new Hiro.Unity.Logger();
    var monitor = NetworkMonitor.Default;
    var client = localHost
        ? new Client("http", "127.0.0.1", 7350, "defaultkey")
        : new Client(scheme, host, port, serverKey);
    var nakamaSystem = new NakamaSystem(logger, client, NakamaAuthorizerFunc());
    var storage = MemoryStorage.Default;

    // Register necessary Hiro Systems
    var systems = new Systems(nameof(HiroInventoryCoordinator), monitor, storage, logger);
    systems.Add(nakamaSystem);
    var inventorySystem = new InventorySystem(logger, nakamaSystem);
    systems.Add(inventorySystem);
    var economySystem = new EconomySystem(logger, nakamaSystem, EconomyStoreType.Unspecified);
    systems.Add(economySystem);
    return Task.FromResult(systems);
}

API reference: Hiro Initialization

Controller (InventoryController.cs) #

Bridges the UI and Inventory system, handling codex loading, item selection, and item actions (such as granting, consuming, and removing) with validation.

Load Item Codex

What is the Item Codex?
Hiro’s codex is the server-defined catalog of item templates—names, descriptions, categories, stack rules, max counts, properties, and icons—that the client loads to know what items exist and how they behave before granting, consuming, or displaying them.
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
// clears the current codex cache, fetches all codex items from the inventory system, 
// and repopulates both the list and ID lookup dictionary with the results
  public async Task LoadItemCodex()
  {
      CodexItems.Clear();
      CodexLookup.Clear();
      var items = await _inventorySystem.GetItemCodexAsync();
      CodexItems.AddRange(items);
      foreach (var item in items)
      {
          CodexLookup[item.Id] = item;
      }
  }

Grant item

Grants a codex item by quantity after validating selection, nonzero quantity, max count, and slot availability.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
public async Task GrantItem(int codexIndex, int quantity)
  {
      if (codexIndex < 0 || codexIndex >= CodexItems.Count)
          throw new Exception("Please select a valid item.");

      if (quantity == 0)
          throw new Exception("Quantity cannot be 0.");

      var selectedItem = CodexItems[codexIndex];

      // Only validate limits when adding items (positive quantity)
      if (quantity > 0)
      {
          ValidateItemMaxCount(selectedItem, quantity);
          ValidateInventorySlots(selectedItem, quantity);
      }

      var items = new Dictionary<string, long>
      {
          { selectedItem.Id, quantity }
      };

      await _inventorySystem.GrantItemsAsync(items);
  }

Consume item

Consumes the selected consumable item by quantity (with optional overconsume), then refreshes the economy state.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
public async Task ConsumeItem(int quantity, bool overconsume)
{
    if (_selectedItem == null) return;

    if (quantity <= 0)
        throw new Exception("Quantity must be greater than 0.");

    var items = new Dictionary<string, long>
    {
        { _selectedItem.Id, quantity }
    };
    var instances = new Dictionary<string, long> {};

    await _inventorySystem.ConsumeItemsAsync(items, instances, overconsume);
    await _economySystem.RefreshAsync();

    _selectedItem = null;
}

Validate item max count

Ensures adding a quantity won’t exceed an item’s MaxCount, throwing “MAX_COUNT_REACHED” when it would.

Validate inventory slots

Checks inventory capacity, throwing “INVENTORY_FULL” when stack rules or slot count can’t fit the addition.

Refresh inventory

Refreshes inventory and wallet state, repopulates the local item list, and returns the updated items.

API reference: Inventory

Account Switcher

The Account Switcher lets you explore the project as different players without managing multiple builds. Use it to test features from different accounts.

How to use:

  1. Open the Account Switcher panel (Tools > Nakama > Account Switcher).
  2. Select different accounts from the dropdown to switch between up to four test users.
  3. Each account is automatically created the first time you select it.

Key points:

  • Only works while your game is running in Play mode.
  • Usernames will display in the panel after switching to an account for the first time.

Setting up your own Nakama server with Hiro

While this project works with our demo server, you'll want to set up your own Nakama and Hiro instance to customize the features and configurations.

Prerequisites

Before you can set up Hiro, you'll need to:

  1. Install Nakama: Follow the Nakama installation guide to get Nakama running with Docker.
  2. Obtain Hiro: Hiro is available to licensed users. Contact us to obtain your license.
  3. Install Hiro: Once you have your license key, follow the Hiro installation guide.

Configure Hiro

This sample project ships with specific Hiro system configurations on the server. You can view the exact configuration files used in our demo server here: Demo server configurations.

Copy the JSON files to your server (such as inside a definitions directory) and update main.go to initialize the required Hiro systems according to the installation guide or view the example on Github.

Connect this Unity project to your server

After installing Nakama and Hiro and running it locally with the appropriate configurations, edit these settings in the Unity Editor to connect to your server:

  1. Select the main coordinator component from the scene hierarchy panel.
  2. Open the Inspector tab.
  3. Look for the field inputs under Nakama Settings and replace them with the following:
    1. Scheme: http
    2. Host: 127.0.0.1
    3. Port: 7350
    4. Server Key: defaultkey

Additional resources