Team Fight Tactics API Projects
API: Version 1
September 2023 - December 2023
After learning how to use APIs in my Intro Data Science class, I was excited to learn the Riot Games has an API for Team Fight Tactics, my favorite game. Later that year, I took a class on database management systems where I learned how to correctly store large data and the language SQL.
And thus, I put it all together in this three-part project!
Step 1: Utilize Riots API to collect TFT player and match data.
Step 2: Organize and store said data in a SQL database (using Supabase).
Step 3: Analyze!
Step 1 and 2 were done in Python since I was more comfortable creating functions in Python than R at the time. Step 3 would be done in R because it was easier to perform statistical analysis there than in Python.
While working on Steps 1 and 2 over summer, I ran out of time to do Step 3 before school started back up again. Lucky, my Multilevel and Mixed Modeling class allowed me to use any data set I wanted for the final project, so I used the data I collected over summer! Well, a subset of it at least.
To fix the data in a multilevel format, I sought to determine whether there are significant differences in how Challenger ranked players play the game compared to Master and Grandmaster players. Randomly selecting 205 players from each of the three ranks, I filtered down to each players five most recent matches, using the end of game data from all eight players in these matches. This gave me a nested format, where player results are nested within a match!
Using logistic multilevel modeling, I predicted whether or not a player is Challenger based on player end-of-game variables such as placement, gold leftover, and board cost. Exploratory analysis shows that Challenger players tended to place higher than non-Challenger players (as expected), leading me to believe that placement would be an important variable.

The final model included the following variables: placement, average unit level, match average board cost, and the interaction between match average board cost x average unit level.
With a train-test split of 80-20, my final model achieved an accuracy of 81% with a ROC-AUC of 0.92, indicating that the model is very effective at distinguishing between Challenger and non-Challenger players.
Side Project: Composition Generator
March 2025
Recently learning how to create Shiny Apps in R (think interactive web applications), I wanted to push what I knew how to do to the limit. While working on my API project, I stubbornly refused to use any packages to help use Riots API. However, I learned about Community Dragon where I could find all unit and item information for each TFT set. With this in the back of my mind, I wanted to try creating a program that would recommend a team composition to players based on their input.
I ended up with two different generators: a vertical composition and bronze for life generator.
The vertical composition generator is meant to be used in games where you have a trainer golem or wandering trainer, in other words you have multiple emblems and you want to go deep into one trait or origin. On the other hand the bronze for life generator is meant for the opposite situation where you want to maximize the amount of non-unique traits or origins active like when you have the augment bronze for life or trait tracker.
For both cases, the user can select any units they want to forcefully include in their composition, team size, maximum unit cost, up to three emblems or crests, and whether they want to force a specific vertical trait.

My biggest takeaway from this project ended up being UI and UX design. It took me more testing than I expected to get a look and feel I was happy with. I fell in love with the simplistic unit card design I ended up with, and how they popped and displayed the units trait(s) and origin when hovered over.
You can access my Shiny App here and Github Repo here. I plan to add new sets and improve my team composition generators in the future!
API: Version 2
June 2025 - Present
Newly graduated and with more time on my hands, not to mention much improved skills, I decided to return to my API project. Since I made it, Riot updated their API to fully rely on PUUIDs, and I figured that might have broken a function or two I had written (although I made them pretty robust). However, before I got too far into this updating, I decided to make an R package! I had a lot of practice since the bulk of my thesis was contributing to an R package, and I could not find any R package that improved the use of Riots TFT API.
Although the package is still a work in progress right now, you can check-in at this Github Repo!
I plan to do the same three steps as before, although a different analysis this time.