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 #
- 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 anext
field can cause false syntax error. Create a local variable with a manually assigned type to hold protoext
fields, as we’ve done withspecExt
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!")
}
}
- Register your plugin by editing
local-dev.yml
:
game:
pluginConfigs:
InventoryService.instancedItemPlugin:
class: "DemoInstancedItemPlugin"
- Run
make ext
using a terminal from the platform directory. - 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
.
- Log in to Pragma using Postman by sending
PragmaDev ➨ Public ➨ Player - AuthenticateOrCreateV2
. - Use the following request body in
PragmaDev ➨ Game ➨ RPC - Player ➨ Inventory ➨ storePurchaseV4
to purchase the starter bundle from thefreeVendor
:
{
"requestId": 1,
"type": "InventoryRpc.StorePurchaseV4Request",
"payload": {
"data" : {
"ext": {},
"storeId": "freeVendor",
"storeEntryId": "starterBundle",
"amount": 1
}
}
}
- Send
storePurchaseV4
again to purchase a laser sword by changing thestoreId
toshopkeeper
and thestoreEntryId
tolaserSword
. Confirm the cost was subtracted from the currency amounts, and that the inventory contains alaserSword
that deals between 21 and 42damage
.
{
"requestId": 1,
"type": "InventoryRpc.StorePurchaseV4Request",
"payload": {
"data" : {
"ext": {},
"storeId": "shopkeeper",
"storeEntryId": "laserSword",
"amount": 1
}
}
}