Ryan Markel

On Patch Notes

Video game nerdery ahead.

It's pretty safe to say the 1.1.4 update coming to Destiny 2 tomorrow is a big deal. It's an attempt to respond to criticisms of the game's shortcomings when it comes to the gameplay tuning, pretty much across the board—and it took Bungie over six months from launch to get to.

Lots of people are looking to this patch to reinvigorate some of the game and bring some excitement back to both PvE and PvP modes. It's been termed the "Go Fast" update, because it has tweaks to player movement, ability recharge rates, and some gunplay bits.

The notes won't drop until tomorrow, but I want to take a few to talk about patch notes and what makes for good game patch notes. At least so far, Bungie hasn't provided good patch notes for a game that a lot of hardcore players study down to specific numbers. In fact, just today, one day before the update, the main subreddit for the game has been publishing or republishing a lot of numbers, like these:

These posts have very specific numbers that are based on measurements being taken by players that have no access to the underlying math of the game—they are all based on observation. There's a post like this probably every week somewhere, detailing something and including numbers to show the work.

They shouldn't have to do this all over again; post-patch, the patch notes should give them all the information they need. I'll explain. Bungie's patch notes have previously looked like this (and yes, this is a bit cherry-picked, but it's representative and is from this update):

  • Increased the base damage and reduced the precision modifier of Precision Auto Rifles
  • Slightly reduced the aim deflection of High-Caliber Rounds on Auto Rifles and Scout Rifles
  • Reduced the effectiveness of Aim Assist at higher ranges on Scout Rifles
  • Reduced severity of recoil on Hakke High-Impact Auto Rifles
  • Hand Cannon accuracy recovery now scales with rate of fire
  • Improved base Aim Assist on aggressive Hand Cannons
  • Slightly increased the rate of fire time between bursts on all Omolon Sidearms
  • Slightly increased impact damage on lightweight single-shot Grenade Launchers

These aren't good patch notes. They leave me with tons of unanswered questions.

How much more damage will my Precision Auto Rifle do now? Why are you making it less precise, and how? High-Caliber rounds deflected aim before? What do you mean, and how is that changing? How much is "slightly," and does that mean roughly the same across the various notes, or does it stand for a range of values?

Almost everything in these notes is pretty vague.

Good patch notes should:

  • Tell you what changed.
  • Tell you how much and in what direction.

Great patch notes will also:

  • Tell you why something was changed.

The best example of this is almost certainly Killer Instinct. KI had the best patch notes of any game I have ever seen, followed pretty closely by Diablo III. Here's a great example of KI patch notes that accomplish this:


  • [Fulgore has been pretty difficult to balance. We’ve adjusted his rushdown, his zoning, and his instinct during Season 3 and he is still an extremely powerful character, which shows how tricky it is to find the sweet spot for him. Now that the dust has settled a bit, the team feels confident that Fulgore now has the weaknesses we intended him to have, but on the journey to this spot, we went a little far in a few areas. These buffs will not send Fulgore over the top again, but should help with some small quality of life aspects of his game.]
  • Raised Energy Bolt damage by 42% (from 7 to 10) [This gives him more zoning damage and more damage on his Energy Bolt into Teleport mixups]
  • Raised Light Cyber Uppercut damage 33% (from 15 to 20)
  • Raised Medium Cyber Uppercut damage 16% (from 12 to 14) [Usually, you’d expect the heavy version of a move to do the most damage, but in this case we wanted the reverse. The benefit of the light uppercut is the highest damage and most invulnerability, while the benefit of the heavy version is more potential damage left behind and multiple hits.]
  • Light and Medium Eye Lasers can now be Pip Cancelled into Energy Bolts. Heavy Eye Beam still cannot be. [This is a big buff to pip cancels and these versions of Eye Lasers, and as a result, his instinct mode as well.]
  • The minimum reactor spin speed has been increased slightly. It now takes about 10 seconds at the lowest speed to build one pip, instead of 12.5 seconds. [Fulgore’s weakness should be the odd way in which he gains meter. The old instinct mode gave him so much free meter per game that this weakness didn’t matter. Now that we have things functioning the way we want, we feel his default ‘slow’ meter gain is just a hair too low. Over the course of an average match, this should result in 3 to 5 more pips than you used to get.]

For real: these notes are amazing. Fulgore was a special case in that specific update, but these notes accomplish everything they should:

  • They tell you exactly what changed, and don't leave anything out.
  • They give you exact numbers for the changes, so there's no guesswork as to the extent of the changes.
  • They tell you why things were changed and what the intentions of the development team were when they made the change.

Look through the rest of that patch's notes, and you'll see more of the same. Specific, well-documented patch notes that indicate not only the exact changes made to the game, but the thought process behind them.

And look: I know these are two different game genres. One is a 2D fighting game with a limited amount of movement on a plane, and the other is a 3D first-person shooter with lots of complicated environmental and player-vs-player interactions to keep in mind.

But when you get down to it, it's still adjusting math and systems. This information is available to someone, somewhere. (If it's not available internally, there are other problems afoot.) And this goes not just for Destiny 2, but all games: please don't use vague terminology when you patch your games. (Capcom with SFV is another notable offender here.) Tell your players what you are changing, whether it was a bug you fixed or is a new adjustment, and why you are making the change and what you hope to accomplish with it.

They'll most likely appreciate it.


WordCamp US 2017 Presentation: Security, The VIP Way

This past Friday, I gave a 20-minute presentation on WordPress security, giving a high-level overview of things you can do to help keep your sites secure.

The Presentation

Here's a SlideShare embed of the presentation deck:

And you can download the Keynote source file for my presentation, including presenter notes.

Twitter Questions

As part of my talk, I asked attendees to submit any questions they might have had via Twitter using the hashtag #wpvipsec. Here are the questions I received, and some brief answers to them as best I can provide.

As we have been transitioning some of the WordPress.com VIP platform to our next-generation VIP Go platform, we've had to reinvent some of this stuff slightly. :) You'll be pleased to know that we have made the mu-plugins we use on VIP Go publicly-viewable on Github, and you can see our custom two-factor module here.

I don't know very much about securing sites via VPN, but I'm assuming here that you have site access (even front-end) locked to internal IPs only based on that VPN connection. That should handle a large portion of your security from outside attack, assuming the VPN is using appropriate security precautions.

At this point, your chief enemy is likely to become human error. This is where portions of the talk surrounding things like limiting user capabilities and access to certain settings pages can really help you out. Making sure your users are following good account security processes for connecting to the VPN is also critical.

As I suggested in the Q&A after the talk, I highly recommend that user roles and capabilities be in your WordPress engineering toolbox. They are enormously useful.

Multisites are interesting because they have additional layers of user access. Let's look at the two admin roles:

Super Admin: This should be as limited as humanly possible. The only users who should have superadmin powers on a multisite IMO are system administrators, your development team, and support users who will be assisting other users with account-level actions regularly. (An additional user or two might be necessary if you have people who need to spin up new sites on-demand rather than contacting your support team.) You should certainly require two-factor authentication here, and if you can require proxy or VPN access at this level, you absolutely should look into that as an option.

Administrator: This is going to be on a site-by-site basis within the multisite. If you can craft custom roles and their capabilities finely enough for your needs so that non-development users who are "in charge" of a site can use those roles instead of full admin, you should absolutely do this. Ideally, this user group and the Super Admin user group are as close to identical (and as limited) as possible.

The remainder of the roles are easier to parse. I'd like to especially recommend here (as I did during the talk) the use of an audit trail plugin; as you will have many users working on sites, and some with superadmin powers, the helpfulness of knowing which users performed which actions increases.

Additional Questions?

If you have any questions that haven't been covered above or in the talk, please send me a reply on Twitter and I'll be happy to drop them in the post and let you know when I have updated it.

I'll be updating this post occasionally with new information, as well as a link to the talk's video archive when it's available. To be notified of this, please either follow my blog or follow me on Twitter.

Destiny Discussion Stream: Bungie’s December Roadmap Post

Bungie dropped a pretty big blog post today regarding where they are with updates and changes to Destiny 2, which seems to be in a spot with some hardcore players.

My son and I hopped in-game tonight and had a chat about the changes while we were playing. We keep things positive and talk about the changes and a bit about the things others seem to want but aren’t yet getting (and may not get).

Garden Glow 2017

We took the family to the Missouri Botanical Gardens this evening for the yearly Garden Glow, where the front half of the grounds is lit up with various Christmas light displays.

I took a host of pics with my phone and didn’t do any editing on them—just posting them up now because if I wait much longer, I won’t make the post. :)

If you are in the St. Louis area, I highly recommend the walk; it’s quite nice and it’s very different being in the gardens at night, which you normally cannot do.

Bracket Running: Avoiding Disappearing Players

Bear dropped this on Twitter in reply to PerfectLegend, and I thought it worth it to mention something about how I handle it. Using this method, I have never had a problem with the following problem:

Here’s how you make this less of a problem:

Talk about this with your players before you start your bracket.

Issue clear expectations for things like bathroom and smoke breaks, because players will ask you for these things. Let them know that they need to ask for them immediately after one of their matches, and that you have to OK them by looking at the bracket and seeing what time is available for people to do so. Also let them know that when you and they agree on a time limit for these activities, and they go over the time limit, they can be DQ’d.

Know where you are in the bracket and how long matches take.

You can’t be honest with players regarding the time available to them for a break unless you know how much room you have in a bracket for those things. You’re generally only going to be able to give them break time in the first couple of rounds, because that is the only time you have a lot more matches to play than stations.

Make sure you are playing out matches by rounds as much as possible to give players time to rest between their matches. Don’t run one person way through the bracket before you have had other players get their matches in.

Write breaks down on the bracket sheet or a notebook/notepad (if using electronic bracketing, which you shouldn’t be in most cases), and make sure the player sees you do it.

When I have a player ask for a break, I talk to them briefly about what they are leaving to do and ask them how long it will take them to do it. I check the time on my watch, and then tell them exactly when I expect they will be back for their next match. I then write their player name and the agreed-upon return time on the bracket, showing them as I do this, and let them go have their break.

This becomes a two-way agreement; I let them take the break, and they agree they’ll be back by that time. If they aren’t back by that time, I generally give them two to three minutes’ grace period before issuing a DQ loss. (This also means that when budgeting the time for their break, I give them two to three minutes less than I actually have for them.)

Above all, be fair and respectful.

Before every bracket I run, I set expectations that I’m going to respect players’ time, and that in return, I expect certain courtesies from them. It’s only in partnership with your players that you’ll be able to run an efficient and well-received bracket. Respect your players’ time and communicate with them clearly, and they will respect the decisions you may have to make.

Extra Life 2017 – A Change of Plans!

If you’d like to contribute regardless of what I’m doing, please donate here! Otherwise, read on for more information.

Hello, friends!

In most years, this is the post where I would tell you that I’m running my Extra Life marathon tomorrow, as that’s the assigned Game Day for the program.

However, I have outstanding commitments for the entire weekend that will prevent me from doing the Extra Life thing on the assigned day. So this year, I’ll be moving it around a bit and am also planning on doing more than one of these. I may not be able to do anything 24-hour based on my various commitments, but I’m looking at a handful of 12-hour-plus runs.

The first one of these is going to be on November 11th, and will start at 9:00 a.m. Central. I’ll be starting Super Mario Odyssey, and will take it as far as I can. I’ll stay on Super Mario Odyssey for the marathon series as long as people continue to donate – for every $5 donated to my Extra Life campaign, I’ll find one more moon in Odyssey, up to 100%ing the game before the end of the year.

You are guaranteed I’ll get the minimum number of moons for a game clear. Money donated will go to moons past the minimum.

I’ll post more information as we get closer to the marathon and will also post more regarding additional mini-marathon dates as they are going to happen. (Expect something around Destiny 2’s first DLC release.)

Destiny 2: Month Two Gallery

I find myself hitting the screen capture button fairly often in this game, which is kind of nice. It gives me a record of what I’ve been doing and the things I’ve been messing with in the game.

My son and I are still playing together almost nightly, and it’s been a lot of fun. And we recently joined SafeGamers, giving us some groups we can play with who are respectful of our time and of us—a welcome change from a lot of online gaming experiences.

I’ve managed my first Destiny series raid, and cleared it a few times since then. I expect fewer screenshots next month, if only because I’m exhausting a lot of the content in the game prior to the first DLC release coming this December. (And I included the Legacy screenshots, which showcase some pretty neat art from various experiences I completed in the first game. I’m hoping my next Legacy is much more complete.)

Also, I’m aware there are some resolution problems with the carousel for these images; if you want to see the (much sharper) originals, use the button that appears when you are browsing the images in carousel.

macOS Command Line Tips

As previously mentioned, one of my favorite exercises is to avoid using system transfers when I move to a new MacBook, and instead start over from scratch, as I learn something new every time.

One big difference this time around has been that I am in the command line much more now than I have been in the past. I’ve been working actively on this as a skill, and as a result, it means more time sitting at a prompt.

The default terminal in macOS is fantastic, at least for the reason that it’s a modern OS with UNIX-like command line syntax—but there are some way it falls short, based on either its BSD roots or choices made by Apple.

The good news is that you can make up for a good number of those shortcomings with a bit of work, and find some neat tricks at the same time. I asked on Twitter for some additional tips:

I’ll be sharing any tips that I’m pointed to there for the first time in this post and subsequent edits, so if you have any tips of your own, drop me a reply on that tweet and I’ll check them out.

Optional Step One: Install a Terminal Replacement

This is very greatly a matter of personal preference, but I usually replace the Terminal app with an alternate solution. (This is where we pour one out for TotalTerminal a.k.a. Visor, of blessed memory.)

I prefer iTerm2 and its advanced features such as split panes, shell integration, and more intelligent buffering and options, but you may find something of your own you prefer. iTerm2 is also open source under the GPLv2.

Install Xcode Command Line Tools

Before we can do anything else of note with the command line, we should install some command line stuff that’s left out by default in macOS but very useful for a lot of the other things we’ll want to do. Thankfully, Apple made this bit pretty easy.

Open your command line and run:

xcode-select --install

You’ll be prompted to confirm this installation with a GUI dialogue. Accept it, and macOS will download the developer tools for you. (You will possibly end up upgrading some of these tools, but that’s OK. This will get you started and give you the basics you need.)

Get a Monospaced Font That’s Not Monaco

Monaco as a font is OK, but not great. There are two alternative options I usually recommend.

The first is the monospaced font that comes bundled in with the default Terminal app:SF Mono. Apple doesn’t distribute this font outside of either Terminal or Xcode from what I can tell, but you can extract it from the Terminal app if you would like. Get to the folder containing the font files using this:

open /Applications/Utilities/Terminal.app/Contents/Resources/Fonts/

Select all the files in that folder and open them, which will take you to Font Book to try and install them. Font Book will tell you there are problems with the font files. Font Book is lying. The installation will work, and I haven’t seen any reports of it being problematic.

(I think the warning is because doing this might possibly be against the terms of use for the font.)

If you would rather not pull SF Mono out of Terminal, or if the errors give you pause, another great option is to install Anonymous Pro, which has been my go-to fixed width font for years. It’s a great option and has a free license. You can download it here.

Get Homebrew for Package Management

Modern Linux distributions often use package managers to add and remove installed software with ease.

Now, when you run into a command line tool or other utility someone’s pointed out to you, you can usually install it more or less automatically with Homebrew. Here’s an example for wget, which quite honestly should be included with macOS, but isn’t:

pathfinder:nodecg ryanmarkel$ wget
-bash: wget: command not found
pathfinder:nodecg ryanmarkel$ brew install wget
Updating Homebrew...
==> Auto-updated Homebrew!
Updated 1 tap (homebrew/core).
==> Deleted Formulae

==> Installing dependencies for wget: openssl@1.1
==> Installing wget dependency: openssl@1.1
==> Downloading https://homebrew.bintray.com/bottles/openssl@1.1-1.1.0f.sierra.bottle.tar.gz
######################################################################## 100.0%
==> Pouring openssl@1.1-1.1.0f.sierra.bottle.tar.gz
==> Using the sandbox
==> Caveats
A CA file has been bootstrapped using certificates from the system
keychain. To add additional certificates, place .pem files in

and run

This formula is keg-only, which means it was not symlinked into /usr/local,
because this is an alternate version of another formula.

If you need to have this software first in your PATH run:
  echo 'export PATH="/usr/local/opt/openssl@1.1/bin:$PATH"' >> ~/.bash_profile

For compilers to find this software you may need to set:
    LDFLAGS:  -L/usr/local/opt/openssl@1.1/lib
    CPPFLAGS: -I/usr/local/opt/openssl@1.1/include

==> Summary
🍺  /usr/local/Cellar/openssl@1.1/1.1.0f: 6,421 files, 15.5MB
==> Installing wget
==> Downloading https://homebrew.bintray.com/bottles/wget-1.19.1_1.sierra.bottle.tar.gz
######################################################################## 100.0%
==> Pouring wget-1.19.1_1.sierra.bottle.tar.gz
🍺  /usr/local/Cellar/wget/1.19.1_1: 11 files, 1.6MB

Suggested Homebrew Packages

You can get pretty fancy with Homebrew. My colleague Jeremy Herve has a great script he uses to run it when spinning up a new system, and he posted about that here. I don’t install that many things via Homebrew, but there are a handful of things available through it that I use with some regularity.

If you know of any cool utilities I don’t; feel free to ping me on Twitter and tell me about them.


(source on GitHub; MIT license)

mas is a great utility that helps you with both installing and maintaining apps you have installed through the Mac App Store (which, admittedly, is fewer and fewer apps over time). You can even use it to search for apps and manage your authentication status.

pathfinder:nodecg ryanmarkel$ mas list
409183694 Keynote (7.2)
408981434 iMovie (10.1.6)
485812721 TweetDeck (3.9.889)
443987910 1Password (6.7)
904280696 Things3 (3.0.3)
803453959 Slack (2.6.2)
442007571 AntiRSI (3.3.0)
557168941 Tweetbot (2.5.1)
407963104 Pixelmator (3.6)
409201541 Pages (6.2)
682658836 GarageBand (10.2.0)
409203825 Numbers (4.2)
692867256 Simplenote (1.1.8)


(source on GitHub; GPLv2 license)

At work, we do a lot of code review and scheduling those code reviews. If I have a bundle of code and I want to size it up quickly to see what it does, I use cloc to do this. It’s a great first-look at how much work a review could end up being.

pathfinder:Development ryanmarkel$ cloc ryanmarkel-v2/
    1933 text files.
    1905 unique files.
     146 files ignored.

github.com/AlDanial/cloc v 1.72  T=8.46 s (211.5 files/s, 32469.1 lines/s)
Language                              files          blank        comment           code
PHP                                    1305          18979          44697          79398
CSS                                      79           5329           2056          32684
JavaScript                              149           4631           5865          20148
PO File                                  73           8254          12486          20091
XML                                      74            869            926           5606
Markdown                                 40           1512              0           3896
JSON                                     31             14              0           3282
HTML                                      9             14              0           1444
Velocity Template Language                1             11              4            470
Bourne Shell                              6            114             40            468
Maven                                     1             30             21            305
YAML                                     10             52            111            262
Ant                                       1             19             30            140
INI                                       7             27             89             95
DTD                                       1             25             54             69
XSLT                                      1              5             14             19
make                                      1              1              0              3
SUM:                                   1789          39886          66393         168380


(source on GitHub; BSDv2 license)

streamlink is a forked successor of livestreamer, which unfortunately became a dead project but is insanely useful. It uses command line instructions combined with (normally) an install of VLC to open streaming video using a method that tends to be much lighter-weight than using a browser. It will help you identify various transcodes as well, and can be used even to load authentication-required video for some services.

pathfinder:Development ryanmarkel$ streamlink https://twitch.tv/gamesdonequick
[cli][info] Found matching plugin twitch for URL https://twitch.tv/gamesdonequick
Available streams: audio_only, 160p (worst), 360p, 480p, 720p, 720p60 (best)

Bring Some Color to bash

Some of the tools that are included with macOS at the command line and its default configuration are slightly altered from defaults you may be used to in other UNIX-like environments. One that tends to bother me is that by default, ls doesn’t have any color indicators for output. By default, it looks like so:

This really isn’t helpful. Let’s add at least some color marking by adding this to our ~/.profile:

export CLICOLOR=1

Now, when I’m in a terminal session in any terminal app, I should see my directories like so:

You may also wish to customize your prompt using the information you can find here, but the number of options there are a bit much for me to get into.

Using pbcopy/pbpaste

Mark Jaquith replied to me with this tip:

Straight up: I did not even know about pbcopy and pbpaste, but reading the man pages for them, it’s crazy I went this long without knowing what they were and how to use them.

You can use the commands to move text back-and-forth between your terminal session and the macOS Clipboard. This should be self-explanatory, but for example, I just realized that I could have used it to put large chunks of the output from commands in this very post without having to select it and copy it.

What Am I Forgetting?

If there’s a neat trick or setup tip you think I’m missing, please let me know! Drop a reply to either the tweet for this post or the one I posted earlier and let me know what I can add!