Purchasing Stackable Items in a Store

Purchasing Stackable Items in a Store

Patrick

Top level header for Purchasing Stackable Items in a Store.

This article was written on Pragma Engine version 0.0.94.

Purchasing Stackable Items in a Store #

In this article, we’ll take a look at creating an in-game store that buys and sells stackable items in Pragma Engine. If you haven’t already, check out our previous article on creating stackable items.

Pragma Engine’s store system catalogs preexisting items—both stackable and instanced—inside a store for item exchanges with a player. In this tutorial, we’re going to learn how to create a store with a catalog of stackable item exchanges, and then simulate a player buying and selling stackable items with the store using their gold coins.


Video tutorial for Purchasing Stackable Items in a Store.

Understanding Stores #

Most games have some type of item store for players to acquire, sell, and exchange items. A store could be a cosmetic market in a title screen, a shady, traveling merchant found during gameplay, or any other game system that exchanges items with the player. Pragma Engine uses stores to contain a list of possible item exchanges between items. These items go back and forth between the player and the store’s limitless storage via service calls to the engine.


A UI menu of a shop that sells instanced and stackable items.

An example shop that sells instanced items (armor) and stackables (resources) for gold coins.

Stores require that items are first created in their respective JSON files. These two files are StackableSpecs.json for stackable items and InstancedSpecs.json for instanced items. Since this article only deals with stackable items, we only have to worry about items we’ll create in StackableSpecs.json.

The next section will show you how to create stackable copper, tin, and iron ore items to buy and sell in a store using the gold coins from the previous article.

Let’s mine for some ore… #

Before we create our stackable ores, make sure you’ve created your 5-ext directory from the previous Creating Stackable Items article. If not, no worries. Simply follow the previous article to build your 5-ext directory and the stackable gold coins item.

To create our stackable ores, go to 5-ext/content/src/StackableSpecs.json and add the following code for copper_ore, tin_ore, and iron_ore. Notice how we’re keeping the gold_coins from the previous article, as we’ll be using that currency to buy and sell our newly created ores with the store.


Tin, copper, and iron ores.

Tin, copper, and iron ore for our store.


[
  {
    "catalogId": "gold_coins",
    "name": "gold coins",
    "limit": 1000000,
    "tags": ["currency"],
    "removeIfNone": false
  },

  {
    "catalogId": "copper_ore",
    "name": "copper ore",
    "limit": 1000000,
    "tags": ["resource"],
    "removeIfNone": true
  },

  {
    "catalogId": "tin_ore",
    "name": "tin ore",
    "limit": 1000000,
    "tags": ["resource"],
    "removeIfNone": true
  },

  {
    "catalogId": "iron_ore",
    "name": "iron ore",
    "limit": 1000000,
    "tags": ["resource"],
    "removeIfNone": true
  }
]

Two things are different when comparing the three ores to the gold coins.

First, the tags for the ores are now a resource instead of a currency. This new tag helps organize and differentiate ores from gold coins based on their functionality and purpose within the game (in this case, ores are a resource item, and gold coins are a currency item).

Next, the removeIfNone parameter has a value of true for our three ores, compared to the coins’ removeIfNone of false. This means that when one of these three stacks of ore is depleted in a player’s inventory, the item disappears from the inventory entirely. Of course, a player can still acquire the depleted stackable item again.

Now that we have all of our stackable ores ready, let’s create a store that buys and sells copper, tin, and iron ore for gold coins.

Creating a Store #

Time to start a small metalworking business!

Go to 5-ext/content/src/Stores.json and add the following code to create a store called shopkeeper:

[
  {
    "id": "shopkeeper",
    "name": "Shopkeeper",
    "storeEntries": []
  }
]

Just like how instanced and stackable items have a catalogId and a name, stores have their own id and name that service calls use to access the store functionalities. Additionally, stores have the parameter storeEntries which is where you’ll list the item exchanges a store can make.

Once we’ve created our shopkeeper, let’s write the item transactions that we want the shopkeeper to be able to make with a player.

Cataloging the store’s item transaction options #

Add the following entries into the storeEntries brackets to give our shopkeeper 6 possible item transactions:

   "storeEntries": [
      {
       "id": "buy_copper_ore",
        "receivedQuantityByCatalogId": {
          "copper_ore": 1
        },
        "costByCatalogId": {
          "gold_coins": {
            "cost": 30
          }
        }
      },
      {
        "id": "sell_copper_ore",
        "receivedQuantityByCatalogId": {
          "gold_coins": 30
        },
        "costByCatalogId": {
          "copper_ore": {
            "cost": 1
          }
        }
      },
      {
        "id": "buy_tin_ore",
        "receivedQuantityByCatalogId": {
          "tin_ore": 1
        },
        "costByCatalogId": {
          "gold_coins": {
            "cost": 20
          }
        }
      },
      {
        "id": "sell_tin_ore",
        "receivedQuantityByCatalogId": {
          "gold_coins": 20
        },
        "costByCatalogId": {
          "tin_ore": {
            "cost": 1
          }
        }
      },
      {
        "id": "buy_iron_ore",
        "receivedQuantityByCatalogId": {
          "iron_ore": 1
        },
        "costByCatalogId": {
          "gold_coins": {
            "cost": 10
          }
        }
      },
      {
        "id": "sell_iron_ore",
        "receivedQuantityByCatalogId": {
          "gold_coins": 10
        },
        "costByCatalogId": {
          "iron_ore": {
            "cost": 1
          }
        }
      }
   ]

Let’s break down this code block by describing what each parameter for our storeEntries means:

ParameterDescription
idThe name used to access the transactional entry in our store. If a store buys and sells the same item, make two separate storeEntries for buying and selling that item.
receivedQuantityByCatalogIdThe ID of the item the caller receives
costByCatalogIdThe ID of the item the store receives for the transaction. In other words, the item that the player pays the store for this transaction.
costThe amount of the item required from the caller for the transaction

Even though buying and selling items might appear as two different functions, they operate very similarly in Pragma Engine; the store receives and gives items to the player the same way a player receives and gives items to the store.

It’s important to be thorough with what your store can actually do for the player; whether it’s only going to allow buying or selling transactions, or both. Also, stores don’t have any type of storage or limited number of transactions. This means that a player can buy an unlimited amount of an item(s) from a store as long as they have the item(s) the store needs for the transaction.

Now that our store is fully functional, with a list of storeEntries for our player to call, let’s apply our content data changes.

Register content changes #

To register the stackables and store we just made, we need to run Pragma Engine with a fresh build and apply our content data changes. Run the following line of code in a terminal using platform as the working directory:

make ext-contentdata-apply

After we’ve applied our changes, it’s time to make sure our gold_coins, our 3 different ores, and the store shopkeeper are ready for business by simulating service calls with Postman.

Testing the Store #

Before we test our store and stackables, make sure you’re running a MySQL database and have Postman installed. If you don’t already have Postman installed, check out our Postman Setup guide in the initial setup README.

Simulating service calls with Postman #

To get started with Postman, enter the following line in a terminal with platform as our working directory. This command gets the engine up and running so we can run calls against it.

make run

Now that Pragma Engine, MySQL, and Postman are up and running, let’s test our store by authenticating an Operator and a Player, granting some stackable ores and gold coins, and buying and selling our three types of ores with our newly created shopkeeper.

Authenticating Operator and Player logins #

Let’s go shopping!


UI of a store that sells copper, tin, and iron ore.

An example of a store cataloging copper, tin, and iron ore.

In the PragmaDev folder, navigate to the two service calls: Public>Operator - AuthenticateOrCreateV2 and Public>Player - AuthenticateOrCreateV2. Then click Send for both service calls and check that the response body for each call has given us pragmaTokens with a filled pragmaGameToken and pragmaSocialToken.

Next, we’re going to grant gold coins to a player to be used with our store.

Granting the gold coins and ores #

This step is identical to the previous Creating Stackable Items article where we grant gold_coins to the player. However, this time around we need to make sure the player has enough currency to purchase our ores from the store.

In the PragmaDev folder, locate the service call: Game>RPC - Operator>Inventory>GrantItemsOperatorV1 and open the service call’s body.

In the service call’s body, find the stackable object and replace the stackable’s catalogId value with gold_coins after the colon (if gold_coins isn’t already there from the previous article). To make sure the player has enough currency, fill in the amount with 1000. This grants 1000 gold coins to the player.

If you want to make sure the player has enough gold coins, go to the service call location: Game>RPC - Operator>Inventory>GetInventoryOperatorV1 and click Send. You can check the response to see if stackables has gold_coins with an amount of at least 1000. You might have more than 1000 gold coins if you completed the previous blog article’s GrantItemsOperatorV1, and that’s okay.

Once the player has some gold coins, let’s run a service call to purchase some ores and sell them back to the shopkeeper.


A bag of gold coins

A bag of gold coins ready to be spent on some ore!

Buying and selling ores with the store #

For this tutorial, let’s assume that our player wants to buy some tin, copper, and iron ore. However, once they make their purchase, they realize they accidentally bought too much copper ore and they don’t actually need any iron ore for their plans. After they realize their mistake, they want to sell all the iron ore back to the shopkeeper and sell exactly 2 copper ore. This interaction is entirely possible with Pragma Engine as long as we input the right storeId and the correct storeEntryIds in the StorePurchaseV4 service call.

Navigate to Game>RPC - Player>Inventory>StorePurchaseV4 and open the service call’s body. Inside payload and data, edit the storeId to have the value of shopkeeper so we use the correct store for this call.

Once we’re all set to interact with our shopkeeper, let’s try to buy some ore!

Go to the storeEntryId and type buy_copper_ore to purchase some copper_ore from the shopkeeper. Then, edit the amount by giving it a value of 5. Click Send once you’ve edited the service call’s body and do this process over again by replacing the storeEntryId with buy_iron_ore and then buy_tin_ore.

You can check the player’s inventory for 5 copper_ore, iron_ore, and tin_ore by using the GetInventoryOperatorV1. If the player’s inventory had 1000 gold_coins, they should have spent 300 gold_coins by buying 5 of each ore and their inventory should now have 700 gold_coins.

However, the player actually only wants 3 copper ores and none of the 5 iron ore they just bought. So, to fix our player’s mistake, type sell_iron_ore in the storeEntryId and click Send. Then, type sell_copper_ore in the storeEntryId, change the amount value to 2, and click Send.

After our player has fixed their kerfuffle by selling the ores they don’t want to the shopkeeper, let’s check the player’s inventory for 3 copper_ore, 5 tin_ore, and no iron_ore (because our ores have a removeIfNone value of true). They should also have gained 110 gold_coins from selling their ore and should now have 810 gold_coins in their inventory.


Copper, iron, and tin ore next to a backpack with gold coins

If your player has the correct amount of ores and gold coins, then bravo! You’ve just created a store that can buy and sell stackable items!


For more information, check out the rest of the articles in this series:

Part I: Creating Stackable Items
Part II: Purchasing Stackable Items in a Store (this article)
Part III: Creating a Crafting System Using Stores



Posted by Patrick Olszewski on July 28th, 2022
Other posts

Contact Us

Pragma is currently working with a select group of studios in development.

A great underlying platform is essential in bringing players together. Pragma's technology lets us focus on the creative side of game development while offloading much of the complexity of shipping at scale.

Nate Mitchell

Founder of Mountaintop Studios and Oculus