Tag

Showing blog posts sorted under the tag: halo

haloR - A New R Halo API Wrapper

Earlier this week Microsoft released Halo Wars 2, a followup to the original that has somewhat of a cult following. In contrast to the mainline Halo titles, Halo Wars is a real-time strategy game. I've played through the Halo Wars 2 campaign and dipped my feet a little bit into the multiplayer. It isn't really for me (I prefer FPS) but it was still an enjoyable experience.

Similar to Halo 5, Microsoft and 343i have decided to open up much of the game details to the public through their Halo API. I really enjoyed digging through Halo 5 data and it was a big engagement point for my interest in the game. Kudos to MS/343i for the work they do on this stuff.

Even though I don't plan to continue playing the game, I decided to update my Halo R API wrapper to now include functions to easily get data from the Halo Wars 2 endpoints. Installation instructions and a tiny example can be found on the haloR Github.

Before using it, I suggest reading through the documentation provided my 343i since the documentation for my package is kind of sparse and the returned objects can be a little bit cryptic without a reference.

And as an additional small example, I pulled some Halo Wars 2 data for the game mode 'Rumble'. This is a new mode where players have infinite resources and don't have to worry about their economy. I wanted to see which leader had the highest winrates so I pulled a bunch of matches and graphed their percentages (at the top of this post). It's interesting that the two main story characters, Cutter and Atriox, have the highest winrates.


Tags:


Objective Gametypes and KDA

Something that often gets said regarding objective gametypes (capture the flag, strongholds, etc.) is that KDA (kill-deaths-assists) does not matter as long as you're getting the objectives. So I wanted to dig through some of my recent Halo 5 matches to see if there's any truth to this statement. Using a sample of recent objective games that I completed, a logistic regression was performed using Kills, Assists, and Deaths on the dependent variable of winning or losing. Basically I want to know how much each of these variables influences the probability of winning or losing a game.

This was also a bit of an excuse to play around some more with the language Julia. I've been starting to use it more at work and am really enjoying what it offers. Although it's tough to compete with the whole R ecosystem, thanks to the RCall package it makes the transition pretty painless. Head over to Julia-Lang if you want to know more.

First the non-Julia stuff. Since I want Halo 5 data I'll be using RCall to interface with my R package to get some data. Below is a simple wrapper function to get the match data I want using my h5api package.

using DataFrames, RCall, GLM

api_key = "itsamystery"
slayer_id = "257a305e-4dd3-41f1-9824-dfe7e8bd59e1"

R"library(h5api);library(data.table)"
function getRecentMatches(player, modes, start, count, key)
  R"recent_matches <- getRecentMatches(player = $player,
                                        modes = $modes,
                                        start = $start,
                                        count = $count,
                                        key = $key)"
  r_data = R"cbind(rbindlist(lapply(recent_matches$Results$Players, flatten)),
                  id=recent_matches$Results$GameBaseVariantId)"
  return rcopy(DataFrame, r_data)
end

Next, just using a simple loop I'll grab data from 250 of my most recent matches. CLWakaLaka is my gamertag, so you can either use mine again or try your own if you play Halo 5.

match_data = DataFrame()
for i in 0:9
  match_data = [
    match_data;
    getRecentMatches("CLWakaLaka", "arena", i*25, 25, api_key)
  ]
end

This performs a little cleaning up before performing the regression. Besides a win or a lose, it's possible for a match to end in a tie or disconnect. So first only definite win/lose matches are considered. Slayer games are also filtered out. Since kills are the objective in this game type it goes without saying that KDA directly influences your likelihood of winning. Finally the result is changed to a simple 1-0 variable. 1 meaning win and 0 meaning lose.

match_data = match_data[((match_data[:Result] .== 1) | (match_data[:Result] .== 3)) & (match_data[:id] .!= slayer_id), :]
match_data[:Result] = map(match_data[:Result]) do x
  if x == 3
    return 1
  else
    return 0
  end
end
match_data[:Result] = convert(Array{Float64, 1}, match_data[:Result])

Finally, using the GLM package, a logistic regression is performed in the data with the following results:

my_lm = glm(Result ~ TotalDeaths + TotalAssists + TotalKills,
            match_data,
            Binomial(), LogitLink())

Formula: Result ~ 1 + TotalDeaths + TotalAssists + TotalKills
Coefficients:
               Estimate Std.Error   z value Pr(>|z|)
(Intercept)   0.0405304  0.531324 0.0762819   0.9392
TotalDeaths   -0.202424 0.0572149  -3.53796   0.0004
TotalAssists   0.202192 0.0941433   2.14771   0.0317
TotalKills     0.121854  0.049335   2.46993   0.0135

So what does this tell us? Well the logistic function looks like this: 1 / (1 + exp(-( intercept + b1x1 + b2x2 + etc. ))) Where bi's are the estimates above and xi's are the data points. For example, if I had a game with 10 kills, 4 assists, and 8 deaths, then my estimated probability of winning that game would be: 1 / (1 + exp(-( 0.0405 -0.2028 +0.2024 + 0.122*10 ))) = 0.61 or 61%

From the estimates above: deaths negatively influence the probability of a win and kills and assists influence the probability of a win positively. All three variable estimates have a p-value of less than 0.05 which suggests they are significant factors in the overall outcome of a game (obviously). The intercept, however, is not significant which makes sense since we likely have no data for a 0/0/0 game.

Interestingly, deaths and assists coefficients have roughly equal magnitude while the coefficient for kills is slightly less. This would suggest that the relative importance of these actions corresponds to Deaths = Assists > Kills. Meaning that the most important factors towards getting the win are (in this order): not dying, always shooting/helping teammates, then getting kills.

So there we go, it seems there is a little kernel of truth in the idea that KDA in an objective-based gametype is not everything... Although it certainly helps, and feels so good.


Tags: