Project: Leaf
About a decade ago I launched my first site responsible for obtaining stats from the then-current Halo game. When Halo Infinite launched Leaf was reborn as another site with a new stack of technology.
Laravel with Livewire and Bulma joined together to build a quick responsive template to take a more clean minimal approach to Halo stat design. I was just getting upset with the other sites in this ecosystem that either had ads everywhere or some heavy interface.
So I found a public API service known as HaloDotAPI to save me the stress of building both a stat platform and stat obtaining platform.
If you searched your own gamertag you would land on the page above. This was a basic quick overview page that showed people information they probably wanted to see. We cached it on the backend so next loads were extremely quick with the data refresh happening behind the scenes.
Of course everything seems fast when you build it, but then when you add ~40 million games into it - things do sadly slow down a bit.
Once you land on this page you see the top medals obtained as well.
The other tabs make jumps into pure competitive, a medal breakdown and a historical reference of games played.
Once you found a game you could jump into the game detail view of that game. This page took such a different approach to medals than I've seen anywhere else before. I struggled in previous Halo games showing medals for each player in an interface that didn't explode in visual space needed.
This time I just grouped all medals together ordered by rarity and put the count and gamertag by the user who obtained it. This got some good feedback because folks could quickly see who obtained some rare medals without clicking on each person individually.
Building in export support for everything was an odd request I got on Twitter that seemed to explode in popularity. Most folks used this to export data and visualize it in some tools. It was even abused to the point that some folks automated dashboards via the CSV export I have - crawling it way too often.
When you move into the esports scene of Halo - I wanted to see the bracket without scrolling my browser thousands of pixels to the right. Once again I was upset with the required site to use as it put my computer to a crawl. Thankfully they had an API so I got to work.
This took an interesting approach to reviewing what is normally a classic double elimination bracket. You could tab through losers/winners from above and the sidebar would let you move between rounds.
At some point I wanted to be able to click a team and have their entire history throughout the tournament visible, but I never got around to it. Related to competitive play I got request to combine the stats of multiple games in order to see the best performer of a series.
So I built out the scrim feature, which was pretty neat. You simply enabled scrim mode from either the local or custom game history and just checked boxes of the games you wish to be included. It even persisted the check boxes across pagination which was a cool built in feature of Livewire.
I wanted to gain some feedback on how to use these pages since I never use it, but never got any extra requests - so it sat.
When I noticed the site was quite popular - it made sense to investigate into some cool analytics. Once I passed 10 million games it seemed possible to build a fairly accurate leaderboard of stats. It may have been missing some things that the mega popular stat sites had, but I figured the leaderboards would correct themselves as people stumbled upon them.
One top ten leaderboard that was extremely popular was the most kills in a game with zero deaths. Folks would share this on Twitter when the record was beat.
Now medals were something that I really wanted to show, but I didn't have the best database design to query it. All the medal data was basically serialized into a key/value array and dumped into a single column.
So while the leaderboard was live - it got slow over time. What once took milliseconds to render now takes seconds. The bug report for that has been open for a bit and I think my only resolution is to process the top 1,000 of every medal and remove the live aspect of it.
The things I haven't talked, but I want to record into history.
- 100% test coverage
- fully automated ci/cd system
- automatic XUID comparison to detect renames
- automatic image optimization and caching
- open source
- zero ads
- zero trackers
- free
This iteration of Leaf is by far the best. The biggest issues it hits now is reacting to popularity which harms its rate limit and database size. The site may not exist anymore by the time readers read this, but it was hosted at: https://leafapp.co and the repository lived at: https://github.com/iBotPeaches/LeafApp_Infinite.