View as Markdown

Inventory

The Inventory meta-system in Hiro enables players to collect, upgrade, and consume items in your game. These in-game items can be anything from a piece of equipment like a sword or chestplate, to a cosmetic item like a flag or costume, to a power up like a spawner or boost.

Inventory items can be purchased from the virtual store, or earned through gameplay.

Inventory and loadout screen in Firebreak showing equipped weapons and available gear slots
Inventory & Loadout Systems from Firebreak by Remedy is supported by Hiro
Ready to try it yourself? Explore the Inventory sample project.

Customization parameters #

Every item that a player can own must be defined in the inventory config before it can be granted or listed. The config is the authoritative catalogue of all ownable items in your game, think of it as the item codex. Items not present in the config are invisible to all inventory APIs: List, ListInventoryItems, GrantItems, and ConsumeItems all skip unrecognised item IDs silently with a warning.

If you need items that aren’t known at deploy time — for example, procedurally generated weapons or items fetched from an external service — use SetConfigSource to provide a per-item fallback lookup.

The following JSON represents the customization parameters you can use to configure the default user experience for the inventory system.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
{
  "items": {
    "iron_sword": {
      "name": "Iron Sword",
      "description": "A sharp sword made of iron.",
      "category": "weapons",
      "item_sets": ["common_weapons"],
      "max_count": 99,
      "stackable": false,
      "consumable": false,
      "string_properties": {
        "equipment_slot": "right_hand"
      },
      "numeric_properties": {
        "rank": 1
      },
      "disabled": false
    },
    "health_potion": {
      "name": "Health Potion",
      "description": "A vial of red liquid used for healing.",
      "category": "potions",
      "max_count": 99,
      "stackable": true,
      "consumable": true,
      "keep_zero": true,
      "consume_reward": {
        "guaranteed": {
          "energies": {
            "health": {
              "min": 100
            }
          }
        }
      }
    },
    "small_crafting_bag": {
      "name": "Small Crafting Bag",
      "description": "A small bag of miscellaneous crafting materials.",
      "category": "loot_bags",
      "max_count": 99,
      "stackable": false,
      "consumable": true,
      "consume_reward": {
        "max_rolls": 2,
        "weighted": [
          {
            "items": {
              "leather_scraps": {
                "min": 1,
                "max": 5
              }
            },
            "weight": 50
          },
          {
            "items": {
              "bronze_nails": {
                "min": 5,
                "max": 100,
                "multiple": 5
              }
            },
            "weight": 50
          }
        ]
      }
    }
  },
  "limits": {
    "categories": {
      "armor": 10
    },
    "item_sets": {
      "shield": 5
    }
  }
}

The JSON schema defines several objects which define the various items and item sets that will be available in your game. You can configure as few or as many of each as needed for your desired gameplay.

PropertyTypeDescription
itemsstring:ItemA map of all items.
limitsConfigLimitsAny limits to the quantity of items a user can hold from specific Categories or Item Sets.

Config Limits #

ConfigLimits can be used to restrict how many items are able to be held at a given time from specified Categories or Item Sets.

In the case that an item is restricted by its Category AND its Item Set:

  • Assume there is an item with category armor from the item set shield that is being granted.
  • The inventory limits are set to a maximum of 10 armor and 5 shields.
  • Even if the user has fewer than 10 pieces of armor, they won’t be able to receive the item if they currently have 5 shields.
PropertyTypeDescription
categoriesstring:int64A map of categories and maximum quantities of items a user can hold from the specified category.
item_setsstring:int64A map of item sets and maximum quantities of items a user can hold from the specified item set.

Each individual item is keyed by id and may define the following:

Item #

PropertyTypeDescription
namestringThe display-friendly name for this item.
descriptionstringThe description text for this item.
categorystringThe category that this item belongs to.
item_sets[]stringThe item sets that this item belongs to.
max_countint64The maximum number of this item a user can own at a given time. This is checked by summing the count across all instances of this item ID in the user’s inventory.
stackableboolWhether this item can stack. When true, all instances of this item are stored as a single item instance with the count property tracking quantity. When false, each item is stored as a separate instance with its own unique instance ID.
consumableboolWhether this item can be consumed to receive the consume_reward.
consume_rewardRewardThe rewards that a user receives when they consume this item.
string_propertiesstring:stringA map of string values that define item specific metadata.
numeric_propertiesstring:float64A map of numeric values that define item specific metadata.
disabledboolDisables the item across all inventory APIs without removing it from the config. Disabled items are excluded from List, ListInventoryItems, GrantItems, ConsumeItems, and all reward rolls.
keep_zeroboolUsed to make this item stay in a user’s inventory, even when there are none left. Useful for displaying certain items that have been acquired, regardless of whether the user still has any.
Collectable cards screen in Fruit Fall showing a grid of unlockable fruit character cards
Collectable Items / Cards in Fruit Fall by Gram Games uses Hiro Inventory System

Item Definitions #

Item Categories #

Every item definition has a category property. This is a simple string property that defines which broad collection the item belongs to and is useful for listing items. For example, you may wish to separate your items into categories such as weapons, armor, and potions.

Item Sets #

Item definitions can optionally define an array of item_sets they belong to. Unlike category (a single string per item), an item can belong to multiple sets at once. Use them as multi-value tags: for example, ["rare", "sword"] or ["event_spring", "cards_epic"].

Item Rewards #

A powerful feature of the Inventory system is the ability for game designers to add consume rewards to item definitions. When a user consumes the item, they will be granted the reward accordingly. Due to the power and flexibility of the Hiro reward system, this allows game designers the opportunity to create all manner of consumables.

Consider the following scenarios and associated item definitions:

A potion that restores 50 health

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
{
  "health_potion": {
    "name": "Health Potion",
    "description": "A vial of red liquid used for healing.",
    "category": "potions",
    "max_count": 99,
    "stackable": true,
    "consumable": true,
    "consume_reward": {
      "guaranteed": {
        "energies": {
          "health": {
            "min": 100
          }
        }
      }
    }
  }
}

A coin pouch that rewards between 100 and 500 gold coins in multiples of 10

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
{
  "coin_pouch": {
    "name": "Coin Pouch",
    "description": "A small pouch of gold coins.",
    "category": "bags",
    "max_count": 99,
    "stackable": true,
    "consumable": true,
    "consume_reward": {
      "guaranteed": {
        "currencies": {
          "coins": {
            "min": 100,
            "max": 500,
            "multiple": 10
          }
        }
      }
    }
  }
}

A loot chest that rewards a sword and a random rare weapon

To reward a player with a specific item, reference it by ID in a reward definition’s items field. To reward a random item from a set — useful for gacha mechanics, loot tables, or rarity pools — use the item_sets field in the reward definition instead.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
{
  "loot_chest": {
    "name": "Loot Chest",
    "description": "A shiny chest full of treasure.",
    "category": "chests",
    "max_count": 99,
    "stackable": false,
    "consumable": true,
    "consume_reward": {
      "guaranteed": {
        "items": {
          "bronze_sword": {
            "min": 1
          }
        },
        "item_sets": [
          {
            "set": ["rare", "weapon"],
            "min": 1
          }
        ]
      }
    }
  }
}

The set array specifies an intersection: the reward engine picks a random item that belongs to all listed sets. In the collectible cards pattern, this is how rarity-based gacha pulls work. See the Collectible Cards guide for an end-to-end example.

A loot chest that rewards a weighted random currency

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
{
  "currency_chest": {
    "name": "Currency Chest",
    "description": "A shiny chest full of unknown currency.",
    "category": "chests",
    "max_count": 99,
    "stackable": false,
    "consumable": true,
    "consume_reward": {
      "max_rolls": 1,
      "weighted": [
        {
          "currencies": {
            "coins": {
              "min": 100
            }
          },
          "weight": 80
        },
        {
          "currencies": {
            "gems": {
              "min": 10,
              "max": 20,
              "multiple": 5
            }
          },
          "weight": 20
        }
      ]
    }
  }
}

Item Instances #

When a user is granted an item, whether from a Store Purchase, as a Reward, or any other means, it is stored as an item instance inside their inventory. The inventory itself is stored inside the Storage Engine under a special collection/key for that user.

A user’s inventory has the following JSON schema.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
{
  "2cb9c733-a2c8-498f-aaed-8ba24a989c45": {
    "item_id": "iron_sword",
    "owned_time": 1674300933,
    "update_time": 1687347732,
    "count": 1,
    "string_properties": {
      "equipment_slot": "right_hand",
      "gem_slot_1": "strength_ruby",
      "gem_slot_2": "dexterity_emerald"
    },
    "numeric_properties": {
      "rank": 3,
      "monsters_defeated": 435
    }
  },
  "e264eaa7-6bc0-4a78-99ed-18fdadf3afea": {
    "item_id": "potion",
    "owned_time": 1654334562,
    "update_time": 1654338987,
    "count": 12,
    "string_properties": {},
    "numeric_properties": {}
  }
}

The inventory is a map of item instance IDs and the associated item instance data, where each item instance has the following structure.

PropertyTypeDescription
item_idstringThe ID of the item definition this is an instance of.
owned_timeint64The time that this item was acquired.
update_timeint64The time that this item was last updated.
countint64How many of this item are in this instance. For stackable items, this tracks the total quantity. For non-stackable items, this is always 1, with each item existing as a separate instance.
string_propertiesstring:stringA map of string values that define item instance specific metadata.
numeric_propertiesstring:float64A map of numeric values that define item instance specific metadata.

Item Properties #

Item instances have their own metadata, stored within the string_properties and numeric_properties fields. This allows you to build systems where a user can customize, rank up, or modify the items they own. For example, you may have a weapon rank system that allows your players to “level up” their weapons, or a “gem slot” system that allows players to improve the stats of their items by socketing various gems to them, or perhaps you just want to keep track of how many monsters a user has defeated with a particular weapon as shown in the example above.

When retrieving inventory items, properties are merged between the item instance and its config definition. Item instance properties take precedence, so only properties that don’t already exist in the item instance are added from the config. See Property merging behavior for examples.

Default properties
Item definitions can define string_properties and numeric_properties which will be copied across to an item instance when it is retrieved. The values specified in the item definition will always override the value in the item instance. This allows you to update things like stats or XP curves for an item globally across all existing item instances.

Item Stacking #

Where an item is granted that is defined as stackable, the inventory system will first check to see if the user currently has an item instance for that item ID. If they do, the count property of that particular instance will be increased accordingly. If they don’t, or if the item is not stackable, a new item instance will be generated instead and added to the user’s inventory.

Additional Information #