How to create items in Reldens?

In this section I will describe the process to create different item types.

You can have any item types in Reldens but the most implemented ones are:

  • Usable (like potions or bombs)
  • Equipment (any kind)
  • Base (any stuff that won’t trigger an specific action, like coins, or craft items)


The steps to include a new item in the game are:

1 - Get your database ready

2 - Get your objects and classes ready

3 - Get your assets ready

4 - Build your client

5 - Reload / run your Server and be happy!

Let’s go through these…

Note, the skeleton repository master branch doesn’t contain the modifications commented on this doc, to find these changes you can visit the master-docs-examples branch: https://github.com/damian-pastorini/reldens-skeleton/tree/master-docs-examples


1 - Preparing the database


For this example we are going to create 2 new items, one usable and one equipment.

Go to your database and insert two new records on the “items_item” and on the “items_item_modifiers” tables (these are for the “usable” item):

INSERT INTO `items_item` (`id`, `key`, `group_id`, `label`, `description`, `qty_limit`, `uses_limit`, `useTimeOut`, `execTimeOut`) VALUES (6, 'magic_potion', NULL, 'Magic Potion', 'A magic potion that will restore 20 MP.', 0, 1, NULL, NULL);

INSERT INTO `items_item_modifiers` (`id`, `item_id`, `key`, `property_key`, `operation`, `value`, `maxProperty`) VALUES (4, 6, 'magic_potion', 'stats/mp', 1, '20', 'initialStats/mp');

Side note: as you can see I’m using hard coded IDs for the sake of the example, but you may better use NULL and get the ID for the related INSERT.

Then insert two new records for the “equipment” item:

INSERT INTO `items_item` (`id`, `key`, `group_id`, `label`, `description`, `qty_limit`, `uses_limit`, `useTimeOut`, `execTimeOut`) VALUES (7, 'wooden_shield', 2, 'Wooden Shield', 'A wood shield.', 0, 0, NULL, NULL);

INSERT INTO `items_item_modifiers` (`id`, `item_id`, `key`, `property_key`, `operation`, `value`, `maxProperty`) VALUES (5, 7, 'def', 'stats/def', 5, '3', NULL);

Here you can see I’m using the group_id = 2 which corresponds to a pre-generated group used in Reldens called “shield”. In Reldens demo the groups are used to equip the item in the proper group.


2 - Objects and classes


First let’s create the item required classes, for that go to the folder:

[skeleton-root]/packages/inventory/items

And create a new file with the following contents, "magic-potion.js":

const { ItemSingleUsable } = require('@reldens/items-system');

class MagicPotion extends ItemSingleUsable
{

 constructor(props)
 {
 super(props);
 this.removeAfterUse = true;
 this.animationData = {
 frameWidth: 64,
 frameHeight: 64,
 start: 6,
 end: 11,
 repeat: 0,
 hide: true,
 destroyOnComplete: true,
 usePlayerPosition: true,
 closeInventoryOnUse: true,
 followPlayer: true,
 startsOnTarget: true
 };
 }

}

module.exports.MagicPotion = MagicPotion;


As you can see this one extends from the proper class of the @reldens/items-system.

The “Single” on the class name is for a shortcut to make that item a single instance class (you can read more about it here: https://github.com/damian-pastorini/reldens-items/blob/master/lib/item/type/single.js )

We only create a class for the magic potion items since we need to define all the attributes for the animations used later in Phaser (some are custom properties to make Phaser do specific stuff), when you “use” a potion a “heal” effect animation will be played over the player.

Now we need to tell Reldens that these items are available and the instance class each item will use, for that we need to edit two files:

[skeleton-root]/theme/packages/client.js

[skeleton-root]/theme/packages/server.js

And in both files you will find the custom classes tree with some default items in the inventory, like:

 inventory: {
 items: {

So here you will need to require and add the two new classes in the export:

const { MagicPotion } = require('./inventory/items/magic-potion');
const { ItemSingleEquipment } = require('@reldens/items-system');
// ...
module.exports.CustomClasses = {
 // ...
 inventory: {
 items: {
 // ...
 magic_potion: MagicPotion,
 wooden_shield: ItemSingleEquipment,
// ...

Note we can use the same object and set up the animation data here since we never execute / use this item, though the item instance is created on the client, this is never executed so we can call this data when we get the item confirmation that was executed on the server (sounds more complex that what it really is):

> same item object is used in the server and in the client

> the client click on an item to execute it, but actually only the item key is sent to the server

> the server gets the items (validating the action) and execute it on the player

> then the server sends the execution to the client

> the client receives the message and runs the animation using this data that it already has on it.

Next, we need to associate the items to some game object that will provide them to the player, like an NPC or as an enemy drop. Lucky me we already have some examples for this which I’m going to reuse, but if you like to create your own Objects, NPCs or Enemies the guide is soon to come (I will replace this by the link as soon it’s ready).

So where are these examples? Go to the folder:

[skeleton-root]/theme/packages/objects/server


Here you will find two files that we will modify:

healer.js

weapons-master.js

When edit the healer.js you will see around line 53 that it’s already giving an item when you choose not to be heal:

https://github.com/damian-pastorini/reldens-skeleton/blob/6b8563a8f38976f67ae08beb20ba3e108916a203/theme/packages/objects/server/healer.js#L53

So we are going to modify that block of code to give you the new Magic Potion as well:

// ...
} else {
 let errorCount = 0;
 let healPotion = playerSchema.inventory.createItemInstance('heal_potion_20');
 playerSchema.inventory.manager.addItem(healPotion).catch((err) => {
 errorCount++;
 Logger.error(['Error while adding item "heal_potion_20":', err]);
 });
 let magicPotion = playerSchema.inventory.createItemInstance('magic_potion');
 playerSchema.inventory.manager.addItem(magicPotion).catch((err) => {
 Logger.error(['Error while adding item "magic_potion":', err]);
 errorCount++;
 });
 if(errorCount === 0){
 let responseMessage = 'Then I will give you some items for later, you never know...';
 let activationData = {act: GameConst.UI, id: this.id, content: responseMessage};
 room.send(client, activationData);
 } else {
 let contentMessage = 'Sorry, I was not able to give you the extra items.';
 room.send(client, {act: GameConst.UI, id: this.id, content: contentMessage});
 return false;
 }
}
// ...

Then edit the weapons-master.js and this is quite easier since we only need to modify the options.

Around line 27, add the wooden shield as 3rd option:

 this.options = {
 op1: {key: 'axe', label: 'Axe', value: 1, icon: 'axe'},
 op2: {key: 'spear', label: 'Spear', value: 2, icon: 'spear'},
 op3: {key: 'wooden_shield', label: 'Wooden Shield', value: 3, icon: 'wooden_shield'}
 };

And that’s it, now you have from where you can get the items in the game.


3 - Objects assets


The assets live in your custom theme folder, in the skeleton demo this folder name is: “custom-game-theme-test” but you can rename it to whatever you like, for example “my-crazy-game-theme”.

Inside this folder you need to follow the path for the items folder:

[skeleton-root]/theme/[your-theme-folder]/assets/custom/items

And there you need to place the images/thumbnails for your objects:

[skeleton-root]/theme/[your-theme-folder]/assets/custom/items/wooden_shield.png

[skeleton-root]/theme/[your-theme-folder]/assets/custom/items/magic_potion.png

Then you need the one for the magic potion animation which is an animation and goes with the sprites:

[skeleton-root]/theme/[your-theme-folder]/assets/custom/sprites/magic_potion.png

Note all the images are called after the item "key" value in the database.


4 - Build your client


As you may / should know everything related to the client side of the project must be build in order to make it work. By default Reldens comes with Parcel to run these builds.

The Skeleton package provides some commands to re-run the build after you customize the project.

The first you need to run is the “[your-OS-prefix]BuildClient” command (replacing [your-OS-prefix] by “windows” or “linux”, and adding --them=[your-theme-folder] as parameter, in my case all this translates to:

$ npm run windowsBuildClient --theme=custom-game-theme-test

After that and since we included new images we need to copy those as well, for that we need to use the command “[your-OS-prefix]CopyCustomAssets” and pass the theme name as well, like:

$ npm run windowsCopyCustomAssets --theme=custom-game-theme-test


5- Start your server and be happy!


$ npm start