In the 5v5 game League of Legends, produced by Riot Games, the game is largely centered around teamfights, which, as the name suggests, involves two teams fighting each other in the game. Teamfights can break out at many different times in the game and can drastically impact the match result. However, teamfights can be quite chaotic and it can be difficult for players participating in the teamfight to properly understand their contribution to the fight without viewing replays multiple times. This can lead to players having many questions about a fight (ex. how much damage did I do in that fight? What did I take damage from? Did I die too early in the teamfight?).
Riot Games, the creator of the game League of Legends, has become one of the most valuable game companies in the world. This growth has allowed them to create an extensive API that includes a rich dataset for each match that is played. The goal of this project is to analyze a particular match of League of Legends and use features of the match dataset (e.g. participant data, match timeline) as well as region-wide stats (how players of similar rank generally perform) to provide feedback to the match participant on how to perform better.
If successful, this work may produce a helpful tool which could analyze/grade a player's performance in a particular teamfight. This could help players improve their performance in teamfights as well as in the game as a whole, which would hopefully improve the overall quality of matches that take place. This could be a valuable tool especially for players who don't have time to watch an entire match replay to figure out things they can improve on. One potentially negative outcome of such a tool is that it may not tell the whole story of what happens in a match, leading to misinformation about what players did wrong.
To answer our question we will create a dataset using the Riot Games API, relying mainly on two specific endpoints for our data.
This endpoint provides a dataset with the following features about a match:
Our project seeks to use the features above to gain information about the participants in a match as well as overall match stats that can be used in the determining of how well a player performed overall.
This endpoint provides a dataset with more specific, time-based data regarding a match structured as a list of 'frames.' Each frame contains a list of events that took place within that frame (each frame represents approximately one minute of a match).
We will use this endpoint to calculate specific teamfight stats for teamfights that take place.
This endpoint provides more general data about players at a given rank in the game. League of Legends uses a tier-based ranking system, where players are placed into a variety of leagues, starting from the Iron and Bronze leagues all the way to the highest rank, the Challenger league.
We will use this endpoint to obtain more general stats about players of a given rank that can be used to show whether a player performed well or poorly relative to the average performance of players at their rank.
import pandas as pd
df = pd.read_json('exampleMatch.txt')
df_events = pd.DataFrame(df['frames'][1]['events'])
df.head()
df_events.head()
The following data is an example of the match timeline dataset (the second endpoint from above). The data is obtained as a JSON, so we have included the head of the dataframe as a whole (which is not very meaningful) and also a second head showing the list of events from a given frame of a timeline. You can see how said tables were extracted by viewing the code in the cell above.
frames | frameInterval | |
---|---|---|
0 | {'participantFrames': {'1': {'participantId': ... | 60000 |
1 | {'participantFrames': {'1': {'participantId': ... | 60000 |
2 | {'participantFrames': {'1': {'participantId': ... | 60000 |
3 | {'participantFrames': {'1': {'participantId': ... | 60000 |
4 | {'participantFrames': {'1': {'participantId': ... | 60000 |
type | timestamp | participantId | skillSlot | levelUpType | itemId | wardType | creatorId | |
---|---|---|---|---|---|---|---|---|
0 | SKILL_LEVEL_UP | 1831 | 10.0 | 3.0 | NORMAL | NaN | NaN | NaN |
1 | ITEM_PURCHASED | 3845 | 10.0 | NaN | NaN | 1055.0 | NaN | NaN |
2 | ITEM_PURCHASED | 4275 | 6.0 | NaN | NaN | 2033.0 | NaN | NaN |
3 | ITEM_PURCHASED | 5597 | 10.0 | NaN | NaN | 2003.0 | NaN | NaN |
4 | ITEM_PURCHASED | 6521 | 5.0 | NaN | NaN | 1055.0 | NaN | NaN |
One potential problem is that the definition of what a 'teamfight' is can be somewhat subjective - some could classify a 2v2 skirmish as a teamfight while others might reserve the definition for 5v5s only. This could be problematic of users are seeking analysis on something that our project does not define as a teamfight. To mitigate this, we will look to be explicit in defining what a teamfight is when creating our project.
Another potential problem is that certain meaningful statistics may be difficult to calculate given the datasets available through the Riot Games API. In particular, it might be hard to determine how much damage a player dealt over a given period of time without a lot of backtracking and extra work.
In addition, while this problem may be present in almost any sort of data analysis, it may be the case that the data we collect does not tell the whole story. League of Legends matches can be incredibly nuanced and complex and its possible that the stats we collect do not accurately depict a player's performance. To address this, we will look to use a wide range of stats to gain a better understanding of how a player is actually performing.
We pose our problem as a classification problem. We will analyze general data for players at different skill levels. Then, we can compare our analysis of a player's performance in a particular match with the average performance of player at their rank. This can provide insight into whether a player is performing well or poorly relative to other players at their skill level. We can also use this comparison to determine what features a player should look to improve upon.