Skip to main content

Pretty Good Hat

Tag: Destiny

Today I made improvements to some R code in my Destiny 2 hobby-coding-verse after learning how to much more cleanly deal with nested lists. I had previously used a solution using map() to apply a selector to each item in the list, but this was clunky, hard to remember, and became really hard to read with several levels of a nested list.

The far better solution is the unnest_auto function from {tidyr}, which I came upon when tinkering with the last.fm API data recently. Once I understood how it works, it’s so easy and satisfying! The key is to first make a named tibble.

> tibble(my_tibble = instanced)
# A tibble: 906 × 1
   my_tibble        
   <named list>     
 1 <named list [10]>
 2 <named list [10]>
 3 <named list [10]>
 4 <named list [10]>
 5 <named list [12]>
 6 <named list [10]>
 7 <named list [10]>
 8 <named list [10]>
 9 <named list [9]> 
10 <named list [9]> 
# … with 896 more rows

That nice tibble can be operated on by unnest_auto():

> tibble(my_tibble = instanced) %>% unnest_auto(my_tibble) %>%
select(itemLevel, breakerType)
Using `unnest_wider(my_tibble)`; elements have 8 names in common
# A tibble: 906 × 2
   itemLevel breakerType
       <int>       <int>
 1       132          NA
 2       133          NA
 3       133          NA
 4       132          NA
 5       133           3
 6       132          NA
 7       133          NA
 8       133          NA
 9         0          NA
10         0          NA
# … with 896 more rows

(I selected just a couple of columns for readability there; if you don’t do that, you’ll receive all fields at the current list level, including additional nested lists if they exist). After figuring this out, I realized that I also needed to keep the names of each list element, because they constitute a unique ID for the element returned from the API query, and I banged my head a bit on trying to do that as a part of the unnest operation, before I backed up, recentered on the outcome I wanted to produce, and realized I could do it really cleanly using mutate()! The final code looks like this:

> tibble(my_tibble = instanced) %>% unnest_auto(my_tibble) %>% 
select(itemLevel, breakerType) %>% mutate(id = names(instanced))
Using `unnest_wider(my_tibble)`; elements have 8 names in common
# A tibble: 906 × 3
   itemLevel breakerType id                 
       <int>       <int> <chr>              
 1       132          NA 6917529338105913753
 2       133          NA 6917529550016812142
 3       133          NA 6917529281178546429
 4       132          NA 6917529231127188610
 5       133           3 6917529301504642848
 6       132          NA 6917529234625200021
 7       133          NA 6917529193313832065
 8       133          NA 6917529182955737017
 9         0          NA 6917529417667489181
10         0          NA 6917529490520758715
# … with 896 more rows

The D2 API returns a ton of nested lists, so this simplified, accessible and effective tool is 100% getting a featured spot in my toolbox.

Destiny 2 Power leveling tool in R

The latest piece of my homebrew Destiny 2 toolset is Travelr, a power leveling tracking tool built with R and using a much simpler process than most of my prior nonsense. (Aside: I'm still using ArmoreR, but it has some key limitations that I haven't spent much time with, including a problem incorporating the authentication flow more fully into Shiny so that I could make it an app that others could use in a more friction-free way.)

The power climb is part of the game with each new Destiny season. A lot of this process is luck: A player can only get so many pinnacle drops per week and there's no guarantee that a given drop won't be in a duplicate category. But, some drops can be targeted to broad categories -- armor versus a weapon, for example -- and there is some efficiency across characters if you can strategically raise one category to increase the base level for all characters. 

I was inspired by a fantastic tool written by a member of the small Destiny 2 community I'm in, that identifies categories to target (or, try to target, anyway; a lot of it is still frustrating random luck, sometimes), and decided to try building my own version. It doesn't do anything unique, but it works and it's wonderfully satisfying to step through an R markdown notebook that authorizes me to the D2 API, retrieves all my equipment statistics, calculates my maximum power level and indicates which, if any, categories should be targeted.

For example, here's a screenshot from the beginning of the season, where every single equipment type would increase my total maximum power level:

A screenshot of a table of data showing lots of equipment categories that would increase power level to the next integer

... and later in the season:

Travelr screenshot showing a table of armor and equipment values, highlighting values that would increase the total maximum power level to the next highest integer

It's been great fun to have this small tool with me during the season's play. It's currently dependent on another small tool that grabs the equipment "manifest" file, and I'll be publishing the whole notebook to github when I finish incorporating that into the repository. 

Today I dusted off my latest video game hobby project, ArmoreR, my Destiny 2 armor stats profiler, and finished some improvements that have been on my list. I haven’t been motivated to dig back into it for a while partly because I just … didn’t feel like it … and partly because I had hit a point of complexity with it that made it hard to approach again. But I had a really nice time catching up with just how it works and then gradually identifying and implementing the improvements I wanted to make. It’s a good lesson that is sometimes hard for me to remember, that small but concrete steps add up.

Destiny nerd warning, most people can probably stop reading now: This version adds something really useful to loadout building: class items! I had to think on how to do this for a while, because most class items don’t add much to the stat value of an armor build, and each added class item combinatorially increases the number of armor set combinations that have to be measured. I settled on including only masterworked class items because they add enough stat points to tip one or more categories into the next tier. Still, for characters that have a lot of armor to choose from, doubling (or more) the total number of builds does add to the time that the tool requires. I added some ways to optionally include/exclude more armor to try to make this processing time more bearable. I also found a few improvements to make and fixed a number of bugs along the way, and will plan to return for a round of efficiency-finding later.

The tool is at a neat, workable point right now, where it’s actually useful for finding armor builds and, really critically, the armor pieces that work across multiple builds of interest. I’ve learned a ton working on it, and am pretty proud of it. There’s more documentation over at the application and if you happen to be into Destiny I’d love to hear what you think.

Spent a good chunk of the day learning how to make a Shiny app out of my Destiny Armor Profiling Thing. That was fun and my brain is also broken.🎮

🎮 Speaking of Destiny, a note out to my micro.friends gamers: The upcoming expansion will be free for XBox with Game Pass, so if any folks new to the game are interested in checking it out, I’m happy to team up and show you some ropes! (I’m actually playing primarily on PC/Steam, so equally happy to meet up there.)

Alan Plays Destiny - Season 11

This was an extra-long season of the game due to delays in the launch of the next significant expansion, Beyond Light. That length worked well for me because I bounced out of the game for a while this summer and fall and enjoyed some other games and pastimes from my mostly-quarantined home. (The seasonal experiment has been at times a lot of fun and often really frustrating, because it created a game loop that was often too much of a grind.)

But then I happened into spending more time with a nice community of friendly and welcoming players, and had a really good time the last several weeks checking off activities that I hadn't completed and earning my first titles in the game. Those are special designations that players get to wear in-game for finishing significant sets of activities centered on seasonal quests or specific game modes. It feels good to rock the MMXX label while shooting space magic at aliens. 

2Q==

I'm happy to have come back and really enjoyed the game lately, pleased to have earned some titles, but most fulfilled by having done it alongside folks who are good company. We cheerfully helped one another complete raids we hadn't checked off and finish incomplete quests.  Having finished off the title for both the current season and the "moments of triumph" title for 2020, I'm ready for more.

2Q==

Previously in this series:

Alan plays Destiny - 2020 Edition

Previous updates:

----

It's been a while since I did this, so here's another set of revised win/loss numbers and weapon stats for my Destiny 2 play. The final Iron Banner -- a week-long competitive PVP mode -- of the current season concluded last week, so I thought it was time to wrap up this edition of the perpetually-open fish shell and R Studio session and get on with making a picture of my data. 

Iron Banner holds a lot of fun, nostalgic memory for me from the first Destiny. It was one of the events that offered a chance at loads of high-powered loot that one could use to upgrade gear, and diving into it broke my reluctance to spend time playing in PVP game modes. The current incarnation of the game mode is not quite the same loot-fest, but it's still a game type that I generally have fun with, so I look forward to playing it when it comes around. It's also a nice discrete mode to use as a lens into my game data. Here's a big picture of my games since the launch of the last big expansion, Shadowkeep, last fall:

And the summary of all that data says that I perform pretty similarly across all three of my shooty space dolls, with the edge going to the Warlock. (Which surprises me, actually.)

class Outcome #Games Avg K/D

------ ------- ------ ------ Hunter Defeat 51 12.92 Hunter Victory 57 12.72 Titan Defeat 55 13.64 Titan Victory 58 14.41 Warlock Defeat 41 13.95 Warlock Victory 61 15.49 

This last completed Iron Banner was the first such event in a long time where a non-Erentil was anywhere close to my use of that precious voop-shooter; I had a really good time experimenting with a fun change-up in my loadout, which is probably a good finding, since Bungie will be sunsetting all my favorites in seasons to come. 

Tune in next time, when I might, finally, complete writing up the chain of tools that I use to make this data. If you made it this far and need a buddy in-game, I'm playing on Xbox and on PC these days; let's splode some aliens sometime from our respective quarantines.

A dot plot showing win and loss performance over time, with my Titan having a slightly better performance A plot of Destiny weapon usage showing the Erentil fusion rifle being my far and away favorite

I’ve been meaning to post an update to my Destiny Stats for a good long time. While I have a long methods post sort of drafted (and have dramatically improved the way I produce this information), I thought I’d share these stats from the Iron Banner events through the Shadowkeep expansion: A plot of my win-loss and score by class, and a visual of total weapon usage. The latter clearly shows that I have a pretty serious fusion rifle problem.

I just finished up the newest Iron Banner event today. I haven’t played much Destiny the past month or so, but got back into it with this week’s event and had a lot of fun.

One of the things that continues to be neat about keeping these records is that the picture, once I finally build it, does tell a story. There’s the Erentil story, obviously (that fusion is so good), but also the numbers for Beloved and Imperative each represent time earning pinnacle in-game weapons, for example. I really like the reminders of the times that I enjoy playing this game that live behind these numbers.

Alan Plays Destiny: My Season 3 Summary

A while back, I wrote about my "Destiny Diary," a combination hobby coding and gaming project that uses the Destiny 2 API to gather information about my in-game loot and identifies new items so that I can annotate them with my own tiny journal about my play. This was a way of telling stories that come out of my time playing the game, and trying to play conscientiously. 

For "season 3" of the game, I continued this tracking, and added a brand new feature: game-by-game storing and aggregation of my stats. There are tracking sites that use the API to monitor the meta -- overall weapon dominance and how those numbers trend over time -- but they don't provide per-weapon detail *per player*. So I set about to do that for myself, and kept the record of every activity (more or less) that I played through this season of the game (roughly, early May through early September). Each game is stored as a json file that I can parse (again, with my favorite ever tool, jq), build summary data, and then bring into R to analyze and visualize.

Now, just as the Forsaken update is about to launch and end season 3, I thought I should actually go look at that data. Here are my top twenty weapons, by kills, for each of the PVE and PVP game modes:

|       PVE         |  n   |               PVP                |  n  |
|-------------------|------|----------------------------------|-----|
|      Sunshot      | 2408 |          Vigilance Wing          | 325 |
|      Crimson      | 1763 |         The Jade Rabbit          | 251 |
|   Origin Story    | 1199 |             Crimson              | 188 |
|     Valakadyn     | 1193 |            Valakadyn             | 120 |
|   True Prophecy   | 1024 |            Kibou AR3             | 116 |
|   Polaris Lance   | 852  |         Perfect Paradox          | 63  |
|  Niflheim Frost   | 822  |         Positive Outlook         | 62  |
|    Vacuna SR4     | 715  |         Main Ingredient          | 56  |
| IKELOS_HC_v1.0.1  | 613  |       The Time-Worn Spire        | 39  |
|    Conspirator    | 522  |            The Vision            | 37  |
|  Perfect Paradox  | 443  |            Vacuna SR4            | 33  |
|     Kibou AR3     | 442  |           Proelium FR3           | 28  |
|   Better Devils   | 392  |         Sins of the Past         | 25  |
| Positive Outlook  | 355  |         Legend of Acrius         | 23  |
|   Machina Dei 4   | 333  | Hawthorne's Field-Forged Shotgun | 22  |
| Sins of the Past  | 244  |           Manannan SR4           | 18  |
| Inaugural Address | 200  |       Stochastic Variable        | 18  |
| Nameless Midnight | 170  |          Retrofuturist           | 15  |
| Skyburner's Oath  | 170  |           Conspirator            | 13  |
|  The Conqueror 2  | 156  |         Magnum Shepherd          | 13  |

There are actually a lot of stories just in this summary data! The top 2 for each game mode have a ton of kills, in part because those were required for the masterwork catalyst for each: Sunshot and Crimson had PVE masterwork requirements, while I went to the crucible *a lot* for the Vigilance Wing and the Jade Rabbit masterworks. And while I told myself at the time that I came to really enjoy the Jade Rabbit, you can see here that I did exactly the 250 crucible kills required for the masterwork, plus 1 (!), and then put it away again. Oh, well. 

On the PVE side, after the masterwork grind, two auto rifles and a hand cannon round out my top 5, which tell a lot of stories of running strikes and story missions. Four of the rest of my top 10 are great, favorite scout rifles that I rotate frequently (Polaris Lance melts big enemies and I still haven't finished its masterwork). That Vacuna SR4? That's the D2 equivalent -- almost! -- of the legendary Hung Jury from Destiny 1. Also noteworthy is that three of those scouts are new in season 3; my previous season's favorite scout, Nameless Midnight, barely makes the top 20 (sorry, buddy; still <3 you). 

I would like to have a season 2 to season 3 comparison for PVP, because I changed a lot this season. These numbers show a lot of Crimson and auto rifle use, and less pulse, but the Time Worn Spire (pulse) was one of my favorites in season 2, especially during my grind for competitive wins at the very end of the season. Otherwise, while my numbers overall are much lower than for PVE (of course, because I play far more of that mode), there's a lot of variety here: more SMGs, shotguns and fusions. (Also, The Vision: the weapon finally, finally awarded by my forever faction, Future War Cult, for winning a faction rally finally.)

Bar graph showing number of kills per weapon, by game type (PVP and PVE)
Bar graph showing number of kills per weapon, by game type (PVP and PVE)

The plot above is just a different way of visualizing the same data, mostly to show how steeply different the overall numbers are for PVP and PVE, and to call out the handful of relatively big PVP numbers: again, those blue spikes are the weapons that I worked hard on for masterwork catalysts, and you can see how much higher they are than the comparable PVE numbers for the same weapon. 

This is a really interesting and useful way for me to document one of the hobbies that occupies a good chunk of my free time, and now that I've explored some of the data I'm happy that it sparked as many gaming memories as it has; there's a lot of time in successful and unsuccessful raid attempts, gradually improving crucible skill, and questing for specific items represented in these numbers. Forsaken/Season 4 introduces a new weapon system and will have a ton of brand new gear, so I'll look forward to watching my trends as we go into the new several months of the game.