A new Player Data service has been released that is more up to date and supported with this current release of Pragma Engine. We recommend you check it out by viewing the Player Data Overview page.
Upgrading Instanced Items #
In this section, we’ll demonstrate how to upgrade a custom, unique instanced item type called gear
with stackable runestone
items. To upgrade gear
we’ll go over the following steps:
- Create the
updateEntries
used to updateext
data ingear
with specific stackablerunestones
. - Define the catalog of stackable
runestone
items used to upgradegear
instanced items. - Customize an
InstancedItemPlugin
in Kotlin that can build and upgradeext
data ingear
. - Test the
InstancedItemPlugin
,gear
, andrunestones
by running service calls in Postman.
Prerequisites:
- The previous Instanced Items tutorial sections for Creating Instanced Items and Customizing the Instanced Item Plugin must be completed.
Get started #
Run the following commands in the terminal from the platform
directory to build the engine and make 5-ext
if it doesn’t already exist:
make skip-tests protos engine
make ext
Create the stackable runestones #
One way to upgrade instanced items is by requiring the player to use specific items for the upgrade. Stackable items are great for this purpose, as they are identical to one another like crafting or currency materials.
In this section we’ll create three stackable runestone items used to upgrade gear-type instanced items.
Edit the stackable specs catalog #
Define a runestone_fire
, runestone_water
, and runestone_earth
for upgrading gear-type items.
- Go to
5-ext/content/src/StackableSpecs.json
. - Add the following code block to create three different types of runestones:
[
{
"catalogId": "runestone_fire",
"name": "Fire Runestone",
"tags": ["fire", "socketable", "runestones"],
"limit": 10,
"removeIfNone": true
},
{
"catalogId": "runestone_water",
"name": "Ice Runestone",
"tags": ["water", "socketable", "runestones"],
"limit": 10,
"removeIfNone": true
},
{
"catalogId": "runestone_earth",
"name": "Earth Runestone",
"tags": ["earth", "socketable", "runestones"],
"limit": 10,
"removeIfNone": true
}
]
Define the update entries #
Update entries catalog different types of item-updates that require some type of cost for client or server based RPCs. ext
data for updateEntries
can be defined in protos, but the entries themselves are defined in a JSON catalog.
In this section we’ll author the ext
fields for three updateEntries
in protos and catalog the update entries in a JSON catalog.
Edit the inventory content ext file #
- Open
5-ext/ext-protos/src/main/proto/shared/inventoryContentExt.proto
. - In the
ExtUpdateEntry
message, add the following code to define an update entry for upgrading gear withrunestones
:
message ExtUpdateEntry {
oneof data {
string socketed_runestone_catalog_id = 1;
}
}
Apply proto changes #
Run the following make command using platform
as the working directory to apply protobuf changes:
make ext-protos
Create the Update Entries catalog #
- Open
5-ext/content/src/UpdateEntries.json
. - Add the following code block to define three different
UpdateEntries
for eachrunestone
:
[
{
"id": "socket_runestone_fire",
"costByCatalogId": {
"runestone_fire": {
"cost": 1
}
},
"ext": {
"socketedRunestoneCatalogId": "runestone_fire"
}
},
{
"id": "socket_runestone_water",
"costByCatalogId": {
"runestone_water": {
"cost": 1
}
},
"ext": {
"socketedRunestoneCatalogId": "runestone_water"
}
},
{
"id": "socket_runestone_earth",
"costByCatalogId": {
"runestone_earth": {
"cost": 1
}
},
"ext": {
"socketedRunestoneCatalogId": "runestone_earth"
}
}
]
Apply content data #
In order to register the content you just defined with Pragma Engine, you must apply your content data changes. You may apply content data either using the command line with make
or via an IntelliJ run configuration.
Customize the Instanced Item Plugin #
In this section, we’ll customize the Instanced Item Plugin to update ext
data in gear-type instanced items using stackable runestones
. Make sure you already have logic to build gear
in the plugin’s newInstanced()
function from the previous tutorial.
- Go to
5-ext/ext/src/main/kotlin/InstancedItemTutorialPlugin.kt
. - Replace the plugin’s
update()
function with the following code to enablegear
upgrades from stackablerunestones
:
override suspend fun update(
initialInstancedItem: InstancedItem,
instancedSpec: InventoryContent.InstancedSpec,
updateEntry: InventoryContent.UpdateEntry,
inventoryContent: InventoryServiceContent,
startingInventory: InventoryData,
pendingInventory: InventoryData,
clientRequestExt: ExtInstancedItemUpdate?,
serverRequestExt: ExtInstancedItemServerUpdate?
): InstancedItemPlugin.InstancedItemPluginResult {
val extInstancedItemBuilder = ExtInstancedItem.newBuilder()
val extItem: ExtInstancedItem = initialInstancedItem.ext
return when (extItem.dataCase) {
ExtInstancedItem.DataCase.GEAR -> {
val updateExt: ExtUpdateEntry = updateEntry.ext
//Updates gear with the new attribute value and socketed runestones.
val gearBuilder = extInstancedItemBuilder.gearBuilder
gearBuilder.attributeValue = extItem.gear.attributeValue
gearBuilder.addSocketedRunestones(updateExt.socketedRunestoneCatalogId)
InstancedItemPlugin.InstancedItemPluginResult(
extInstancedItemBuilder.setGear(gearBuilder).build(),
InventoryModifications()
)
}
else -> error("Unknown item!")
}
}
Build plugin changes #
Run the following make command using platform
as the working directory to register plugin changes:
make ext
Test the plugin #
In this section, we’ll test if the plugin logic uses runestones
to upgrade unique gear
items with more custom ext
data by running API calls in Postman.
Start Pragma Engine #
Run Pragma Engine via one of the following methods.
Once the engine has started successfully, it prints the message [main] INFO main - Pragma server startup complete
.
Grant a player three runestones #
- Open Postman.
- Navigate to the two service calls
PragmaDev ➨ Public ➨ Operator - AuthenticateOrCreateV2 and PragmaDev ➨ Public ➨ Player - AuthenticateOrCreateV2
. - Click Send for both service calls and check that the response body for each call has
pragmaTokens
with a filledpragmaGameToken
andpragmaSocialToken
. - Open
PragmaDev ➨ Game ➨ RPC - Operator ➨ Inventory ➨ GrantItemsOperatorV1
and open the service call’s body. - Insert the following code block in the payload’s
itemGrants
’s square brackets forrunestone_fire
,runestone_water
, andrunestone_earth
:
{
"requestId": 1,
"type": "InventoryRpc.GrantItemsOperatorV1Request",
"payload": {
"playerId": "{{test01PlayerId}}",
"itemGrants": [
{
"stackable": {
"catalogId": "runestone_fire",
"amount": 1,
"tags": []
}
},
{
"stackable": {
"catalogId": "runestone_water",
"amount": 1,
"tags": []
}
},
{
"stackable": {
"catalogId": "runestone_earth",
"amount": 1,
"tags": []
}
}
]
}
}
- Click Send to grant the player their
runestones
. - Confirm the player has their three instanced items by using the call
PragmaDev ➨ Game ➨ RPC - Operator ➨ Inventory ➨ GetInventoryOperatorV1
.
Upgrade three gear-type items #
Go to
PragmaDev ➨ Game ➨ RPC - Player ➨ Inventory ➨ UpdateItemV4
. In the payload’sinstancedItemUpdate
’s curly brackets, make three separate instanced item update calls by filling theinstanceId
with each gear’sinstanceId
(which can be found by runningGetInventoryOperatorV1
). Then add the correctupdateEntryIds
for eachitemUpdate
(check eachupdateEntryId
with yourUpdateEntries.json
catalog).Run three separate calls so that the player’s
metal_sword_1
has arunestone_fire
,metal_chest_2
has arunestone_water
, andmetal_hat_3
has arunestone_earth
.
Below is an example of what socketing arunestone_fire
to ametal_sword_1
looks like:
{
"payload": {
"instancedItemUpdate": {
"instanceId": "2e9404ab-c970-4e16-9542-8358819846a4",
"updateEntryId": "socket_runestone_fire",
"tags": [""]
}
}
}
- Confirm the player has a
metal_sword_1
with arunestone_fire
,metal_chest_2
with arunestone_water
, andmetal_hat_3
with arunestone_earth
by using theGetInventoryOperatorV1
call.