This article was written on Pragma Engine version 0.0.94.
Creating a Crafting System Using Stores #
In this article, we’ll learn how to use a technique to create a crafting system using Pragma Engine’s store structure. If you haven’t already, check out our two previous Stackable Items series articles on creating stackable items and a store system.
Pragma Engine’s flexible store system is a perfect example of how Pragma Engine supports customizability in your unique backend. For this tutorial, we’ll create more stackable items for a crafting system called Smelter (for making metal ingots from ores), build the Smelter using Pragma Engine’s stores, and test the stackable items and Smelter by simulating a player crafting three different metal ingots.
Understanding Pragma Engine’s Customizability #
All of Pragma Engine’s features and systems are built to encourage flexible, creative solutions for whichever backend features you need to power your game. For example, even though our store system is labeled as such, you can use Pragma Engine’s store structure to create a fully fledged metal-working smelter by simply exchanging stackable items (ores for ingots). The store system could even create a bulletin board for quest selection, a quest reward menu for selecting which rewards to receive, or a market for buying all sorts of stackable and instanced items.
Just like the store system, the inventory system that supports items is extensible and unique. Stackables and instanced items alike don’t have to be solely physical items in your game world–these items could also be experience points, login trackers, player statistics, radiant quests, and whatever your team could possibly need or think of. You might find that the best way to support a questing system with Pragma Engine is by using our store structure. Or, in our case for this tutorial, using a store to create a metal-working smelter!
Building our smelter’s foundation #
Building our smelter’s foundation requires turning ore into metal ingots, and in order to do that, we need to create the smelter’s final product, ingots, as stackable items.
First, you’re going to want to make sure you’ve created your 5-ext
directory from our previous Stackable Items series articles. If you haven’t already checked out our previous two articles, look at them to familiarize yourself with Pragma Engine’s stackable items and store system.
Once your 5-ext
directory is all set, go to 5-ext/content/src/StackableSpecs.json
and add the following code for copper_ingot
, bronze_ingot
, and iron_ingot
. Just like the previous store article, we’re going to keep the copper, tin, and iron ores. If you like, you can also keep the gold_coins
from the first Stackable Items series article.
It’s important to note that we are not creating a tin ingot and are instead making a bronze ingot. This is because making a bronze ingot requires combining copper and tin ores, which we’ll show you how to do in the store section of this guide.
[
{
"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
},
{
"catalogId": "copper_ingot",
"name": "copper ingot",
"limit": 1000000,
"tags": ["resource", "craftable"],
"removeIfNone": true
},
{
"catalogId": "bronze_ingot",
"name": "bronze ingot",
"limit": 1000000,
"tags": ["resource", "craftable"],
"removeIfNone": true
},
{
"catalogId": "iron_ingot",
"name": "iron ingot",
"limit": 1000000,
"tags": ["resource", "craftable"],
"removeIfNone": true
}
]
Compared to the last stackable entry we made for our copper, tin, and iron ores, not much has changed with how we define our stackable items. The only new addition from our stackable ingots is the tag craftable
, which helps categorize our ingots as both a resource for further crafting (possibly for armor or weapons) and a resource that can be crafted.
With all our stackables created and in place for smelting, let’s create a store named smelter
as our unique crafting system.
Creating the Smelter #
Let’s hammer out the details for our crafting system by navigating to 5-ext/content/src/Stores.json
and adding the code block below to create our smelter
. Make sure you add this new store inside the file’s largest square brackets (which contains all individual stores) and below the previous store we created in the last Stackable Items series article. You’ll want to make sure that the previous store’s code block ends with a comma after its final curly bracket as well.
{
"id": "smelter",
"name": "Smelter",
"storeEntries": []
}
Once you’ve written the id
and name
for our Smelter, we’re going to add the following code for our Smelter’s storeEntries
:
"storeEntries": [
{
"id": "craft_copper_ingot",
"receivedQuantityByCatalogId": {
"copper_ingot": 1
},
"costByCatalogId": {
"copper_ore": {
"cost": 2
}
}
},
{
"id": "craft_bronze_ingot",
"receivedQuantityByCatalogId": {
"bronze_ingot": 1
},
"costByCatalogId": {
"copper_ore": {
"cost": 2
},
"tin_ore": {
"cost": 1
}
}
},
{
"id": "craft_iron_ingot",
"receivedQuantityByCatalogId": {
"iron_ingot": 1
},
"costByCatalogId": {
"iron_ore": {
"cost": 2
}
}
}
]
Stackable Item | Material Cost |
---|---|
1x copper_ingot | 2x copper_ore |
1x bronze_ingot | 2x copper_ore , 1x tin_ore |
1x iron_ingot | 2x iron_ore |
There are a few big differences between the smelter
store and the shopkeeper
store from the previous article.
First, our smelter
has no storeEntries
for reversing an ingot back to an ore. Second, our bronze_ingot
has two different costByCatalogId
s: copper_ore
, and tin_ore
.
You can add as many receivedQuantityBycatalogId
s and costByCatalogId
s as your storeEntries
require, and in this case, a bronze_ingot
requires both copper_ore
and tin_ore
. To mimic how some crafting systems require multiple amounts of a resource to create another item, we’re also going to change the cost of some of the ores to 2
instead of 1
(except for tin_ore
, which will still have a cost of 1
).
Once you’re finished creating the smelter
, let’s apply our content data changes before making some ingots with Postman.
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
Now that our changes are applied, we can craft copper, bronze, and tin ingots from our Smelter by simulating service calls with Postman.
Testing the Crafting System #
Before we go smelting, 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.
To test our crafting system, we’re going to be using all of the same service calls from the Purchasing Stackable Items in a Store article. With that in mind, you might notice a lot of similar instructions you’ve already seen before, only with slight variations for testing our particular crafting system.
Simulating service calls with Postman #
To get started, go into a terminal with platform
as the working directory and do a make run
to get the engine running for making service calls.
make run
Once you’re ready, we can test our smelting store by authenticating an Operator and a Player, granting some stackable ores to a player’s inventory, and crafting copper, bronze, and iron ingots from our newly granted ores using the Smelter.
Authenticating test Operator and Player logins #
Just like the previous Stackable Items series article, 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 copper, tin, and iron ores to a player to use with our Smelter.
Granting the ores for smelting #
In the PragmaDev
folder, locate the service call: Game>RPC - Operator>Inventory>GrantItemsOperatorV1
and open the service call’s body. Once you’re there, add the code block below in the service call’s payload
to make three itemGrants
for 5 copper, tin, and iron ore to a player’s inventory.
"itemGrants": [
{
"stackable": {
"catalogId": "copper_ore",
"amount": 5,
"tags": ["resource"]
}
},
{
"stackable": {
"catalogId": "tin_ore",
"amount": 5,
"tags": ["resource"]
}
},
{
"stackable": {
"catalogId": "iron_ore",
"amount": 5,
"tags": ["resource"]
}
}
]
If you check the player’s inventory by going to the service call: Game>RPC - Operator>Inventory>GetInventoryOperatorV1
, the player might have some leftover ores in their inventory from the previous Stackable Items series article. You also might see a catalogId
of gold_coins
with an amount of 0
in the player’s inventory from when we tested our store shopkeeper
as well. This stackable item carried over from our inventory because gold_coins
has a removeIfNone
value of false
, and our three ores have a removeIfNone
value of true
.
If you want to see this parameter value in action, you can run the GrantItemsOperatorV1
service call with one of the three ores as the stackable’s catalogId
value and an amount value of -5
. With the amount as a negative value, the service call subtracts that amount from the player’s inventory until it reaches 0
, rather than adding it.
When you’re finished granting the ores to the player, they’ll have 5 copper, tin, and iron ore in their inventory for smelting. Now we can run a service call to smelt our ores into three different ingots.
Creating ingots with our Smelter #
To simulate our newly created crafting system, let’s imagine that our player has acquired their 5 copper, tin, and iron ores from a recent mining mission in-game. With their ores as crafting materials, the player wants to go to a Smelter and make three different kinds of ingots. They want to make 1 copper ingot, 1 bronze ingot, and 2 iron ingots. Our Smelter can do these three tasks as long as we input the right storeId
and the correct storeEntryId
s 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 smelter
so we use the correct store for this call.
Next, give the storeEntryId
a value of craft_copper_ingot
to craft a copper ingot from the smelter
. You can leave the amount
value as 1
. Click Send once you’ve edited the service call’s body and do this process again by replacing the storeEntryId
value with craft_bronze_ingot
.
Remember that we created the storeEntry
for craft_bronze_ingot
to cost both 2 copper_ingots
and 1 tin_ingot
, so both items will be taken out of the player’s inventory. To craft the last ingot, replace the stackable’s storeEntryId
value with craft_iron_ingot
and an amount value of 2
.
Once you’re done, let’s check the player’s inventory by running GetInventoryOperatorV1
. In total, our player’s inventory should have the remaining stackables (not including any leftover stackables from the previous articles): 1 copper_ore
, 4 tin_ore
, 1 iron_ore
, 2 iron_ingot
, 1 bronze_ingot
, and 1 copper_ingot
.
If your player has the correct amount of ores and ingots, then congrats! You’ve just created a crafting system using Pragma Engine’s stores. This is just one example of how you can customize Pragma Engine’s systems to your creative developmental needs.
There are many more examples and technical blog tutorials to come, and we’re excited to share more of them with you soon!
A stack of gold coins, a pile of copper, tin, and iron ores, and a bundle of copper, bronze, and iron ingots.
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
Part III: Creating a Crafting System Using Stores (this article)