Updating Items #

Games often allow players to upgrade or reforge their items. Pragma Engine can handle this scenario via the InstancedItemPlugin.update() method.


Create the proto definitions and store entry #

  1. Complete the Setting Up the Item Catalog and Store and Purchasing Items sections, then shut down the engine if it’s still running.
  2. In IntelliJ, define the update-related protos in 5-ext/ext-protos/src/main/proto/shared/inventoryContentExt.proto:
message ExtUpdateEntry {
  oneof data {
    WeaponUpdateSpec weapon_update_spec = 1;
  }
}

message WeaponUpdateSpec {
  int64 damage_upgrade = 1;
  int32 awesomeness_upgrade = 2;
}
  1. Edit 5-ext/content/src/UpdateEntries.json to provide actual upgrade data. The following json states that each upgrade will cost 350 of catalogId coins, will upgrade the damage by 3, and will upgrade the awesomeness by 1.
[
  {
    "ext": {
      "weaponUpdateSpec": {
        "damageUpgrade": 3,
        "awesomenessUpgrade": 1
      }
    },
    "id": "upgradeWeapon",
    "costByCatalogId": {
      "coins": {
        "cost": 350
      }
    },
    "tags": []
  }
]
  1. Run make ext from a terminal. Make sure the working directory is the platform directory.

Apply content data #

In order to register the instanced items, stackable items, and store you just defined with Pragma Engine, you must apply your content data changes.

In a terminal with platform as the working directory, run:

java -jar 5-ext/target/pragma.jar contentdata apply -d 5-ext/content

At the prompt, confirm that you wish to apply content changes.

Update InstancedItemPlugin #

  1. Implement the update method in DemoInstancedItemPlugin:
Due to known issues with IntelliJ performing type inferences on protos, using a value nested in an ext field can cause false syntax error. Create a local variable with a manually assigned type to hold proto ext fields, as we’ve done with specExt below.
override fun update(
  initialInstancedItem: InstancedItem,
  instancedSpec: InventoryContent.InstancedSpec,
  updateEntry: InventoryContent.UpdateEntry,
  inventoryContent: InventoryServiceContent,
  clientRequestExt: ExtInstancedItemUpdate?,
  serverRequestExt: ExtInstancedItemServerUpdate?
): InstancedItemPlugin.UpdateResult {
  val extInstancedItemBuilder = ExtInstancedItem.newBuilder()

  // check which item type is being processed
  val specExt: ExtInstancedSpec = instancedSpec.ext
  return when (specExt.dataCase) {
    ExtInstancedSpec.DataCase.LASER_SWORD_SPEC -> {

      // this describes specific attributes of a laser sword
      val laserSwordSpec = specExt.laserSwordSpec

      // this describes how to update weapons, including the laser sword.
      val updateExt: ExtUpdateEntry = updateEntry.ext
      val weaponUpdateSpec = updateExt.weaponUpdateSpec

      // calculate updates
      val existingLaserSword = initialInstancedItem.ext.laserSword
      val updatedDamage = existingLaserSword.damage + weaponUpdateSpec.damageUpgrade
      val currentAwesomenessIndex =
        laserSwordSpec
          .awesomenessList
          .indexOf(existingLaserSword.awesomeness)
      val updatedAwesomenessIndex = min(
        currentAwesomenessIndex + weaponUpdateSpec.awesomenessUpgrade,
        laserSwordSpec.awesomenessCount - 1
      )

      // build laser sword data with the updated values
      val laserSwordBuilder = extInstancedItemBuilder.laserSwordBuilder
      val updatedLaserSword = laserSwordBuilder
        .setAwesomeness(laserSwordSpec.getAwesomeness(updatedAwesomenessIndex))
        .setDamage(updatedDamage)
        .build()
      InstancedItemPlugin.UpdateResult(
        extInstancedItemBuilder.setLaserSword(updatedLaserSword).build(),
        emptyList()
      )
    }

    else -> error("Unknown item!")
  }
}
The update() method can be extended to support additional items by adding conditions to the when statement.
  1. Run make ext using a terminal from the platform directory.
  2. Run make run to start Pragma Engine. Run this in a terminal with platform as the working directory.
  • Alternatively, Pragma Engine can be run from IntelliJ. From the IntelliJ toolbar in the upper right, ensure MainKt - LocalConfigured is selected, then click the play button.
  • If not, click Add Configuration…. In the Run/Debug Configurations window that appears, expand Kotlin in the left hand side, then select MainKt - LocalConfigured. Click OK. Click the play button in the IntelliJ toolbar to start Pragma Engine.
  • Once the engine has started successfully, it prints the message [main] INFO main - Pragma server startup complete.
  1. In Postman, send PragmaDev ➨ Social ➨ Player ➨ Account ➨ authenticateOrCreateV2 to log into the engine as a player.
  2. Send PragmaDev ➨ Game ➨ RPC - Player ➨ Inventory ➨ storePurchaseV4 with the following request body to get coins:
{
  "requestId": 1,
  "type": "InventoryRpc.StorePurchaseV4Request",
  "payload": {
    "data" : {
     "ext": {},
     "storeId": "freeVendor",
      "storeEntryId": "starterBundle",
      "amount": 1
    }
  }
}
  1. Change the storeId to shopkeeper and the storeEntryId to laserSword, then resend the storePurchaseV4 call to purchase a laserSword. Copy the instanceId of the laserSword from the body of the response as this will be used in the next step.
{
  "requestId": 1,
  "type": "InventoryRpc.StorePurchaseV4Request",
  "payload": {
    "data" : {
     "ext": {},
     "storeId": "shopkeeper",
      "storeEntryId": "laserSword",
      "amount": 1
    }
  }
}
  1. In Postman, navigate to PragmaDev ➨ Game ➨ RPC - Player ➨ Inventory ➨ updateItemV4. Edit the instanceId in the body of the request with the value copied from the previous step. Also change the value of updateEntryId to "upgradeWeapon". Send the service call to upgrade the laserSword.
{
  "requestId": 1,
  "type": "InventoryRpc.UpdateItemV4Request",
  "payload": {
    "itemUpdate": {
      "instanced":
      {
        "ext": {},
        "instanceId": "your item's instanceId here",
        "updateEntryId": "upgradeWeapon",
        "tags": [""]
      }
    }
  }
}
  1. Confirm that the damage of the laserSword increased by 3 and the awesomeness was incremented from a little to somewhat.