Dota has come to R!
(or maybe vice versa!)
If you know Valve’s popular game Dota2 then you will be pleased to know that it has come to R. If you don’t, it might interest you to have a look at steam to find out what it is. As a short introduction, it is one of the most popular video games ever made with a huge fan base of around 13 million registered users (at the time of writing)! To make things even most interesting, you can see that Valve has actually paid the biggest prize ever in e-sports. The International Dota2 Tournament, has paid $20.7 million to its winners in August 2016.
So, how does this relate to R? Well, apparently Valve has released an API for Dota2’s data (and we are talking about a lot of data!), which is now available through R with the release of RDota2.
The package is currently on CRAN and can be installed via:
install.packages('RDota2')
Valve give away a huge amount of data, which is accessible through RDota2. Every single game is recorded and data is available for free through the package. RDota2 gives you access to the following API methods:
Dota 2 methods relating to match information:
Dota 2 methods relating to Dota 2 economy:
You can access the Steam API Documentation from this link.
RDota2 utilizes the above methods with the use of the corresponding get_*
functions:
In order to start using the package you would need a steam api key, which you can get from the steam community. You will also need a steam account.
Once you have a key you can provide it to key_actions
, which will make it available to all RDota2 functions so that you won’t have to re-enter it every time you use an API method.
Let’s see how we would use RDota2!
After we have installed the package, we load it with library
and use key actions
to register a key:
#load RDota2
library(RDota2)
#register key
key_actions(action = 'register_key', value = Sys.getenv('RDota_KEY'))
## Key set successfully
The value
argument requires the key we received from Steam Community. Although we could just stick the actually key value there (it is just a combination of numbers and letters), best practice dictates we save it in an environmental variable, which we can then call with Sys.getenv
as I did above. There is a step by step explanation on how to create a system variable on the RDota2 tutorial.
Now that we have registered a key we can call each one of the API methods, seen above. I will show you some examples below:
The most useful (probably) function would be get_match_details
which allows us to retrieve details of a particular match.
#match list contains information about both players and the match
match_details <- get_match_details(match_id = 2686721815)$content
#match_details[[1]] is a list with all the players - usually 10
#match_details[[1]][[1]] is just one of the 10 players
str(match_details[[1]][[1]])
## List of 27
## $ account_id : num 4.29e+09
## $ player_slot : int 0
## $ hero_id : int 106
## $ item_0 : int 54
## $ item_1 : int 0
## $ item_2 : int 145
## $ item_3 : int 48
## $ item_4 : int 185
## $ item_5 : int 11
## $ kills : int 2
## $ deaths : int 1
## $ assists : int 16
## $ leaver_status : int 0
## $ last_hits : int 92
## $ denies : int 3
## $ gold_per_min : int 411
## $ xp_per_min : int 461
## $ level : int 17
## $ hero_damage : int 8107
## $ tower_damage : int 1425
## $ hero_healing : int 0
## $ gold : int 948
## $ gold_spent : int 13620
## $ scaled_hero_damage : int 7420
## $ scaled_tower_damage: int 1058
## $ scaled_hero_healing: int 0
## $ ability_upgrades :List of 17
## ..$ :List of 3
## .. ..$ ability: int 5603
## .. ..$ time : int 141
## .. ..$ level : int 1
## ..$ :List of 3
## .. ..$ ability: int 5605
## .. ..$ time : int 295
## .. ..$ level : int 2
## ..$ :List of 3
## .. ..$ ability: int 5604
## .. ..$ time : int 324
## .. ..$ level : int 3
## ..$ :List of 3
## .. ..$ ability: int 5603
## .. ..$ time : int 385
## .. ..$ level : int 4
## ..$ :List of 3
## .. ..$ ability: int 5603
## .. ..$ time : int 489
## .. ..$ level : int 5
## ..$ :List of 3
## .. ..$ ability: int 5606
## .. ..$ time : int 560
## .. ..$ level : int 6
## ..$ :List of 3
## .. ..$ ability: int 5603
## .. ..$ time : int 646
## .. ..$ level : int 7
## ..$ :List of 3
## .. ..$ ability: int 5605
## .. ..$ time : int 850
## .. ..$ level : int 8
## ..$ :List of 3
## .. ..$ ability: int 5605
## .. ..$ time : int 1012
## .. ..$ level : int 9
## ..$ :List of 3
## .. ..$ ability: int 5605
## .. ..$ time : int 1264
## .. ..$ level : int 10
## ..$ :List of 3
## .. ..$ ability: int 5606
## .. ..$ time : int 1298
## .. ..$ level : int 11
## ..$ :List of 3
## .. ..$ ability: int 5604
## .. ..$ time : int 1635
## .. ..$ level : int 12
## ..$ :List of 3
## .. ..$ ability: int 5604
## .. ..$ time : int 1772
## .. ..$ level : int 13
## ..$ :List of 3
## .. ..$ ability: int 5604
## .. ..$ time : int 1909
## .. ..$ level : int 14
## ..$ :List of 3
## .. ..$ ability: int 5002
## .. ..$ time : int 2063
## .. ..$ level : int 15
## ..$ :List of 3
## .. ..$ ability: int 5606
## .. ..$ time : int 2149
## .. ..$ level : int 16
## ..$ :List of 3
## .. ..$ ability: int 5002
## .. ..$ time : int 2200
## .. ..$ level : int 17
#information about the match
str(match_details[-1])
## List of 22
## $ radiant_win : logi TRUE
## $ duration : int 2016
## $ pre_game_duration : int 75
## $ start_time : int 1475527616
## $ match_id : num 2.69e+09
## $ match_seq_num : num 2.35e+09
## $ tower_status_radiant : int 1844
## $ tower_status_dire : int 4
## $ barracks_status_radiant: int 63
## $ barracks_status_dire : int 3
## $ cluster : int 137
## $ first_blood_time : int 517
## $ lobby_type : int 0
## $ human_players : int 10
## $ leagueid : int 0
## $ positive_votes : int 0
## $ negative_votes : int 0
## $ game_mode : int 1
## $ flags : int 0
## $ engine : int 1
## $ radiant_score : int 35
## $ dire_score : int 10
This gives you an idea of the vast amount of information you can get for just one match! As you can see you have full details for each one of the players participating (usually ten), including items, kills, deaths, assists, gold, experience last hits and so much more. You also get information about the specific match!
Another important function shows us the Dota TV-suppported leagues:
#available leagues
str(get_league_listing()$content)
## 'data.frame': 1569 obs. of 5 variables:
## $ name : chr "Dota 2 Just For Fun" "joinDOTA League Season 3" "Killing Spree: North America" "Wild Cards West" ...
## $ leagueid : int 1212 1640 25 2 3 4 5 6 7 8 ...
## $ description : chr "64 of the best Brazilian amateur teams compete to become the winner of the first Dota 2 Just For Fun tournament. " "The global Dota 2 league for everyone. Featured are all of the matches from division 1 and 2. There are three leagues: Europe, "| __truncated__ "Killing Spree is a perpetual King of the Hill event featuring four premier teams from North America. Each team will battle thei"| __truncated__ "Watch eight of the best Dota 2 teams compete for a spot in The International" ...
## $ tournament_url: chr "https://binarybeast.com/xDOTA21404228/" "http://www.joindota.com/en/leagues/" "http://neodota.com/?page_id=1389" "http://www.dota2.com/tournaments/international/" ...
## $ itemdef : int 10541 10742 15014 15015 15016 15018 15042 15047 15049 15051 ...
And then we have functions that show all Dota2 Heroes and all Dota2 Items:
#items
head(get_game_items()$content, 10)
## id name cost secret_shop side_shop recipe
## 1 1 item_blink 2250 0 1 0
## 2 2 item_blades_of_attack 420 0 1 0
## 3 3 item_broadsword 1200 0 1 0
## 4 4 item_chainmail 550 0 1 0
## 5 5 item_claymore 1400 0 0 0
## 6 6 item_helm_of_iron_will 900 0 1 0
## 7 7 item_javelin 1500 0 0 0
## 8 8 item_mithril_hammer 1600 0 0 0
## 9 9 item_platemail 1400 1 0 0
## 10 10 item_quarterstaff 875 0 1 0
## localized_name
## 1 Blink Dagger
## 2 Blades of Attack
## 3 Broadsword
## 4 Chainmail
## 5 Claymore
## 6 Helm of Iron Will
## 7 Javelin
## 8 Mithril Hammer
## 9 Platemail
## 10 Quarterstaff
#heroes
head(get_heroes()$content, 10)
## name id localized_name
## 1 npc_dota_hero_antimage 1 Anti-Mage
## 2 npc_dota_hero_axe 2 Axe
## 3 npc_dota_hero_bane 3 Bane
## 4 npc_dota_hero_bloodseeker 4 Bloodseeker
## 5 npc_dota_hero_crystal_maiden 5 Crystal Maiden
## 6 npc_dota_hero_drow_ranger 6 Drow Ranger
## 7 npc_dota_hero_earthshaker 7 Earthshaker
## 8 npc_dota_hero_juggernaut 8 Juggernaut
## 9 npc_dota_hero_mirana 9 Mirana
## 10 npc_dota_hero_nevermore 11 Shadow Fiend
This is a first taste of the functions that can be used to access the Dota2 Steam API. If you want details about every single function you can follow the RDota2 tutorial. The vast amount of data that is offered through the API can be used for data science analysis on many occassions. For example, we could predict the winning team based on hero combinations or players’ past performances using machine learning. But I will leave that for another post!
The code for the full package is hosted on github.
Thanks for reading!