Multiplayer Discord Game Bot

Creating a multiplayer discord game bot, using node, discordjs, and my own re-written survey-toolbox (for JavaScript). Deploying it on Heroku with a Mongo Database just for good measure, sounds simple enough right?!

Multiplayer Discord Game Bot
Photo by ELLA DON / Unsplash

If you've been following my blog you'll remember I wrote a little Python package to help with basic flat plane 2d coordinate mathematics. Also remember I wrote a simple two player text based Artillery game using that library - and - previously I'd written a game bot with my Pal Tim.P. Well, I thought it would be a smashing idea to combine them all and create a two player game on discord!

tldr; https://discord.gg/tAmJNqNB come fight me!

Here's what I set out to achieve.

  • Discord bot written in Python, utilising the following libraries
    • discord.py
    • survey-toolbox
  • Deployed on Heroku

The problems with my vision.

Discord API

There are significant changes to the Discord API being effected on April 22, writing bots the old way would just result in an bot with a short life span. All the changes are all available on the Discord blog, and heavily opinionated elsewhere, so I won't go into much detail here. I did enjoy learning the new Interactions and Slash Commands - I think they make for a great user experience particularly with auto-complete now available to the user as well as attribute prompts.

Just type a slash to initiate command auto-complete.

discord.py Library

The original discord.py library is no longer being maintained, and nor will it be upgraded to accommodate the 'new' Discord. I respect Danny's the reasons and appreciate his work over the last 6+ years - some effort he's put in! Whilst discord.py has been forked and will continue in some capacity, I opted to shop around for a replacement and found discordjs - not related. Discordjs is a full featured discord API built on - you guessed it - JavaScript.

The re-written vision

  • Multiplayer Discord bot written in JavaScript, utilising the following libraries
    • node / npm
    • discordjs
    • survey-toolbox-js
    • mongodb and mongoose
  • Deployed on Heroku

You'll note this project is already blowing out; in addition to adding database capabilities, the whole purpose of this exercise was to use my own library to create something cool; but my library is written in Python - so, enter the JavaScript version of the survey-toolbox!

survey-toolbox-js

Thankfully my survey-toolbox library was quite small, so the decision to convert it to JavaScript was an easy one. I tried to keep it structurally as close to the Python version as possible so when I make changes to one I can implement them on the other quite easily too. Anyone that has programmed in both languages will know it's not a word for word transcription between the two, in fact some simple things (extracting an integer for example) required additional little scripts written. Other aspects were easier. I'll detail this conversion in a separate blog post later.

Uploading the package to Node Package Manager for sharing and reuse was just a delight compared to deploying to PyPi

MongoDb

What's the point of having a multiplayer game if you can't keep track of your stats right?! I'm familiar with Mongoose and mongodb form the Full Stack Developer Bootcamp I completed last year - this was relatively easy for me to implement - admittedly I spent some time refreshing as I haven't used it in a while, and I kept the database functionality simple (for now) mostly due to time constraints.

Node and Heroku

Node and Heroku work well and are simple enough - independently and as a deployment option. The only issue I had here was working out (aka googling) that I required to specify the engines in the package.json file or Heroku would use an incompatible version of node and throw an error on deployment.

"engines": {
    "node": "17.x"
  }

Discord

The new discord interactions / slash commands were pretty confusing at first - the documentation is good but the examples are limited so there was a lot of trial and error here. I've really only scratched the surface with what I can do here and I'm looking forward to adding in some permissions, roles, buttons and selectable options to make the Artillery bot game a much deeper and better experience for the user.

const { SlashCommandBuilder } = require('@discordjs/builders');
require("survey-toolbox");

global.EASTING = "e";
global.NORTHING = "n";
global.ELEVATION = "el";
global.BEARING = "bg";
global.DIST_2D = "dist_2d";
global.DIST_3D = "dist_3d";

const { NewSurveyPoint } = require('survey-toolbox/lib/SurveyPoint');
const { toDegreesMinutesSeconds } = require('survey-toolbox/lib/ConvertToDegMinSec');
const { formatAsDms } = require('survey-toolbox/lib/FormatDegMinSec');

module.exports = {
	data: new SlashCommandBuilder()
		.setName('todms')
		.setDescription('convert to dms')
		.addStringOption(option => option.setName('decimaldegrees')
			.setDescription("input decimal degrees")
			.setRequired(true)),
	async execute(interaction) {
		try{
			let toDms = interaction.options.getString('decimaldegrees');
			toDms = toDegreesMinutesSeconds(parseFloat(toDms));
			await interaction.reply(formatAsDms(toDms));
		} catch (err) {
			console.log(err);
		}

	},
};
This basic example will take decimal degrees and return formatted degrees minutes seconds to the user.

The game itself

Enough about the technical stuff (for now). The game was intended to be a two player game, player a issues challenge to player b and the two take turns battling - well I'm sorry but that's just not fun.

A game where pen and paper will add to the experience :P

I got away from the keyboard for a while and really thought through the gameplay; the end result is a battleground, users join, they are placed at random coordinates and the coordinates determine which team they're on. Each player currently is representing a single gun (cannon) crew. For the time being, the only command available is to fire the gun and hope for a hit (anything within 500m). If you miss the gun computer returns a hint to help you out.

Gun computer returns bearing and distance from splash to target.

Don't be a basic bitc... bot

Look, the bot is very basic right now. It is really a prototype of what can be done with my survey-toolbox-js library when combined with other libraries. But i do love this bot and the game idea in general so I'll keep developing it on my (limited) spare time.

Future plans

  • Scoring - there is none - right now you can get a hit but it's not recorded and you don't 'kill' anyone.
  • Different gun types
  • Upgrades (radar, sound ranging, survey, meteorology, advanced radio comms, gps)
  • Sharing intelligence to gun crews within specified distance to enable triangulation / trilateration of enemy locations.
  • Movement - yeah, you see, the survey-toolbox packs a punch and will enable the playing pieces to change their position in real (or simulated) time.
  • Ranking - the higher the rank the more guns you can deploy, create a Battery, or even a Regiment.
  • More advanced gun-computer - you want those rounds on target right?!
  • Shift from Degrees to Mils - the Artillery unit of measure.

You can play the game by dropping by joining my discord channel, join the game and then start firing wildly.

/joingame

/fire [enter decimal degrees] [enter bearing]

References

I wasn't born with the know how for this, I had to Google the shite out of it! For more detailed information on the above, please check out these websites.

discord.py (Python)

discordjs (JavaScript)

survey-toolbox (Python)

survey-toolbox-js (JavaScript)

Discord Slash Commands

MongoDb