I first began creating Mizar two years ago after the UK went into its first COVID-19 lockdown. As schools closed and moved to online learning, I suddenly had a lot more free time and was spending more time socialising with my friends on the social media platform Discord. Using the platform more, I noticed several features that Discord was lacking - such as the ability to play music in voice channels and a message levelling system. With nothing better to do, I decided to try implementing these myself in my very own Discord bot.
For those of you unaware, Discord is a chatting platform similar to Teams or Slack but aimed at friends and communities rather than businesses. Users can join multiple guilds - or servers - which each have multiple text and voice channels. A Discord Bot is a special type of user that can be controlled through code. As it can read and send messages like a normal user, commands can be implemented - where any message starting with a prefix can run a pre-defined function. Nowadays, Discord has added additional fancy features that bots can use - such as slash commands and buttons - however when I first began creating Mizar, none of these existed.
As of today, Mizar has executed over 100,000 commands across over 900 guilds. It's completely free and can be installed on your own server by going to mizarbot.xyz.
The Development Process
Mizar started small in a GitHub monorepository. I first began by implementing the
!ping command - as almost everybody does - and then followed a few guides to add the ability to play music, the feature I wanted most. I then slowly added more and more commands, making a simple website to enable, disable and configure these as desired.
To keep my updates organised when pushing code to my production VPS, I implemented a version-naming system inspired by the creative version names of Android. Each major update would be called a food beginning with the next letter of the alphabet, with minor updates (such as bug fixes) simply incrementing the number at the end of the version. This started with Version Apple and was followed by Blueberry, Cookie, Dragonfruit, Elderberry, Fruitcake and Grapefruit.
As more features were added, I refactored the code behind the bot multiple times to simplify the process of adding new commands. In its current state, each command is stored individually in its own file within a module folder. The other parts of the bot handle everything else in the background - such as parsing and validating the arguments given by the user, handling the help menus and managing the command configuration (such as user permissions) on the webpanel.
Once the project had become quite large, I decided to split the large monorepo into several smaller ones stored on a GitHub Organisation. This also meant that I was able to make Mizar's documentation open-source and could offload the website and documentation onto Cloudflare Pages, improving performance.
I also ended up moving music playback to a separate application called lavalink using the lavaclient library. This also helped improve performance as playback could be handled completely separately using a more efficient language. In the future, this also means that I'll also be able to run multiple instances of lavalink on multiple, different servers if required.
Mizar's website is written in React.js, communicating to the Express backend through websockets and API requests. Although the main purpose of the website is to allow admins to configure the bot, it also provides a nice landing page to encourage people to install the bot themselves.
The website has had three main iterations, each using a different style library. I first began using Bootstrap with the Darkly theme due to its ease of use. However, I didn't like the look of it so switched to Fomantic UI with a custom theme in update Blueberry.
This too, however, had its problems: Fomantic UI was a community fork of Semantic UI, which had been abandoned in 2018. Fomantic UI did not provide its own React library, so I had to use Semantic UI React with the newer Fomantic UI CSS. In addition, Fomantic UI did not provide as many user interface components as I wanted - especially as the main purpose of the website was the admin webpanel.
This led to the third and final iteration of the website which used Ant Design (with another custom theme to keep the colour scheme consistent). Ant Design is a fantastic library built specifically for React, so it had many different components that I could use. I also felt that it gave more of a modern look.
Using Services and APIs
One of the reasons that I started Mizar was so that I had an excuse to use a bunch of APIs that I hadn't messed with before. As my aim with Mizar was to create useful commands that anyone could need, I was able to implement a whole bunch of different APIs (shown in the bottom left of the technology stack image below).
In particular, I enjoyed working with Google Cloud Platform. Although complicated at first, it offered a huge range of services with generous free quotas. For Mizar, I used the YouTube Data API for music and receiving YouTube channel updates, the Cloud Text-to-Speech API for automatic TTS and the Cloud Translation API for flag message translation.
Once Mizar had been released publicly, I focused on spreading the word about my bot so that people could add it to their own servers. The main way that I did this was by adding Mizar to bot lists, dedicated websites where people could find Discord bots to match their needs.
The majority of these bot lists also had their own APIs that I could implement so that I could send statistics about Mizar (such as the number of servers that it was in) to the bot page.
As well as this, I registered a Twitter account to advertise the bot's features and post new updates.
Monitoring Bot Performance
I used multiple services to monitor Mizar's performance - both in the longer term to see how the bot is growing, and in the shorter term to catch bugs and have high uptime.
Statcord is a service that provides historical data on bot growth and usage, and by adding this from an early stage I was able to see how the bot had grown into more servers and how many commands had been run (over 100,000 as of today)!
I used New Relic to monitor Mizar on a shorter term, such as system usage and the commands run during the day. New Relic also stores Mizar's logs, so when combined with Sentry error tracking was very useful to find and fix bugs.
For uptime monitoring, I added Mizar to HetrixTools, a free tool that monitors Mizar's API from multiple locations. Although Mizar very rarely goes down, this sends me a message if it does.
Implementing New Features
As more people started to use Mizar, they had their own suggestions on what they wanted to be added. Unsure of the best way to track these, I started by just creating a channel on the Support Discord Server. However, this led to certain ideas being lost in message history, so I tried hosting an open-source Flarum forum.
This, however, seemed too overkill - users had to register their own accounts to submit or comment on suggestions, and the process of submitting a suggestion became too complicated. After exploring many other options, I eventually decided to go with a roadmap run by Convas. This decreased the friction of requesting a feature and looked much nicer.
I also implemented a versioning system within Mizar, as each new version often required a database migration. By storing changelogs within the Mizar code itself, I was also able to automatically display the changelog on Mizar's website and automatically send changelog messages to updated servers.
Overall, I think that Mizar has been a very fun project to work on. Over the past two years, I've committed over 1,500 commits on GitHub and written over 35,000 lines of code.
Mizar currently has 107 commands - these have been run over 100,000 times across over 900 servers.
Although I still plan to work on Mizar in the future to try and add everything in the roadmap and keep implementing Discord's new features, I consider Mizar to be in a semi-finished state as it is, and a successful Discord bot.