19 minutes

Build a Star Wars RPG bot with Bot Connector by Recast.AI!

What are we going to build ?

A bot!

The bot we are going to build is a role playing game (RPG) bot around the Star Wars universe. This bot will be created with Recast.AI and Bot Connector. 

You will be able to use this bot on Facebook Messenger and on Kik, and you can find the finished product here!

What is a RPG bot ?

Well, it can be defined as a bot who does not just provide information, but makes you an actor in a compelling story. Each of your answers will take you on a different storyline.

If you’d like to know more about where we got the idea, read this Gamesbook Wikipedia page.

What are we going to learn ?

This bot is developed in NodeJs, and we’ll use ES5.

We’re using the Recast.AI technology, Recast.AI is a collaborative platform for bot making. We provide an API that will help you understand your users, to guide the conversation.

Everything we use will be explained step by step.

First step, for any part of the tutorial, is to create your Recast.AI account!

Star Wars Bot V1

Create your bot on Bot Connector

Bot Connector allows you to connect your bot to multiple channels at the same time with only one API integration.

Login to  Bot Connector with your Recast.AI account.

Home-bot-connector

Let’s start by creating a new bot, pick a name you like.

To create the URL of you bot, create a webhook. That will create a tunnel from your bot to Bot Connector. We’re using a ngrok webhook, but you can use any kind of webhook you like. If you don’t have ngrok, check this out to get started.

Open the terminal and type:

ngrok http 5000

ngrokUrl
Copy paste your bot url:

Creat your bot

Nice, you now have a first version of your bot! Now, let’s connect it to channels.

Bot Connector has two main areas:

– in the orange selection, pick the channel you want

– in the purple selection, configure your integration

In this tutorial, we’ll cover the Messenger integration, feel free to discover Slack and Kik on your own. 🙂

set-up-your-channel

So, you need two things: your page token and your app token.

You’ll find you page token here:

https://developers.facebook.com/apps/YOUR-APP-ID/messenger/

and your app token here:

https://developers.facebook.com/apps/YOUR-APP-ID/dashboard/

After adding your channel, the connector will send you back a url and a webhook token. Put those information in the Facebook Developer page.

You now have a bot connected to Facebook!

But we still need to code the bot 😀

Setup the code

Much like before, we’re going to start from scratch. But if you like to move faster, you can clone the code from this repo.

mkdir bot-starwars && cd bot-starwars

What your repertories and files will look like:

├── config
│   └── index.js
├── package.json
|
└── src
 |
 ├── botConnector.js
 └── server.js

Create your config.js file:

You will find all your bot-connector credentials on the settings tab.

bot-connector-Tokens

vim config/index.js
const config = {}

config.botToken = 'Bot token'
config.url= 'https://api-botconnector.recast.ai'
config.botId = 'Bot id from bot-connector'
config.slug = 'Usename of bot-connector'
module.exports = config

Create your server.js

You need 3 different modules for these two files:

-Express will be your server,

-Body-parser will parse the response from the word wide web,

-Superagent will make the Post back to the server,

npm install --save express body-parser superagent

The following file creates a server and connects the web chat service of your choice (Kik, Slack, Messenger, ….) to your bot.

vim src/server.js
const express = require('express')
const bodyParser = require('body-parser')
const sendMessage = require('./botConnector')
const config = require('../config')

const app = express()
app.set('port', process.env.PORT || config.port || 5000)
app.use(bodyParser.json())

/* Get the request from the connector */

app.post('/', (req) => {
 const { attachment, conversation } = req.body.message
 const senderId = req.body.senderId
 const messages = [{ type:'text', content:'Hello'}] // send your first message
 sendMessage(messages, senderId, conversation)

})
app.listen(app.get('port'), () => { console.log('Our bot is running on port', app.get('port')) })

You need a function to send the message back to Bot Connector. This function is really simple and will only send the message you formatted back to Bot Connector.

vim src/botConnector.js
const request = require('superagent')
const config = require('../config')

function sendMessage(messages, senderId, conversationId) {
   return new Promise((resolve, reject) => {
     request.post(`${config.url}/users/${config.slug}/bots/${config.botId}/conversations/${conversationId}/messages`)
       .set('Authorization', `Token ${config.botToken}`)
       .send({ messages, senderId })
       .end((err) => {
         if (err) {
           console.log('err =', err)
           reject()
         } else {
           resolve()
         }
       })
    })
}

module.exports = sendMessage

You should be ready to receive a message from Facebook! Let’s try 🙂

npm run start

Next, we’re going to see how to make your bot smarter!

Setup the bot

We’re going to create the bot from scratch, and the first step takes place on Recast.AI. If you’re familiar with the platform and want to directly dive in the code, you can find the bot here and fork it. If not, let’s get started!

Create the bot:

Create your bot

Create your intent, An intent is a box of expressions that mean the same thing but are constructed in different ways. Intents are the heart of your bot understanding. Each one of your intents represents one thing your bot is able to understand.

We need these first three intents to initiate the conversation of the bot. In each intent, enter expressions. You should put at least 10 sentence for your bot to  be able to understand, and we advise you to put around 20 sentences for a really good classification.

Intent

Greetings: any possible way to say “hello”

The next intent will be a little different: you will need to tag a entity!

An entity is a keyword extracted from an expression. We automatically detect 31 different entities such as datetimes, names, locations, etc. We call them Gold entities. But you are not limited to these Gold entities: you can also tag your own custom entities to detect keywords depending on your bot context, such as metro stations if you are building a transport assistant. To bring you a precise service with a true added value, we are enriching each of our Gold entities with core information.

Which-space-ship: simple sentences with the name of a Star Wars spaceship.

All spaceship names need to be tagged with your custom entity “spaceship”

Where-are-you-from: same as the previous intent, but with custom entity “planet”.

These three intents are the initiation of the conversation. Now, to create a unique experience and story for the user, let’s jump into Bot Builder!

bot-builder

Each intent becomes an action. Put your three actions on the map, and connect them to each other. Use a green link between greetings and where-are-you-from and use a red link between where-are-you-from and which-space-ship. That means that while greetings is an action that can be skipped, where-are-you-from is necessary to continue to the next action.

botV1

After adding your first 3 actions, you need to set up notions and replies in where-are-your-from and which-space-ship. Notions match entities, and are keywords your bot needs to know at this point of the conversation to move forward. Replies are specific answers your bot should give after the action is completed or when a notion is missing. In this case, set up a reply if “PLANET” is missing, but don’t set up one when the action is done. This stands for the entire tutorial.

Add notion

add reply to notion

Now that your architecture is all good on the platform, let’s dive into the code.

 New architecture:

├── config
│   └── index.js
├── package.json
└── src
 ├── bot
 │   ├── bot.js
 ├── botConnector.js
 ├── formatServices
 │   ├── carouselSpaceShip.js
 │   ├── initConversation.js
 └── server.js

Add Recast.AI token to config/index.js:

Copy paste the Request access token:

recast-ai-token

new config :

const config = {}

config.recastToken = 'Recast token'
config.language = 'en'
config.botToken = 'Bot token'
config.url= 'https://api-botconnector.recast.ai'
config.botId = 'Bot id from bot-connector'
config.slug = 'Usename of bot-connector'
module.exports = config

Create your bot.js

You will need to add the Recast.AI module for your code to run.

npm install --save recastai

The following file is your state machine. It decides what to answer according to the user reply and the conversation advancement.

mkdir src/bot && vim src/bot/bot.js

The function handleMessage() will send the text to Recast.AI.

function handleMessage(messageText, senderID, conversation) {
 client.textConverse(messageText.content, { conversationToken: senderID }).then((res) => {
   const { action } = res
   let messages = []

   if (action) {
     if (action.reply) {
       messages = [{ type: 'text', content: action.reply }]
       sendMessage(messages, senderID, conversation)
     } else {
       engineFunction(senderID, action).then(m => sendMessage(m, senderID, conversation))
     }
   } else {
     messages = [{ type: 'text', content: 'bip......bip..bip..bip, my CPU is overloaded :( Could you please reformulate?' }]
     sendMessage(messages, senderID, conversation)
   }
 }).catch(err => console.log('err recast = ', err))
}

Recast.AI will send back a JSON with key informations (intent and matching ratio, entity and matching ratio, sentiment analysis, etc). This data helps you decide what you should reply.

After getting the response, check if the action has an answer setup on Bot Builder. If it doesn’t, call a engineFunction()

function engineFunction(senderID, action) {
 return new Promise(resolve => {

   if (action.slug === 'greetings') {
     resolve(initConversation())
   } else if (action.slug === 'where-are-you-from') {
     resolve(carouselSpaceShip())
   } else if (action.slug === 'which-space-ship') {
     resolve([{type: ‘text’, content: ‘to be continue’}])
   }
 })
}

This function will call a function for each state of conversion and will format the message, to send back to the user.

You file should look like this:

const config = require('../../config/')
const Client = require('recastai').Client
const sendMessage = require('../botConnector')
const initConversation = require('../formatServices/initConversation.js')
const carouselSpaceShip = require('../formatServices/carouselSpaceShip.js')
const client = new Client(config.recastToken, config.language)

function engineFunction(senderID, action) {
 return new Promise(resolve => {

   if (action.slug === 'greetings') {
     resolve(initConversation())
   } else if (action.slug === 'where-are-you-from') {
     resolve(carouselSpaceShip())
   } else if (action.slug === 'which-space-ship') {
     resolve([{type: 'text', content: 'to be continue'}])
   }
 })
}

function handleMessage(messageText, senderID, conversation) {
 client.textConverse(messageText.content, { conversationToken: senderID }).then((res) => {
   const { action } = res
   let messages = []

   if (action) {
     if (action.reply) {
       messages = [{ type: 'text', content: action.reply }]
       sendMessage(messages, senderID, conversation)
     } else {
       engineFunction(senderID, action).then(m => sendMessage(m, senderID, conversation))
     }
   } else {
     messages = [{ type: 'text', content: 'bip......bip..bip..bip, my CPU is overloaded :( Could you please reformulate?' }]
     sendMessage(messages, senderID, conversation)
   }
 }).catch(err => console.log('err recast = ', err))
}

module.exports = handleMessage

We are going to have a look at the the files in formatServices:

initConversation(), carouselSpaceShip() are really simple. These two functions only return a array of a preformatted  message example: 

[{
type: 'text', 
content: 'My first message', 
}]

Type is what kind of message you will send.

Content is the body of your message, have a look at this doc 🙂

This function gets really long, so I created two gists on Github. Have a look:

initConversation() = github gist

carouselSpaceShip() = github gist

In the files, you will find the response your bot sends to the user. Don’t forget to put this file in your formatServices!

mkdir src/formatServices && vim src/formatServices/initConversation.js && vim src/formatServices/carouselSpaceShip.js

 Run your new Bot.

Before running the bot,  you need to change your server.js

Your new server.js will look like this:

const express = require('express')
const bodyParser = require('body-parser')

const handleMessage = require('./bot/bot.js')
const config = require('../config')

const app = express()
app.set('port', process.env.PORT || config.port || 5000)
app.use(bodyParser.json())

/* Get the request from the connector */

app.post('/', (req) => {
 const { attachment, conversation } = req.body.message
 const senderId = req.body.senderId
 handleMessage(attachment, senderId, conversation)
})

app.listen(app.get('port'), () => {
 console.log('Our bot is running on port', app.get('port'))
})

Run your bot:

npm run start

Now, you should be able to have your first conversation!  🙂

Star Wars Bot v2

Teach the v2 of your bot

Let’s create new intents! You can fork all of them to skip this step here.

Name of intent Type of sentence to trigger the intent entities you need to tag
space-battle
  • use your lazer
  • try to avoid fight
  • use my blaster
  • lazer
  • avoid fight
  • blaster

as attacks

fix-ship
  •  hum I am a good mecano i will do the work.
  • the droid can do a find job
  • send the droid
NULL
battel
  • use you lightsaber
  • use the force
  • run like a coward
  • lightsaber,
  • force,
  • coward

as attacks

riddle-response
  • Fight the AT-ST
  • Fight the Wampa
  • I will fight the Wanpa
  • i need to fight the AT_ST
  • at-st
  • AT_ST

as atst

  • Wampa
  • wampa

as wampa

space-trip
  • Travel to space
  • visiting space sound fun
  • let’s visit space
NULL
training
  • fly to Dagobah
  • yes let’s go to Dagobah !
  • I will follow my training
NULL

The last intent you make is not used in the classification, it’s simply here to create two new files in the memory of your bot.

memory
  • MonsterHp
  • Myhp
  • MonsterHp as MonsterHp
  • MyHp as Myhp

Build the v2 of your bot

Let’s jump back in the Builder and start building the end of the flow. It’s really easy, simply create a conversation flow like this one. We only focus on the orange path here, but take the time to create the rest 🙂

Add 4 new actions : training, riddle-response, battle-vs-monster and memory. Put the memory on top left, and connect the 3 other with a red link.

bot-builder-v2

Add two notions to the action “memory”:

Add-notion

Update the code of your bot’s V2

Your new architecture:

├── config
│   └── index.js
├── package.json
└── src
 ├── bot
 │   ├── bot.js
 │   ├── handleBattle.js
 │   ├── handleMemory.js
 │   └── handleRiddle.js
 ├── botConnector.js
 ├── formatServices
 │   ├── carouselSpaceShip.js
 │   ├── choseTraing.js
 │   ├── Combat.js
 │   ├── initConversation.js
 │   ├── riddle.js
 │   └── trainingMessage.js
 └── server.js

Let’s go back to the bot.js file and add a few functions:

const config = require('../../config/')
const Client = require('recastai').Client
const sendMessage = require('../botConnector')
const initConversation = require('../formatServices/initConversation.js')
const carouselSpaceShip = require('../formatServices/carouselSpaceShip.js')

/* the new function of formating */
const choseTraing = require('../formatServices/choseTraing.js')
const trainingMessage = require('../formatServices/trainingMessage.js')

/* function to make the story interactive */
const initMemory = require('./handleMemory.js')
const handleRiddleRetry = require('./handleRiddle.js').handleRiddleRetry
const handleBattle = require('./handleBattle.js')

const client = new Client(config.recastToken, config.language)

 

Much like before, engineFunction() checks what action is called and triggers the right function:

function engineFunction(res, action, senderID) {
  return new Promise(resolve => {
    // Get the notion from the builder
    const myHp = res.getMemory('my_hp')
    const monsterHp = res.getMemory('monster_hp')
    const { entities } = res
   
    /*This big stack of else if is just to see what depending on which action we have we trigger a function*/
    if (action.slug === 'greetings') {
      initMemory(senderID)
      resolve(initConversation())
    } else if (action.slug === 'where-are-you-from') {
      resolve(carouselSpaceShip())
    } else if (action.slug === 'which-space-ship') {
      resolve(choseTraing())
    } else if (action.slug === 'training') {
      resolve(trainingMessage())
    } else if (action.slug === 'riddle-response') {
      resolve(handleRiddleRetry(entities, senderID))
    } else if (action.slug === 'battle-vs-monster') {
      handleBattle(entities, myHp, monsterHp, senderID).then(r => resolve(r))
    } 
  })
}

The function handleMessage() does not change.

Your file bot.js should look like this:

const config = require('../../config/')
const Client = require('recastai').Client
const sendMessage = require('../botConnector')
const initConversation = require('../formatServices/initConversation.js')
const carouselSpaceShip = require('../formatServices/carouselSpaceShip.js')

/* the new function of formating */
const choseTraing = require('../formatServices/choseTraing.js')
const trainingMessage = require('../formatServices/trainingMessage.js')

/* function to make the make the story interactive */
const initMemory = require('./handleMemory.js')
const handleRiddleRetry = require('./handleRiddle.js').handleRiddleRetry
const handleBattle = require('./handleBattle.js')

const client = new Client(config.recastToken, config.language)

 function engineFunction(res, action, senderID) {
  return new Promise(resolve => {
    // Get the notion from the builder
    const myHp = res.getMemory('my_hp')
    const monsterHp = res.getMemory('monster_hp')
    const { entities } = res
   
    /*This big stack of else if is just to see what depending on which action we have we trigger a function*/
    if (action.slug === 'greetings') {
      initMemory(senderID)
      resolve(initConversation())
    } else if (action.slug === 'where-are-you-from') {
      resolve(carouselSpaceShip())
    } else if (action.slug === 'which-space-ship') {
      resolve(choseTraing())
    } else if (action.slug === 'training') {
      resolve(trainingMessage())
    } else if (action.slug === 'riddle-response') {
      resolve(handleRiddleRetry(entities, senderID))
    } else if (action.slug === 'battle-vs-monster') {
      handleBattle(entities, myHp, monsterHp, senderID).then(r => resolve(r))
    } 
  })
}
function handleMessage(messageText, senderID, conversation) {
  client.textConverse(messageText.content, { conversationToken: senderID }).then((res) => {
    const { action } = res
    let messages = []

    if (action) {
      /* If we have a reply on the builder */
    if (action.reply) {
      messages = [{ type: 'text', content: action.reply }]
      sendMessage(messages, senderID, conversation)
     } else {
     /* Create are own reply */
       engineFunction(res, action, senderID).then(m => sendMessage(m, senderID, conversation))
     }
   } else {
     messages = [{ type: 'text', content: 'bip......bip..bip..bip, my CPU is overloaded :( Could you please reformulate?' }]
     sendMessage(messages, senderID, conversation)
    }
  }).catch(err => console.log('err recast = ', err))
}

module.exports = handleMessage

Just like initConversation() and carouselSpaceShip(), I created github gists, go and check them out!

choseTraing() = github gist

trainingMessage() = github gist

Space = github gist

Riddle = github gits

Pay specific attention to the three new functions:

initMemory()
handleRiddleRetry()
handleBattle()

Let’s start by initMemory(). This function sets the memory of your bot at an init stat each time that the user says hello.

Even if this function is asynchronous, we will not set a promise because we don’t need this information yet.

vim src/bot/handleMemory.js

const config = require('../../config')
const Conversation = require('recastai').Conversation

function initMemory(senderID) {
 Conversation.resetConversation(config.recastToken, senderID).then(() => {
   Conversation.setMemory(config.recastToken, senderID, {
     my_hp: {
       maxHp: 10,
       currentHp: 10,
     } }).catch(e => console.log('myhp = ', e))
   Conversation.setMemory(config.recastToken, senderID, {
     monster_hp: {
       maxHp: 20,
       currentHp: 20,
    } }).catch(e => console.log('monster_hp = ', e))
  })
}

module.exports = initMemory

handleRiddleRetry() 

This functions takes care of the riddle action. It detects which entities are present in the sentence and allows you to see if the user guessed right or wrong.

vim src/bot/handleRiddle.js
const Riddle = require('../formatServices/riddle.js')

function handleRiddleRetry(entities) {
  let wampa = null
  let atst = null
  entities.forEach(e => {
    if (e.name === 'wampa') { wampa = e.raw }
    if (e.name === 'atst') { atst = e.raw }
   })
  if (wampa) {
    return Riddle.resRiddle()
  } else if (atst) {
   return Riddle.repeatRiddle(false)
  }
 return Riddle.repeatRiddle(true)
}

module.exports = {
 handleRiddleRetry,
}

handleBattle()

So here’s how the fighting system works: the player has 10-HP, the opponent has 20-hp. During each attack, the player has 1 chance out of 2 to miss his shot. If his attack is successful, he does 5 to 9 damage. The opponent can not miss but can only inflict 1 to 3 damage. To make the game more interactive, we’ll make a different message for each attack.

First, find what the name of the attack is and the damage it does:

vim src/bot/handleBattle.js
function handleBattle(entities, myHp, monsterHp, senderID) {
 return new Promise(resolve => {
 const random = Math.round(Math.random() * (3 - 1) + 1)
 let damage = 0
 let attack = null
 let fuite = null
 /*find the type of attack*/
 entities.forEach(e => {
 if (e.name === 'attack') { attack = e.raw }
 if (e.name === 'fuite') { fuite = e.raw }
 })
if (random !== 3) { damage = Math.round(Math.random() * (9 - 5) + 5) }

const yourdamage = Math.round(Math.random() * (3 - 1) + 1)
 const newMonstHp = monsterHp.currentHp - damage
 const newHp = myHp.currentHp - yourdamage

Then get the memory from the Bot Builder. This is the same function than reset memory, but you need to add a promise because we need this information for the rest of this function:

if (attack) {
 /*Get the memory*/
 Conversation.setMemory(config.recastToken, senderID, {
 monster_hp: { maxHp: 20, currentHp: newMonstHp },
 }).then(() => {
 Conversation.setMemory(config.recastToken, senderID, {
 my_hp: { maxHp: 10, currentHp: newHp },
 }).then(() => {
 let nameOfAttak = null
 let nameOfBeast = null

Now the rest of the function is only wording to send the right message to the user:

let nameOfAttak = null
let nameOfBeast = null
/* Send the right message */
if (newMonstHp <= 0) { resolve(Combat.winCombat()) }
if (newHp <= 0) { resolve(Combat.lostCombat()) }
if (attack === 'force') {
  if (random === 1) { nameOfAttak = 'You Choose the force, choke the monster'; nameOfBeast = 'Enraged by the wound, the monster swings its tail at you' }
  if (random === 2) { nameOfAttak = 'You focus the Force to pick up a big tree'; nameOfBeast = 'the monster throws his big claws at you' }
  if (random === 3) { resolve(Combat.humanCombat('Your attack failed completely ', `the monster throws big fireballs at you and does ${yourdamage} damage.`, newHp, newMonstHp)) }

  resolve(Combat.humanCombat(`${nameOfAttak} and do ${damage} damage`, `${nameOfBeast} and do ${yourdamage}`, newHp, newMonstHp))
} else if (attack === 'lightsaber') {
  if (random === 1) { nameOfAttak = 'You jump in action and fight like a beast'; nameOfBeast = 'the beast hits you' }
  if (random === 2) { nameOfAttak = 'You put all your strenghts on you strongest arm and throw your lightsaber at the monster'; nameOfBeast = 'the monster throws his big claws at you' }

  if (random === 3) { resolve(Combat.humanCombat('Your attack failed completely', `the monster throws big fireballs at you and does ${yourdamage} damage.`, newHp, newMonstHp)) }
  resolve(Combat.humanCombat(`${nameOfAttak} and do ${damage} damage`, `${nameOfBeast} and do ${yourdamage} damage`, newHp, newMonstHp))
} else {
  resolve(Combat.humanCombat(`You focus the Force to pick up a big tree and do ${damage} damage.`, `the monster throws his big claws at you and do ${yourdamage} damage.`, newHp, newMonstHp))
}
}).catch(e => console.log(e))
}).catch(e => console.log(e))
} else if (fuite) {
  Conversation.setMemory(config.recastToken, senderID, {
    my_hp: { maxHp: 10, currentHp: 0 } }).then(() => resolve(Combat.runCombat()))
  } else {
     resolve(Combat.bugCombat())
  }
})
}

module.exports = handleBattle

the file should look like this :

function handleBattle(entities, myHp, monsterHp, senderID) {
  return new Promise(resolve => {
    const random = Math.round(Math.random() * (3 - 1) + 1)
    let damage = 0
    let attack = null
    let fuite = null
    /*find the type of attack*/
    entities.forEach(e => {
      if (e.name === 'attack') { attack = e.raw }
      if (e.name === 'fuite') { fuite = e.raw }
    })

    if (random !== 3) { damage = Math.round(Math.random() * (9 - 5) + 5) }

    const yourdamage = Math.round(Math.random() * (3 - 1) + 1)
    const newMonstHp = monsterHp.currentHp - damage
    const newHp = myHp.currentHp - yourdamage

    if (attack) {
     /*Get the memory*/
      Conversation.setMemory(config.recastToken, senderID, {
        monster_hp: { maxHp: 20, currentHp: newMonstHp },
      }).then(() => {
           Conversation.setMemory(config.recastToken, senderID, {
             my_hp: { maxHp: 10, currentHp: newHp },
            }).then(() => {
           let nameOfAttak = null
           let nameOfBeast = null
            /* Send the right message */
            if (newMonstHp <= 0) { resolve(Combat.winCombat()) }
            if (newHp <= 0) { resolve(Combat.lostCombat()) }
            if (attack === 'force') {
              if (random === 1) { nameOfAttak = 'You Choose the force, choke the monster'; nameOfBeast = 'Enraged by the wound, the monster swings its tail at you' }
              if (random === 2) { nameOfAttak = 'You focus the Force to pick up a big tree'; nameOfBeast = 'the monster throws his big claws at you' }

              if (random === 3) { resolve(Combat.humanCombat('Your attack failed completely ', `the monster throws big fireballs at you and does ${yourdamage} damage.`, newHp, newMonstHp)) }

              resolve(Combat.humanCombat(`${nameOfAttak} and do ${damage} damage`, `${nameOfBeast} and do ${yourdamage}`, newHp, newMonstHp))
            } else if (attack === 'lightsaber') {
              if (random === 1) { nameOfAttak = 'You jump in action and fight like a beast'; nameOfBeast = 'the beast hits you' }
              if (random === 2) { nameOfAttak = 'You put all your strenghts on you strongest arm and throw your lightsaber at the monster'; nameOfBeast = 'the monster throws his big claws at you' }

              if (random === 3) { resolve(Combat.humanCombat('Your attack failed completely', `the monster throws big fireballs at you and does ${yourdamage} damage.`, newHp, newMonstHp)) }

              resolve(Combat.humanCombat(`${nameOfAttak} and do ${damage} damage`, `${nameOfBeast} and do ${yourdamage} damage`, newHp, newMonstHp))
            } else {
              resolve(Combat.humanCombat(`You focus the Force to pick up a big tree and do ${damage} damage.`, `the monster throws his big claws at you and do ${yourdamage} damage.`, newHp, newMonstHp))
            }
         }).catch(e => console.log(e))
       }).catch(e => console.log(e))
     } else if (fuite) {
       Conversation.setMemory(config.recastToken, senderID, {
         my_hp: { maxHp: 10, currentHp: 0 } }).then(() => resolve(Combat.runCombat()))
     } else {
       resolve(Combat.bugCombat())
     }
  })
 }

 module.exports = handleBattle

Run the v2 of your bot

npm run start-dev

Talk to your bot, and enjoy the magic!

Your bot is running, it’s now up to you to create a compelling story for your users!

To help you in your bot building quest, you’ll find some other resources on our blog, such as a complete tutorial on our Bot Builder, our best practices for bot building, or this ultimate channel cheat sheet to help you pick the best one for your use case!

Happy coding 😀

Henri Floren – Recast.AI

Share on Facebook0Share on Google+0Tweet about this on TwitterShare on LinkedIn0