Purchasing Items #

Now that we’ve set up the item catalog and store, let’s create our instanced item plugin. We’ll then load the plugin into the engine so that we can purchase unique instances of items.


Create an Instanced Item Plugin #

  1. Create a Pragma Engine plugin that will initialize the purchased item.
  • Create a Kotlin file at 5-ext/ext/src/main/kotlin/DemoInstancedItemPlugin.kt.
  • Define a class that implements the InstancedItemPlugin interface:
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.
import kotlin.random.Random
import kotlin.math.min
import pragma.content.ContentDataNodeService
import pragma.inventory.InventoryContent
import pragma.inventory.InventoryData
import pragma.inventory.InstancedItem
import pragma.inventory.InstancedItemPlugin
import pragma.inventory.InventoryServiceContent
import pragma.inventory.ext.*
import pragma.services.Service

class DemoInstancedItemPlugin(
    val service: Service,
    val contentDataNodeService: ContentDataNodeService
) : InstancedItemPlugin {

    override fun newInstanced(
        instancedSpec: InventoryContent.InstancedSpec,
        inventoryContent: InventoryServiceContent,
        startingInventory: InventoryData,
        pendingInventory: InventoryData,
        clientRequestExt: ExtPurchaseRequest?,
        serverRequestExt: ExtInstancedItemServerGrant?
    ): InstancedItemPlugin.InstancedItemPluginResult {
        val extInstancedItemBuilder = ExtInstancedItem.newBuilder()
        val specExt: ExtInstancedSpec = instancedSpec.ext
        return when (specExt.dataCase) {
            ExtInstancedSpec.DataCase.LASER_SWORD_SPEC -> {
                val laserSwordSpec = specExt.laserSwordSpec
                val laserSwordBuilder = extInstancedItemBuilder.laserSwordBuilder

                val damageRoll = Random.nextLong(laserSwordSpec.minDamage, laserSwordSpec.maxDamage)
                val laserSword = laserSwordBuilder
                    .setAwesomeness(laserSwordSpec.getAwesomeness(0))
                    .setDamage(damageRoll)
                    .build()

                val laserSwordInstance = extInstancedItemBuilder.setLaserSword(laserSword).build()

                InstancedItemPlugin.InstancedItemPluginResult(laserSwordInstance)
            }

            else -> error("Unknown item!")
        }
    }

    override fun update(
        initialInstancedItem: InstancedItem,
        instancedSpec: InventoryContent.InstancedSpec,
        updateEntry: InventoryContent.UpdateEntry,
        inventoryContent: InventoryServiceContent,
        startingInventory: InventoryData,
        pendingInventory: InventoryData,
        clientRequestExt: ExtInstancedItemUpdate?,
        serverRequestExt: ExtInstancedItemServerUpdate?
    ): InstancedItemPlugin.InstancedItemPluginResult {
        TODO("See the next section of this guide!")
    }
}
  1. Register your plugin by editing local-dev.yml:
game:
  pluginConfigs:
    InventoryService.instancedItemPlugin:
      class: "DemoInstancedItemPlugin"
  1. Run make ext using a terminal from the platform directory.
  2. Run Pragma Engine via one of the following methods.
Running via Make
Run make run to start the platform. Run this in a terminal with platform as the working directory.
Running in IntelliJ

From the IntelliJ toolbar in the upper right, ensure MainKt - LocalConfigured is selected, then click the play button.

If MainKt - LocalConfigured isn’t available, you will need to configure it. In the IntelliJ toolbar, click the dropdown next to the run button, then click Edit Configurations…. 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. Open Postman, then send PragmaDev ➨ Public ➨ GetInQueuev1 to enter the login queue.
  2. Log in to Pragma using Postman by sending PragmaDev ➨ Public ➨ Player - AuthenticateOrCreateV2.
  3. Use the following request body in PragmaDev ➨ Game ➨ RPC - Player ➨ Inventory ➨ storePurchaseV4 to purchase the starter bundle from the freeVendor:
{
  "requestId": 1,
  "type": "InventoryRpc.StorePurchaseV4Request",
  "payload": {
    "data" : {
      "ext": {},
      "storeId": "freeVendor",
      "storeEntryId": "starterBundle",
      "amount": 1
    }
  }
}
  1. Send storePurchaseV4 again to purchase a laser sword by changing the storeId to shopkeeper and the storeEntryId to laserSword. Confirm the cost was subtracted from the currency amounts, and that the inventory contains a laserSword that deals between 21 and 42 damage.
{
  "requestId": 1,
  "type": "InventoryRpc.StorePurchaseV4Request",
  "payload": {
    "data" : {
      "ext": {},
      "storeId": "shopkeeper",
      "storeEntryId": "laserSword",
      "amount": 1
    }
  }
}