Discord Bot Coding

Started by persephone325, February 09, 2019, 09:05:29 PM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

persephone325

I've been making a Discord bot for a server I'm a part of (and also just to expand my skills and such), but I'm just having a hell of a time trying to figure out the code for a roll dice command. (d4, d6, d8, d10, d20, plus modifiers to be specific)

I'm using Visual Studio Code as the program where I'm writing the code. I'm also using Node to boot up the bot and such. I've been looking for tutorials and such, but I must be having some sort of idiot block where nothing I'm reading is making sense to me.

I'd really appreciate any help. I think I'm just having a stupid moron moment. >.<
This doesn't have to end in a fight, Buck.
It always ends in a fight.
You pulled me from the river. Why?
I don't know.
"Don't dwell on those who hold you down. Instead, cherish those who helped you up."

Vekseid

Are you asking how to parse a string?

persephone325

Quote from: Vekseid on February 10, 2019, 04:09:32 AM
Are you asking how to parse a string?

I think so? I'm still new to coding and stuff. The tutorials I've been reading aren't as helpful as I'd like. It seems like most of them assume you know where to put the code and how to do it.

v.v I feel kinda dumb. But I know getting started is hard.
This doesn't have to end in a fight, Buck.
It always ends in a fight.
You pulled me from the river. Why?
I don't know.
"Don't dwell on those who hold you down. Instead, cherish those who helped you up."

Blank

#3
Quote from: persephone325 on February 10, 2019, 03:30:37 PMv.v I feel kinda dumb. But I know getting started is hard.
You aren't dumb, coding is hard.  Especially with Node.js.  Companies pay people over 100k a year for people who are good at JS and Node/Angular or React.

First of all, do you need/want to make a dice roller bot?  There are bots out there for you to use for free. https://discordbots.org/search?q=dice

If you do end up going the path of writing one, this tutorial seems pretty good to get at least a basic bot running.  It's unclear at a glance if you have to host your bot somewhere or if Discord does that for you. https://www.digitaltrends.com/gaming/how-to-make-a-discord-bot/

Once you get that working, it comes down to customizing your bot to do what you want.  I know myself and several others on the forum have the interest and ability to help with that. It will (as V said) parsing a string.  You need to tell the program how to find in a string if someone said "roll #d#" or however you delimit a roll command, then print out the result.

persephone325

I do know there are other dice rolling bots, but I wanted to make a bot for the server for a couple reasons - one of which is to expand my skill set a bit because one of my friends on that server wants to assess my coding skills to see what kind of freelance work he might be able to give me.

I've been trying to find at least an example of the code that rolls a die to see how it should be written, and then experiment with it myself - cause that's how I learn best, I feel. But I can't find anything like that. Or maybe I'm just not looking in the right place.
This doesn't have to end in a fight, Buck.
It always ends in a fight.
You pulled me from the river. Why?
I don't know.
"Don't dwell on those who hold you down. Instead, cherish those who helped you up."

Blank

#5
I understand.  I think I can help.

This can be broken down into 3 steps:

1. Listen for the event where a user wants to roll a dice.

This will take a string (an arbitrary length string of characters) and parse it into tokens that you can use.  You will likely need to find:
a) The command indicating the player wants the bot to roll a dice (/roll, roll, !, whatever you want)
b) Number of dice (finding the # on the left side of the 'd' character)
c) Number of sides to the dice (# on the right side of the 'd)
d) Optional modifiers (+ - / * after the #d#)

Example: "roll 1d4 - 2"

To do this, you will want to do:

a) Split the string to turn it into an array
b) Search the array for the appropriate tokens. ie check if stringArray[0] === "roll"
c) Split the string of the number of dice and sides of dice stringArray[1].split('d')
d) Plug in values into your dice roller function rollDice(numberOfDice, numberOfSides,stringArray[2], stringArray[3])

Note: This might be handling types gracefully and may not be the exact way you would want to implement.

2. Generate a random number.

This is the more straight forward part and the part I think you are looking for.  Take the parameters you have collected from part 1 and plug them into an RNG and do math.

On how to generate random numbers, see this: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/random

For my simple code on how to do that possibly, see the link below.
https://js.do/code/285034

3. Print result to screen.  You have the bot post to the screen.  Not sure how to do that, but I bet tutorials will say how to do that.  If not, I can look into it for you.

Does that make sense?  Was it helpful? Too helpful? Did I address your problem? Did I make it only worse? :S

Blank

Alternatively, you can check your project into GitHub (that way you have version control on it which is <3 if you don't have that already), and push your code and I can take a look at it.

persephone325

Okey-dokey. I'll fool around with it over the next few days and see if I need anymore help. I do want to try and do most of it myself - without having to resort to asking anymore. lol
This doesn't have to end in a fight, Buck.
It always ends in a fight.
You pulled me from the river. Why?
I don't know.
"Don't dwell on those who hold you down. Instead, cherish those who helped you up."

Blank

Understandable.  Part of the learning is the struggle.  I wish you luck, just know looking up an answer or asking for help is part of learning.

Google and StackOverflow are valuable tools (https://stackoverflow.com/). If can think of it, someone has probably asked the question before.  I honestly don't know how programming got done before the internet.

MDN has good resources on JS too.

Vekseid

It's a fair enough thing to do. Most dicebots for Discord are quite primitive.

For a more advanced roller, you can use regular expressions (now you have two problems...)

You listen for the roll command as normal, but only split of that part of the string - the substring method.

So if your command is !roll, you can match like

Note, the following code is neither complete nor checked for perfect accuracy. Copy and paste at your peril. >_>


const command = "!roll";

...

let output = false;

// input being the raw text string from Discord.

if (input.substring(0, 5) === command) {
  // You may want to test the string here for gibberish before passing it to the parser.
  output = parseString(input.substring(5).replace(/\s+/g, "").toLowerCase());
}

...

function parseString(roll) {
  // Process things by order of operation.

  if (roll === "") return ""; // Catch sillyness.

  // First would be anything in parenthesis. You can do this through a combination of recursion and iteration:
  parens = roll.match(/\([^(]\)/)[0];
 
  // You can put the above in the while loop condition but some linters will whine about it.
  while (parens) {
    roll = roll.replace(parens, parseString(parens.substring(1,-1)));
    parens = roll.match(/\([^)(]\)/)[0];
  }
 
  // So now we handle parenthesis, and the above should generally return a number. 
  // You may notice that this won't default to multiplication in the event someone does something like 46(5+4d9)
  // The simplest solution is generally to make the input string well-formed from the start - you'd look for parenthesis next to numbers or periods, and put a * in between them.

  // Outside of parenthesis, the highest order of operation ought to be the dierolls themselves:
  dieroll = roll.match(/(\d+[dk])+\d+/)[0];
  // Handling k for keep systems like L5R / 7th Sea.
  // If you want to make the dice default to one, you will need to make it an optional match in your regex.

  while (dieroll) {
    roll = roll.replace(dieroll, handleRoll(dieroll));
    // I'll leave the actual die handler as an exercise.
    dieroll= roll.match(/(\d+[dk])+\d+/)[0];
  }

  // Then do powers, multiplication/division, and addition/subtraction. These can generally be handled inline, though note you will want to include periods in your parse handling.

}


You can use this as a framework for a fairly robust dieroller, should you desire.

persephone325

Thank you, Veks. And Blank. ^^

I think I'm gonna take a break for tonight and get back at it tomorrow, or the next day. I'm starting to get a headache. lol

I just wanted to thank you both. :-)
This doesn't have to end in a fight, Buck.
It always ends in a fight.
You pulled me from the river. Why?
I don't know.
"Don't dwell on those who hold you down. Instead, cherish those who helped you up."