Game Dev Update: Consuming Potions

healing potions in an inventory

In The Dripstone Caverns, users will be able to collect healing potions that they will use in the game to replenish hit points lost in battle. They will be able to “drink” these potions to initiate that action, and in doing so will actually destroy the NFT. In the last update I had implemented a way to mint and send NFT rewards when the user defeats an enemy. As I said, that was going to the be basis for all transactions moving forward, so consuming items is going to look fairly similar.

First Things

I created a new Schema for the collection called “potions” and then a new Template for token called “Healing Potion.”

Healing Potion
Healing Potion

It doesn’t need much information, because it will just be the required token to be destroyed – the game will handle the rest. It has its name, the image above, and a short description, “A potion to heal all wounds.”

Using the Potion

The user will be able to see all the potions in their inventory. This is the first potion, but I don’t expect that it will be the only potion in the game. Under each potion, the user will have the option to drink the potion.

two healing potions in an inventory

When the user drinks the potion, that NFT will be transferred and burned. The game will wait for the transaction to succeed, and then for testing purposes, it will adjust the character’s hit points to 100.

Make it Work

When I implemented the loot system I went into detail about getting these APIs up and running, so I’m just going to jump into it here.

First I need a route in my backend to update the character in the database. For the sake of making it work, it’s just going to update the hit points for the character NFT provided. In production, it will want to verify the transaction of the potion before doing anything. Make it work:

back end api function

Redux controls the state of the character, so it will be the one calling the API. I need an AsyncThunk that I’m simply calling “drinkPotion” that will use a few different builders depending on the status of the API call:

redux function

The builders set loading status before the API is called, then once it’s called it sets the selectedCharacter state to the updated character (which will now have 100 hit points)

redux builder code

Finally, I need React on the front end to make the transaction actually happen. I implemented the “drink” button which will call the “handleDrinkPotion” function, passing the potion’s NFT ID.

I’ll first call my WAX login function again to make sure the user is still connected, ensuring that wax.api is still available. Then I’m going to send the transaction. As I said, in production, the user will burn the NFT calling the “burnasset” action. For testing purposes, I’m simply transferring the tokens between wallets. It’s easier to transfer them back from the game wallet to my testing wallet, than to mint and send new tokens to the test wallet.

react front end code

After the transaction is processed, I check that the status is ‘executed’ and if so I call the Redux drinkPotion function with the character’s NFT to be updated. It will also reset any Game Over status if that’s the case. It takes some time for the blockchain to process the data, so I set a delay before React calls fetchAssets() again, which will refresh the array of potions in the user’s inventory.

Wrapping Up

This was another big system to implement. As I said when I first got transactions going, a lot of what comes next builds upon that.

I’m also working on improving the UI and CSS as I go. For example, this is a much better way to display 26 Rat Pelts:

The next thing I want to start doing with transactions is to modify the data of character NFTs, and to start moving some of that database information to the character’s NFT itself, allowing the user permanently save the current state of the character. Starting to really get into the fun blockchain stuff, so I’ll get into that in the next update.

Leave a Reply

Your email address will not be published. Required fields are marked *