Setting Up the Item Catalog and Store #
In this section, we’ll be defining the item catalog, store, and associated type definitions.
Define the item catalog #
The ItemCatalog
defines the specification for game content managed by the platform. Item definitions include a shared identifier between the platform and game code, and allow custom inventory details for any kind of content managed by the platform.
This section covers creating
instanced
Unique items where two copies of the same item can have different qualities. and
stackable item
Identical items where all copies of the same item are fully interchangeable. specs, which are customizable by defining custom types within extension (ext
) fields.
Get started #
Run the following command in the terminal from the platform
directory:
make skip-tests protos engine ext
Define item types with protobufs #
The structure of instanced and stackable items are defined in
protobuf
A format for efficiently serializing structured data that's cross-platform and compatible with several languages. files defined by the engine. Custom protobuf definitions can be added to extension (ext
) fields. These are predefined protobuf types that can be modified to extend engine functionality.
In this section, we’ll be defining the instanced item spec for pets, along with the pet evolution specs. These proto definitions will match the JSON content we defined below, allowing the engine to load and process the custom data types.
Edit the inventory content ext file #
This is where we’ll define the pet and pet evolution specifications. The inventory content ext file is where content specs are defined. You can think of these as blueprints that your plugin will use to build the actual items.
- Open
5-ext/ext-protos/src/main/proto/shared/inventoryContentExt.proto
. - Edit
ExtInstancedSpec
:
Note that certain protos already exist and require editing. Other protos require you to create them. In this case, the ExtInstancedSpec
proto already exists and must be edited to match the given example.
message ExtInstancedSpec {
string name = 1;
oneof data {
PetSpec pet_spec = 2;
}
}
Theoneof data
is what will later becomeDataCase
. If you name it something likeinfo
, your protos will have anInfoCase
instead.
- Create the
PetSpec
andPetBonus
protos beneath theExtInstancedSpec
message:
message PetSpec {
repeated PetBonus bonuses = 1;
int64 bonus_min = 2;
int64 bonus_max = 3;
}
enum PetBonus {
UNUSED = 0;
XP_BONUS = 1;
GOLD_BONUS = 2;
LUCK_BONUS = 3;
}
- Edit
ExtPurchaseRequirements
:
message ExtPurchaseRequirements {
oneof data {
PetEvolutionRequirements pet_evolution_requirements = 1;
}
}
- Create the
PetEvolutionRequirements
proto:
message PetEvolutionRequirements {
string required_pet_catalog_id = 1;
string required_player_location = 2;
}
- Edit
ExtCraftingEntry
:
message ExtCraftingEntry {
oneof data {
PetEvolutionSpec pet_evolution_spec = 1;
}
}
- Create the
PetEvolutionSpec
proto:
message PetEvolutionSpec {
string target_pet_catalog_id = 1;
int64 bonus_increment = 2;
}
- Edit
ExtUpdateEntry
:
message ExtUpdateEntry {
oneof data {
PetEvolutionSpec pet_evolution_spec = 1;
}
}
Edit the inventory ext file #
This is where we’ll define attributes for our pets. This represents the actual item that our plugin will create and the engine will manage in the player’s inventory.
- Open
5-ext/ext-protos/src/main/proto/shared/inventoryExt.proto
. - Add the following imports:
import "shared/inventoryContentExt.proto";
- Edit
ExtInstancedItem
:
message ExtInstancedItem {
oneof data {
Pet pet = 2;
}
}
- Create the
Pet
proto:
message Pet {
PetBonus bonus = 1;
int64 bonus_amount = 2;
}
Edit the inventory RPC ext file #
This is where we define request parameters that are passed when calling APIs to grant content. This file contains request objects for APIs called by untrusted sources (such as the game client) and trusted sources (such as the admin operator APIs). The trusted request objects are easier to test with, so we’ll use them in this example.
- Open
5-ext/ext-protos/src/main/proto/shared/inventoryExt.proto
. - Add the following imports:
import "shared/inventoryExt.proto";
- Edit
ExtCraftRequest
:
message ExtCraftRequest {
oneof data {
PetEvolutionRequest pet_evolution_request = 1;
}
}
- Create the
PetEvolutionRequest
proto:
message PetEvolutionRequest {
string crafting_location = 1;
}
- Edit
ExtInstancedItemServerGrant
by inserting the following:
message ExtInstancedItemServerGrant {
oneof data {
PetEvolution pet_evolution = 1;
}
}
- Create the
PetEvolution
proto:
message PetEvolution {
ext.Pet pet = 1;
}
Run make ext
using a terminal from the platform
directory.
Define instanced item specs #
If you haven’t yet initialized your 5-ext
content, you’ll need to run the following command to create the content JSON files. Run make init-inventory-content
using a terminal from the platform
directory.
Replace the contents of platform/5-ext/content/src/InstancedSpecs.json
with the following code:
[
{
"catalogId": "fireDragon",
"name": "fireDragon",
"tags": ["avatar", "dragon", "fire"],
"ext": {
"petSpec": {
"bonuses": ["XP_BONUS", "GOLD_BONUS", "LUCK_BONUS"],
"bonusMin": 5,
"bonusMax": 10
}
}
},
{
"catalogId": "fireDragon2",
"name": "fireDragon2",
"tags": ["avatar", "dragon", "fire"]
}
]
In this section, we’re defining two different fireDragon
s.
The base fireDragon
has additional properties defined in the ext
field, which will be used by the pet crafting plugin to generate specific instances of fireDragon
.
fireDragon2
does not have ext
s field for the purposes of this example—fireDragon
is obtainable from the store while fireDragon2
is only obtainable via crafting.
Define stackable item specs #
Next we’ll define an in-game currency and the materials necessary to purchase the pet familiar.
Replace the contents of platform/5-ext/content/src/StackableSpecs.json
with the following code:
[
{
"catalogId": "gold",
"name": "gold",
"limit": 1000000,
"tags": ["currency"],
"removeIfNone": false
},
{
"catalogId": "fireShard",
"name": "fireShard",
"limit": 10000,
"tags": ["material"]
},
{
"catalogId": "fireGem",
"name": "fireGem",
"limit": 10,
"tags": ["material"]
}
]
Stackable items are items with no special properties. Each item in the stack is identical.
Define the store #
We’ll use the store API to purchase the pet. In a game, this could be presented as interacting with a dragon caretaker or using an altar. The store API can be leveraged for many interactions beyond just basic NPC shopkeepers.
Replace the contents of platform/5-ext/content/src/Stores.json
with the following code:
[
{
"id": "materialShop",
"name": "Material Shop",
"storeEntries": [
{
"id": "craftingKit",
"receivedQuantityByCatalogId": {
"gold": 2000,
"fireShard": 2000,
"fireGem": 2,
"fireDragon": 1
}
}
]
}
]
In this section, we’re defining a store with only one purchasable entry. This entry costs nothing and grants the purchaser everything necessary to craft a fireDragon2
.
Define the crafting catalog #
While we used the store API to purchase our dragon from a caretaker, we need to use the more flexible crafting API to power the dragon evolution step.
Replace the contents of platform/5-ext/content/src/CraftingEntries.json
with the following code:
[
{
"id": "fireDragon2Evolution",
"stackableCostByCatalogId": {
"gold": {
"cost": 2000
},
"fireShard": {
"cost": 2000
},
"fireGem": {
"cost": 2
}
},
"ext": {
"petEvolutionSpec": {
"targetPetCatalogId": "fireDragon2",
"bonusIncrement": 2
}
},
"requirements": {
"ext": {
"petEvolutionRequirements": {
"requiredPetCatalogId": "fireDragon",
"requiredPlayerLocation": "fireLake"
}
}
}
}
]
In this section, we define a crafting catalog that allows the player to evolve their fireDragon
into a fireDragon2
when they have the necessary materials and initiate crafting from the fireLake
.
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.