One of the very first projects I worked on as part of the Karta team, was a new addition to the Manchester City Football Group Client’s game “Blue Moon”. The new addition was an entire tournament system for their moonball minigame. Moonball is a rocket-league-esc game in which players can kick a large ball around a football pitch in low gravity. Their goal is to score goals in the opponent’s goal so that they can win. The tournament system involved myself refactoring an entirely unknown codebase for Moonball so that I could easily implement the minigame into a larger Tournament system, all of which had to be created by myself as well. The world can be seen below.
My first order of business was creating the Tournament Service which was going to hold all of the code related to the functionality of the tournament logic. Everything from creating a tournament tree, to handling the migration of a winning team to the next bracket, setting and evaluating the tournament’s state, and more.
Once that was done, I then switched my focus onto the Moonball codebase. Specifically, refactoring the entire system so that I could A) understand the system so that I can really get to know how it works, and B) update the system so that I could create and run matches in an API-like fashion to make hooking it up to the tournament system as simple as possible.
Once those two hefty jobs were finished, I then implemented the last of the work, which was the Moonball Tournament Service. Simply put, this service was the implementation of the tournament system into the game and was responsible for connecting the Moonball minigame to the tournament itself.
One of the issues I faced while creating the initial tournament service, was that I needed a way to dynamically create trees of varying sizes. Tournament systems are rather annoying, especially if you want them to support any number of players / teams. This is because, unless your tournament system only supports 2^x players, you are going to need to create uneven trees. This process usually involves “byes”, but data structure-wise, involves trees. As such, I had to create an entire tree library for Roblox so that I could store all the data appropriately. This can be seen visually here:
Above, you can see what the system looks like in play. We create a tournament tree based on the number of active teams. Now, the initial release of this system handled “byes” by creating uneven trees, hence the need for a Tree library. However, shortly after the initial release, it was decided to remove uneven trees and to instead display the state of the tree before the byes were applied. Annoyingly, if this was the case before release, I wouldn’t have needed to implement trees, but hey it was still an interesting topic to dive into! Essentially, this image above displays the system with even trees. The previous version would display the trees as if the byes for the 3 rightmost brackets were already applied, thus removing those 3 rightmost brackets and populating the 2nd round brackets instead.
The code for the tree library is here: https://gist.github.com/RoyallyFlushed/0a2044b1af652415889f866a66172816
I must say, I am particularly proud of this tree library. I implemented a Render method which would take a GUI object and a node and then render the entire tree to it without any other input from the user! This is actually super useful, as now not only do I have a fully functioning binary tree implementation that I can use across other projects, but I also have a completely stand-alone method to display that very tree visually at any point in time with no extra work needed!
The code for this project can be found here: