NathanHawks / SR1eGameBot

A discord dicebot for Shadowrun 1e-3e which also does initiative, roll macros, ammo tracking, reminders, scene prep, and more. I hope this helps you run Shadowrun 1st/2nd/3rd Editions over Discord.
1 stars 2 forks source link
cyberpunk dice-roller discord-bot shadowrun

SR1eGameBot

What It Is

A Discord dicebot for Shadowrun 1e/2e/3e, which does d6 rolls with modifiers, as well as Success Tests and Opposed Success Tests. It can also store dice macros, and even generates initiative for Shadowrun 1st-3rd Editions -- both forwards and backwards. New in 2022 it also does reminders, ammo tracking, scene text and music, and has a virtual GM screen for hiding your prep from your players. And, hey, why not: it also does initiative for Cyberpunk 2020 and Cyberpunk RED.

Instructions on using the bot are below, after the self-hosting instructions.

How to Install

Click here to deploy the bot on your server.

To self-host:

  1. Install node.js and test that it's working. You'll need this in order to set up the bot.

  2. Get your Discord auth token via the New Application button at http://discordapp.com/developers/applications/me and put the auth token in a discordauth.json file, in the same directory as main.js. The format:

    {
    "token": "your auth token goes here"
    }

IMPORTANT: If you're using git, make sure you add discordauth.json to your .gitignore file before your next commit.

3a. Install MongoDB and test that it's working (for example by connecting to it with MongoDB Compass); and then create a database called sr1egamebot. (If you're using Compass, you'll need to also create a collection in that database; in that case, create the collection folders.)

3b. From the bot's source, copy config.example.js to config.js.

IMPORTANT: If you're using git, make sure you add config.js to your .gitignore file before your next commit.

Open config.js in your code editor and fill in your MongoDB connection string. It has the format:

mongodb://USERNAME:PASSWORD@HOST:PORT/DB

For example:

mongodb://my-db-user:my-db-password@127.0.0.1:27017/sr1egamebot

If you use a strong password with symbols, you might need to encode the password, like this:

mongodb://my-db-user:${encodeURIComponent('my-db-pass')}@127.0.0.1:27017/sr1egamebot

3c. If you used a previous version of the bot, you'll need to migrate your data away from Google Drive, using the provided script migrate.js: see the section Data Migration, below.

3d. For the sake of security, configure MongoDB for password authentication. I also strongly recommend: a) hosting MongoDB on the same server that the bot runs from; b) setting the firewall to reject connections to MongoDB from outside; c) leaving MongoDB on its default configuration to only accept connections from the same computer.

Here's how to enable password authentication for MongoDB.

  1. Run GameBot locally by going to its directory and running node . (with the period).
    • If you plan on self-hosting at home or pushing files to the web via FTP, you can skip to step #9.
    • If you plan on hosting via Heroku and deploying via GitHub, continue with the following steps:
  2. On your deployment server, create an environment variable:
    • TOKEN should have the contents of the discordauth.json file.
  3. Publish your copy of the bot to your repo under the master branch.
  4. Link Heroku to your GitHub repo, and tell Heroku to auto-deploy when you push to master.
  5. In Heroku, under "Configure Dynos", use the "worker dyno", not the "web dyno".
  6. Invite the bot to your server! Replace the XX's in the following link with your bot's ID number: discordapp.com/oauth2/authorize?client_id=XXXXXXXXXXX&scope=bot&permissions=3136

Data Migration

To migrate the data, first make sure MongoDB is installed and running. Make sure config.js is set up with the proper this.dbUrl value including MongoDB user credentials if you've turned on MongoDB's password authentication. Then go to Google Drive and right-click your UserData folder, and choose Download. Then rename the downloaded file to simply UserData.zip and place it in the same folder with the bot's code files. Then run node ./migrate.js from the bot's folder.

After migrating, you will have more entries in the folders collection than were reported in the migrate.js output. This is normal; it happens because node-stream-zip only reports folder endpoints: UserData/serverID/channelID/userID gets reported as one folder, when actually it's four folders nested in each other.

Hosting the Bot Elsewhere

Unfortunately, this is beyond the scope of these instructions.

Gaining access to admin commands:

There are a few admin commands that are hard-coded only to respond to me, the bot's author. If you self-host, you can gain access to them:

  1. Find out your Discord ID (it's not your username followed by a few numbers; it's all numbers; it will be the final number that appears in your bot's log output when you use any of the initiative commands).
  2. Do a find-and-replace in main.js, replacing all occurrences of my Discord ID, 360086569778020352, with your Discord ID.
  3. Push the changes and restart the bot.

Shadowrun Dicebot Features

:game_die: Plain Old d6\'s :game_die:

:six: Rule of 6 & Target Numbers :dart:

:boxing_glove: Opposed Rolls :boxing_glove:

:1234: Multiple Rolls per Message :1234:

You can order GameBot to do multiple rolls with one message. Just separate the dice commands with semicolons.

example: !1 ; 2t ; 3!; 4t +5 and a note for good measure

Be careful not to use semicolons for any other reason.

:label: Notes :label:

Notes are OK, and your options can be in the middle of the note.

examples:

:fast_forward: Macros (Saved Rolls) :fast_forward:

:recycle: Reroll :recycle:

:boom: Initiative System :boom:

Player setup:

:one: !setgm @someone
:two: !setinit X Y

GM setup:

:one: !setgm
:two: !setplayers @player1 @player2 (etc)
:three: !setnpcinits (see below)

!setinit syntax is !setinit X Y where X is the number of dice and Y is the modifier. For example, !setinit 1 4 sets your initiative formula to 1d6+4. (Or, for Cyberpunk, 1d10+4. It'll say 1d6+4, but it'll roll 1d10+4 if you roll Cyberpunk initiative.)

IMPORTANT: Commands won't work unless you @people correctly. Use the menu that pops-up while you type, or tab-completion. If it's highlighted blue, you did it right.

:game_die: Rolling Initiative :game_die:

:arrow_right: !init - Shadowrun 1e initiative
:arrow_right: !initflip - Shadowrun 1e initiative, reversed
:arrow_right: !init2 - Shadowrun 2e initiative
:arrow_right: !init2flip - Shadowrun 2e initiative, reversed
:arrow_right: !init3 - Shadowrun 3e initiative
:arrow_right: !init3flip - Shadowrun 3e initiative, reversed
:arrow_right: !initcp - Cyberpunk 2020 initiative
:arrow_right: !initcpr - Cyberpunk RED initiative

The bot remembers stuff; you won't need to redo setup, just update whatever changes. However:

:game_die: Other initiative commands :game_die:

  Shortcut  Full command    [Required] options
  --------------------------------------------
            !setgm          @someone
  !si       !setinit        [X Y]
  !setp     !setplayers     [@player1 @player2 etc]
  !addp     !addplayers     [@player1 @player2 etc]
  !lp       !listplayers
  !rmp      !removeplayers  [@player1 @player2 etc]
  !clrp     !clearplayers
  !setn     !setnpcinits    [X1 Y1 label1 X2 Y2 label2 etc]
  !addn     !addnpcinits    [X1 Y1 label1 X2 Y2 label2 etc]
  !ln       !listnpcinits
  !rmn      !removenpcinits [label1 label2 etc]
  !clrn     !clearnpcinits

:dragon_face: Adding NPC's :dragon_face:

!setnpcinits and !addnpcinits syntax:
!(command) X Y label
Labels cannot have spaces or commas. Add as many NPCs as you want, separated by spaces.

e.g. !addnpcinits 1 5 thugs (means the thugs have 1d6+5 initiative).

If you have multiple NPC's with the same label, !removeNPCInits also accepts the format !removenpcinits X Y label which requires a full match. But, having multiple NPC's with the same label is confusing anyway, so maybe just don't do that.

:blue_book: Prepared Scenes with (or without) Music :blue_book:

It is strongly recommended that you also read !help gmscreen so you can do your prep in secret!

Every adventure has passages of text that must be given to the players at each new scene. You no longer need to type these out in real time! Now you can prepare the texts in advance via the bot, and deploy them easily later.

!setscene name musicLink sceneText
Creates or updates a named scene. The music link is optional. Scene text can have line breaks and formatting, and is only limited by Discord message length limits.
Example 1: !setscene example1 https://www.youtube.com/watch?v=zsq-tAz54Pg The orks burst through the door carrying uzis and a grudge.
Example 2: !setscene example2 Suddenly the band stops playing as everyone stares at you in horror.

!getscene name
Deploys the named scene. The name of the scene is not displayed in the output. Music (if any) is shown as a link, with Discord's embedded player below that.

!listscenes
Shows a list of scene names that you've saved to the current channel (or play channel, if you're using the virtual GM Screen feature).

!delscene name
Deletes one or more scenes identified by name(s). To delete multiple scenes, simply put spaces between the names. Deleted scenes cannot be recovered!

:ninja: Virtual GM Screen :ninja:

Using this feature, ammo tracking, reminders, initiative and scene commands can be done in a hidden channel.

Players still need to !setgm and !setinit in the play channel.

It's simple!

Step :one:: Go to your hidden channel
This will be the channel where you do all your prep from now on.

Step :two:: !setchannel linkToPlayChannel
Your "play channel" is the channel players have access to; your main channel for the game.
You make a channel link by typing the # sign and typing the channel name or choosing it from the pop-up menu.
If the channel name is highlighted blue, you did it right.

Step :three:: Do your prep!

Notes about running various commands behind the GM screen:
:arrow_forward: !getscene will output to the play channel so you don't need to reveal your scene titles.
:arrow_forward: You can now run !init in secret, or you can prep your NPC's in the secret channel and then do the !init command in the play channel.

:alarm_clock: Reminders :alarm_clock:

The bot can DM reminders of your upcoming game sessions to your players.

!addreminder sessionDate&Time timer1 timer2 etc

!listreminders

!cancelreminder id#1 id#2 etc
Cancels one or more reminders. See !listreminders to get the ID's.

:gun: Ammo Tracking :gun:

GameBot can track ammo during combat, enforcing max ROF and weapon capacity.

!ammo addgun name maxROF ammoContainerType ammoCapacity ammoTypes
Adds a weapon for ammo tracking purposes. The name must not have any spaces or commas.
If the gun is compatible with multiple types of round, separate them with spaces.
You should keep the name short, since you'll be typing it for the !ammo fire and !ammo reload commands.
If the rules don't specify maxROF any other way, don't forget autofire is Skill Rating +1.
Example: !ammo addgun uzi3 7 clip 16 slug

!ammo delgun name
Example: !ammo delgun uzi3
Removes the uzi3 from your inventory.

!ammo addammo qtyContainers containerType qtyRounds roundType maxRounds
The maxRounds should match the ammoCapacity of the gun you want to use this ammo for.
The roundType should match one of the ammoTypes for the matching weapon.
Example: !ammo addammo 10 clip 16 slug 16
Adds 10 clips that are fully loaded with 16 slugs each. This matches the uzi3.

!ammo delammo qtyContainers containerType qtyRounds roundType maxRounds
Example: !ammo delammo 4 clip 16 slug 16
Removes 4 of those clips for your uzi3 from your inventory.

!ammo list
Shows a list of guns, and what they're loaded with, plus a list of your ammo.
Empty clips are not shown, so track those yourself.

!ammo fire weaponName nbrShots
Depletes a number of rounds (nbrShots) from the gun identified by weaponName, assuming nbrShots doesn't exceed the gun's maxROF.
If you try to shoot more rounds than are currently loaded, the weapon will be depleted of all ammo and you will be told how many rounds were shot before the weapon clicked empty.

!ammo reload weaponName
or
!ammo reload weaponName shotType
The first form assumes you only have one compatible ammo type for that weapon.
Example: !ammo reload uzi3
The second form allows you to specify which type of round you want to load, for cases where your weapon has multiple compatible ammoTypes and you have compatible ammo entries for 2 or more of those ammoTypes.
Example: !ammo reload enfield shot

Misc

Commands are not case-sensitive. Go WiLd WitH tHaT.

You can find my Patreon at https://patreon.com/nathanhawks if this bot helps you game.

Legal

This software is released as-is under the terms of the UnLicense; it is available to the public domain.