Launch, the universe, and everything

Introduction

This post is going to be an absolute doozy. It is as much of a post-mortem as a blog post can be without the product in question actually being dead. We’ll talk about what went right, what went wrong, and all of the things I learned along the way. There will be plenty of duplication between other blog posts and my FAQ so that this can be a one-stop shop for those interested in hearing the journey of Bot Land.

History

Iterating, forming a business

In September, 2010, I had an idea to make a game involving scripting. I worked on various iterations of it in my free time for 5 years, never really producing a full game, but always tinkering with Bot Land to some extent.

Here’s the scripting view of the 2010 version that I wrote in Python:

Here’s the game as a multiplayer RPG from 2011 in Java:

Here’s the “lite” version of the game in 2012 (also Java) since the original plan was too vast:

There’s another iteration of Bot Land as an RTS that I don’t have screenshots of, but it’s similarly unimpressive.

After all of that solo work, a co-worker of mine approached me in 2015 about designing a game involving… you guessed it—scripting! I was excited; I told him about my original ideas, and we came up with a new design.

Within a month or so, code was executing in our prototype-of-a-prototype:

We talked to another co-worker who spent a whole weekend making art, and in another month, the game looked like this:

Another month in and we had different weapons, more sprites, and extra features:

The game design was very different from the current version. In this prototype, there was a single, persistent, deathmatch-style arena wherein players would deploy bots. As soon as they died, they’d get redeployed, so players didn’t need to be online for the game to have activity in it. Gameplay was mostly about picking a leaderboard (e.g. “damage dealt with lasers”, “resources collected”) and aiming to top it for the given hour/day/week.

This original version of the game was fun for about a week or two, then gameplay became stagnant. People had unlocked all of the items. They’d tried all of the strategies that they were interested in. There was no real sense of progression after that because the arena lasted infinitely, so players likely didn’t feel that they had much of an impact beyond the transient leaderboards.

But this was just a fun side project for everyone involved. It wasn’t until roughly July of 2015 when that started to change. I felt like I wasn’t learning much at my job anymore, so I talked to my wife about what I should do. She suggested that I try to productize Bot Land.

I conferred with the co-worker who’d originally approached me about designing a scripting-based game, and he was on-board. He wouldn’t be able to work full-time on it, but it was good to know that I had help going into this.

I quit my job as soon as possible and set out with a plan: I would start a business, dump a significant portion of my savings into the development costs, hire a UX designer and some artists, and we would produce a version of the game that was ready for the world. We guessed it would take about 18 months to complete.

Redesigning the game

We knew that we eventually needed to make money from the game, and we didn’t think a single arena worldwide could accommodate the number of players that we’d need for that. We redesigned the game to be a 1v1, timed battle that would require both players to be present and active for the duration of the match. We hoped that this would alleviate some of the other problems with stagnation and progression.

In the first twelve months, things were starting to fall apart on many fronts. The co-founder wasn’t able to devote as many hours to Bot Land as he’d hoped. This became increasingly challenging when we realized that the game still wasn’t fun.

This led to the most stressful month of my entire life: August of 2016. On August 21st, discussions with the co-founder about parting ways finally came to a conclusion. This was amidst frantic redesigns to try to salvage what we could of the game. What I settled on, game-design-wise, was asymmetrical multiplayer. I discuss the background behind pivoting the design here:

Post-mortem

Looking back, there are several things that I would have changed if I could.

For one, optimism has no place in the business world. We should have confirmed or denied whether the redesign would be fun sooner than we did. However, even as I type that, I will add that it’s difficult to know exactly what makes something fun. It’s what led to August being such a crushingly stressful month. You can’t just tell a player to ignore all of the glaring flaws and only try to focus on the game mechanics. Instead, it’s a package deal—the summation of graphics, music, sounds, gameplay, and user experience is what influences a player toward having fun.

The second set of learnings is around co-founders. I do not begrudge the original co-founder for prioritizing life over work. A combination of hopeful expectations and repeated, fruitless conversations about improvement is what left me bitter.

Before Bot Land, we had made a single game together that was much smaller in scope, and we both considered it to be a great success. I think that success gave us false confidence; Bot Land’s scope was gigantic compared to the first game, so we perhaps overestimated how well we worked together simply because there was less work to do.

I learned that having a co-founder was incredibly important to me even if there were no official business dealings; I need someone with as much context and stake in a project as I have so that I can discuss things with them. Over the years, I’d approach friends about various decisions (e.g. “does this feature sound good?”, “is this a good way to monetize the game?”), and while they would give input, they weren’t on the hook afterward for the fallout of whatever decisions were made. What’s more is that you eventually reach a point where you burden your non-co-founder friends with your troubles.

In practical terms, I think that a co-founder should either provide some set of knowledge or skills that you absolutely do not have, or they should be as invested as you are (either monetarily, timewise, or both) so that responsibility can be reasonably split.

Twitch

The History section covered up until August, 2016, but we have to jump back a year for this section.

In August, 2015, I decided I would stream the development of Bot Land on Twitch. People have asked what my motivation was, and it boils down to three things:

  • Accountability – I wanted to stay on-task throughout the day
  • Marketing – I needed people to know about Bot Land in order to make it successful
  • Ego – I saw someone else streaming development once and I thought I could do a better job

I had no real plan and no idea what to expect, so I posted to reddit that morning hoping that I would get helpful suggestions on how to grow such a stream (side-note: it’s funny to read that thread now that I’ve streamed for so long).

That first day, there was way more traffic than I thought I’d get (~50 average viewers). I ended up narrating what I was doing, interacting with chat, and just generally dipping my feet into the very foreign waters of broadcasting my work to the world. I was quite accustomed to gaming streams having watched Twitch for a few years at that point, but now I was on the other side, and it was exhilarating!

I started out with a schedule of 32 hours a week of streaming—8 hours each for four days. I was as consistent as I could be; I started at the same time almost every day, I never once let my ETA timer hit 0 whenever I took a break, and I tried to announce any absences ahead of time. This schedule held until 2019 when I decided to cut back to 16 hours per week, that way I could tackle sensitive work off-stream.

When not streaming, I tried not to work much, but I was still overwhelmed by stress many more times than I’d like to admit. I felt like there was always a weight on my shoulders, that the world was looking at me, and that I owed it to myself not to mess up this amazing opportunity.

I learned a lot from my time streaming:

  • 8-hour streams would completely drain me of any energy I had. I’m an introvert, so trying to code, be entertaining, and interact with chat all at once spread me thin.
  • Exceeding 32 hours a week of streaming was practically a guarantee that I would burn out.
  • When a burn-out would happen, the only real remedy was to take planned time off. Unplanned time off, like when I would stop after being too frustrated for a particular day, led to guilt.
  • Being in front of a camera for so long means that people will see you in practically every mood that you have. Once people know what an average day is like for you, you start to get comments whenever you deviate from that average. This was true whether it was something small (like not styling my hair) or something big (like appearing more tired than normal).
  • It was surreal to have a community form around the stream and Bot Land. They provided much-needed human company, levity, and help of all kinds throughout the years. Twitch is how I met HiDeoo, who has helped greatly with the development of Bot Land.
  • Communities like to have celebrations even if they’re for seemingly arbitrary milestones (like 1000 followers or 500 days of streaming). I think I could have done more over the years on that front.
  • I got to learn what people appreciated about my workflow and what they thought could be improved.
  • Many companies start out trying to make Product X, but along the way, they discover that they have a real opportunity with Product Y. My Product X is Bot Land, but I think my Product Y is some kind of semi-educational streaming. I feel like it gives me a back-up career option should I need one.
  • You make pennies on Twitch compared to what you make as a traditional programmer (note that I never streamed on Twitch to make a living even though I do have subscriptions and cheering enabled on my channel).
  • I don’t like playing games on Twitch. I play games to relax, and the only interaction I tend to like during a game is with the other players of that game.
  • Your productivity will take a hit if you’re streaming on Twitch. It’s just not possible for a programmer to keep flitting between chat and their code without one of the two failing. I tried to overcome most of the context-switching problems by taking excessive notes. It worked reasonably well.

5000+ hours of the streams are archived here, so if you want to see how things evolved over that time, take a look!

Many people ask about what the future of the stream looks like now that Bot Land has launched. Well, even though it launched, it’s not done, so the stream will still be up until 2020. Then, who knows? If Bot Land is doing well, then I’ll probably keep doing it. If it’s not doing well, then maybe I’ll consider that Product Y that I mentioned in the form of an edutainment show. Whatever it is, I’ll likely let everyone know through one form or another.

Part of why I’m writing this entire post is for personal reasons; I want a snapshot in time of what my life looked like at this moment in October, 2019. To that end, I’ll include some stats here about how the stream has grown:

Here are the current view/follower numbers:

And here’s how the average viewership has changed over the years:

(that large spike in September is due to front-page coverage on Twitch for the launch of the game)

Finally, I wanted to link to this somewhere: here’s my advice to prospective development streamers.

Launch

Picking a date and launching

Despite earning money on Twitch, I wasn’t making anywhere near the amount that I’d make at a traditional job. If you recall the History section, my wife and I only expected Bot Land to take about 18 months (which would have put us in about March, 2017). In late 2018, we both agreed that the end of 2019 would be a good stopping point unless the game proved to be profitable, which meant I couldn’t keep working indefinitely.

Common business advice nowadays is to launch a minimum viable product (MVP), then incorporate user feedback and quickly navigate that product to whatever success may look like.

The problem is that I had no confidence that people could enjoy the MVP, which I probably had done sometime in 2016. My thought process progressed something like this:

  • If I publicize the game now, the servers won’t be able to handle the influx of traffic.
  • The UI isn’t good enough.
  • There should be a tutorial.
  • The tutorial could be better.
  • People keep asking for mobile versions, but they’re not ready yet.
  • People keep asking about a Steam launch.
  • I haven’t done enough marketing.
  • [A maddening number of other bullet points could go here]

At almost any point, I kept thinking that it couldn’t possibly be launched. But the deadline of 2020 forced my hand, and I picked September 24th for the launch date (which ended up sticking).

The game had already been playable for four years at that point, so “launching” only really meant two things:

  • Real-money payments would be enabled
  • Players would have their in-game progress reset (e.g. they’d lose their unlocked items, any Botcoin they’d accrued, etc.)

I planned Launch Day to go like this:

  • Start streaming at about 9 AM (and Twitch agreed to give me front-page coverage for two hours to help promote the game).
  • Start the deploy process on-stream, which typically took about 30 minutes. I planned for something to go wrong, so I figured that I would have the game online by 10 or 11 AM.
  • Make marketing posts on various social media sites.
  • Celebrate with everyone.

If I had to sum up how those plans went with a single emoji, I’d pick 💣. The deploy process failed for some unknown reason that I’d never encountered despite the number of attempts (and even practice attempts specifically for launch) I’d put in. My front-page coverage ended before I even got the game online, meaning many people who joined the stream were just watching me amass anxiety in realtime.

I set to frenetically coding and eventually deployed. We discovered that email verification wasn’t working in-game, which meant people also wouldn’t be able to make real-money purchases. Even if they had been able to, iOS payments in particular were broken in several ways (and actually still aren’t online even as I draft this post). Then, due to having to hack together solutions in front of a live audience, I ran into a security problem that I had to fix.

What did I learn? If you’re going to launch at a live event, then make sure it involves nothing more than cutting a rope, and even then, bring a back-up rope. I should have had everything set up and waiting so that I could have just enabled traffic to the production servers.

On the plus side, the celebration aspect ended up being so incredibly heartwarming that I felt uplifted for at least two whole days afterward. The community, led by EveryJuan, put together a video commemorating the stream (Twitch highlight here, same video on YouTube here).

Expectations, goals, and metrics

I am bad at marketing. I imagine most people who start a business do so with the notion that they’ll stick to the core of the business, which in my case is game development. Unfortunately, that’s not how you succeed unless you have oodles of money to hire people who can fill in the gaps. Instead, you need to wear many hats: marketing, customer support, business development, design, etc.

I learned how bad I was at marketing leading up to launch. I wrote a 41-page document that I was using as a roadmap to guide me through the marketing phase. I’d contacted tens of streamers and YouTubers, and practically no one even replied to my emails. I ran advertising campaigns that didn’t really get anyone to stick. I tried some experimental ideas like a tongue-in-cheek crowdfunding campaign and a video specifically targeting subreddit culture.

Due to the lack of marketing success, I mostly expected Launch Week to be just another week. Thankfully, a Hacker News post that I made four days after launch did well, and that led to a reddit post in the /r/programming subreddit.

What was strange to me was the difference in perception between a week before launch and the present. The game hadn’t really changed, but people were playing more, actively participating in Discord, and suggesting it to their friends. I’m still not totally sure what caused that, but Bot Land now feels like a legitimate game to me. Another interesting turning point was seeing people find out about my Twitch stream through the game rather than the other way around.

I’d had tiered goals approaching launch:

  • Goal #1 was my lifelong goal of making a successful video game. I defined success broadly as “a game that more than 50 people want to play”. I believe that goal has been met.
  • Goal #2 was my goal for the last several years, which is to make Bot Land profitable. This is still in progress (there’s a lot of unpaid development time and savings to recoup).
  • Goal #3 is what I’ll strive to do if I can even continue working on Bot Land in 2020: make Bot Land profitable enough for it to fund more than its own development for several years.

As for metrics, here are some quick stats since launch:

  • 23522 total user logins
    • 16440 guest accounts created
      • 744 of these converted to full accounts
    • 6899 full accounts created
  • 54563 games played
  • 31 real-money purchases made

Let’s interpret those a bit:

  • A little over 20k real humans played a game that I made in the last two weeks!
  • None of those guests will probably play the game again.
  • The revenue from those 31 purchases was enough to cover the server costs for a little over a month.

I don’t have an exact number of bugs/suggestions filed since launch, but my email was blowing up, which is perhaps the most important metric—it means that people are invested enough to want to improve the game.

Overall, I think this is a solid foundation for the launch of a game. The money isn’t there yet, and the playerbase is still relatively small, but these things can be grown. The immediate plan is to stabilize the game as much as possible over the next couple of weeks, then get back to adding features and content.

It’s been overwhelming since it feels almost as though these issues stand in the way of “real” changes, but I recognize that they’re necessary and will improve the experience for everyone.

Misc

Technological decisions

Perhaps one of the most difficult parts of making a game is having to make so many decisions. What language do you code it in? How much should Teleport cost? Is it more fun for players if I do X or Y?

I chose to make Bot Land in JavaScript because I wanted players to have as little friction as possible in playing the game. At the time that I started, I don’t think any game engine could reliably produce a web-based build without requiring a browser plug-in. This meant that I needed to make what was essentially a custom game engine for Bot Land, something that I never want to do again due to the number of rendering, performance, and cross-platform issues I hit. Maybe they’d still be present if I’d used a popular game engine, but I imagine that they’d be lessened.

The back-end runs entirely on Amazon Web Services (AWS). I started out knowing nothing about AWS, but now I feel reasonably comfortable with several of their offerings. In the process, I had to learn about related technologies like Ansible, Terraform, and Docker.

Most of the notes that I took over the last several years are public. I’m not an expert on any of the technologies, but you may find some value in them.

Was it worth it?

I always used to wonder whether I was ever giving anything my all in life. With Bot Land, I have no doubts that I did; I poured my heart and soul into the game. There aren’t many things that I’m truly proud of, but Bot Land is one of those things.

Could I have done things faster, better, with less money, etc.? Yes, and if I said that I had done everything 100% correctly, then it would only mean that I hadn’t learned anything.

I’ve gained knowledge, wisdom, and skills. I’ve met great people. I fulfilled a dream of mine. It was beyond worth it.

 

Launch-week catastrophe, the impact, and the recovery

The issue

This is not the kind of launch-week post I’d like to make. I received reports this morning (Friday, September 27th, 2019) that two users were having difficulties logging in. I asked for details. User A was logging in as User B somehow. This is obviously an incredibly severe issue whose bounds I needed to understand immediately.

Background / investigation

On Tuesday, September 24th, Bot Land launched. I had written a script to soft-reset people’s accounts, meaning they could keep their username, email, password, and superficial details, but not their items, in-game progress, etc. I tested this multiple times on PII-sanitized copies of the production database and everything went well.

On Launch Day though, everything did not go well. The script took ~10 times longer than it should have before I assumed that there was an unrecoverable error (I never actually verified whether this was true because I was deploying while live-streaming and I was already frantic to get the game online).

Instead, I rolled the database back about 3 days to when everything was working, reran my scripts, and Bot Land was up and running. Unfortunately for me, a catastrophic issue lurked beneath this rollback.

In Bot Land, users type their username and password and the client sends them over HTTPS to the server. The server salts and hashes your password, verifies it against what’s in the database, then returns an authentication token so that your username and password don’t have to be stored on the client. This token is a JWT, meaning it can be examined by anybody but only changed by someone with the password (i.e. me). The contents of a Bot Land token look roughly like this:

That’s it. It’s just a user ID. Remember though, users can’t tamper with the payload without knowing the secret, so there’s no risk of a user specifying someone else’s ID in here.

User IDs in Bot Land are incrementing integers, meaning they will always be assigned in the order 1, 2, 3, and so on. For a game, it’s fine if you know that user ID #61306 exists; it doesn’t provide any personal information about that user.

So far, everything I’ve described is sound. Sure, you may argue that user IDs should have been UUIDs by default, but there isn’t a major problem yet.

The issue came with the database rollback. Suppose we had 5000 users before the rollback. Imagine a user whose ID is, say, 4993. Let’s say their username is Bob. Bob sets up autologin before the rollback, meaning when they get their token with {id: 4993} in it, they’ll store it locally for use later. After the rollback, an account with the ID 4993 may no longer exist, but Bob’s token representing that account is still in his browser somewhere.

When Bob loads Bot Land after launch, that token will automatically be provided to the server, only now it won’t refer to Bob. Bob has now logged into Carol’s account.

Impact

First of all, in this scenario, Bob would only be able to log in as Carol, a seemingly randomly selected user, but one that is never selected a second time, meaning Bob can’t log in as David afterward.

What information can Bob get about Carol? It’s only the information that Bot Land exposes. Ignoring the game information (like your blueprints, scripts, items, etc.), the only personal information that they’d have access to is Carol’s email address—not her password, payment information (which we never store anyway), or any other identifying information. Furthermore, Bob would only have access to that if he sought it out in the interface, e.g. via the “change email address” function in the game or attempting to verify the email address of the account.

Next, in order for Bob to do this, they needed to have autologin enabled during the 3-day period between the rollback and launch, then they needed to try logging in from the same device/setup during the 3-day period between launch and now. There are 106 accounts that had logins during both time periods, but autologin is a client-side setting, so we can’t tell how many accounts that number is narrowed down to. However, 36 of those were guest accounts, meaning there was no personal information on them whatsoever, so the maximum number of potentially leaked email addresses is 70. Removing spam accounts with obviously fake email addresses (like “asdhjkwhejkwhetkj@ewuitwetyuiw.com”), this brings it down to 59.

Furthermore, while the email address would have to be sent from the server to the client, we can’t know whether the client actually viewed the email address from any of the 59 potentially affected accounts.

Thus, it’s impossible to know exactly who was affected, but again, at most, your email address could have been seen by exactly one user. I will be reaching out to all 59 users with these details and an offer to restore some of their game progress.

Recovery

  • I deleted all 106 potentially affected accounts, including guests and spam accounts, meaning that there is no longer an issue with anyone’s email address leaking.
  • I updated the signing key for all JWTs so that any already-issued tokens will no longer be considered valid. This will require all users to type their credentials again the next time they log in.
  • I will update the signing key again in the future for any rollbacks that have to be done. Since Beta launched on November 7th, 2017, there has been one database reset in late 2018*, then the rollback and soft-reset that we did on Launch Day, September 24th, 2019. Rollbacks are almost always the result of some other catastrophic issue, meaning I can’t foresee future rollbacks, but they could happen.

*This particular reset was not susceptible to the issue described herein because autologin didn’t exist until 3 months later.

Thoughts

Bot Land has a total of two developers. It has automated tests. It has nearly 100k lines of code. We do our best to catch everything, but when something like this is found, I want to be as transparent as possible about what happened and what was done to fix this.

I apologize for the downtime, the lost game progress, and any other repercussions of leaking email addresses.

OS / Editor efficiency

Background

(this particular section is only intended for people who watch my Twitch stream; if this isn’t you, skip to the other sections: general tips, Windows tips, text editor tips)

For a while, I streamed with a camera pointed at my keyboard (here’s a random example video). That got annoying for a few reasons:

  • The actual webcam itself physically obscured part of my monitor, which made it hard for me to see things at the top of my screen.
  • The output of the webcam obscured part of the stream that you would see on Twitch.
  • Every once in a while, the camera would get jostled and need to be readjusted.

I scrapped it and went for Carnac instead. This provided an on-screen display of the shortcuts that I’d press. I had to extend the library to get the positioning/sizing to match my taskbar:

Now, I’m considering switching to Linux (there’ll be a blog post on that eventually!), and I don’t want to have to make a custom version of Screenkey to match my needs. Thus, I took a poll about whether I should keep showing a shortcut display, and at the time of writing, the votes are:

  • I don’t care – 26 votes (44%)
  • Keep the display – 19 votes (32%)
  • Ditch the display – 14 votes (24%)

If I switch to Linux, I’ll be ditching the shortcut display, so that’s why I’m writing this blog post on how I try to be efficient at Windows and Visual Studio Code.

General tips 

The best general tip that I have is to identify where you would gain the most time using shortcuts. To illustrate, here’s a contrived example: suppose you never knew about copy/paste and found yourself frequently duplicating text manually. Learning about copy/paste would likely be by far the biggest time-saver you could incorporate into your workflow.

As the example shows, this process can be broken down into two phases: discovery and incorporation:

  • Discovery: it’s difficult to use something if you don’t know it even exists! I suggest hunting through menus or keybindings files/settings to figure out which commands are even available to you. I’ve found some interesting ones from time to time. For example, in Sublime, you can select a bunch of lines and prune out duplicate values using Edit → Permute Lines → Unique. I wouldn’t have known that I could even do this unless I was searching through menus for it. Some ways to help you with this:
    • Try to analyze where you’re spending most of your time. For example, if you find yourself deleting entire lines multiple times per day, perhaps you could write in a note somewhere “find a hotkey for deleting lines”.
    • Try ditching your mouse for a day (or at least drastically reduce your usage). This will force you to find a keyboard-based solution for what you’re trying to accomplish.
    • Find resources like CheatSheet that list a bunch of shortcuts.
  • Incorporation: now that you know something like Permute Lines exists, you need to actually start using it! For certain shortcuts like commenting code, it will be obvious (“instead of typing  // here, I’ll press the comment shortcut”), but for others, you may need to be more mindful. I find it helpful to write it on my TODO list or a sticky note for a day to try finding a place for a particular shortcut.

As for why any of this is important, it’s simple: context-switching can kill your productivity. The less time you spend going from “what am I doing?” to “how do I do it?”, the less chance you have to lose focus.

Regarding the mouse: it’s not like using your mouse is bad, it’s just probably not the best. For that reason, I’ve always used 10+-button mice. My current one is a Logitech G600 and it has 12 thumb buttons. I did a short video on this specifically for this post.

Windows tips 

Note: I’m writing this for Windows 10. There’s a full list of keyboard shortcuts here.

  • Keyboard shortcuts (“win” means “the Windows key” on your keyboard, and the “→” is used to indicate multiple hotkeys must be used in succession)
    • Win+# (e.g. win+1): navigate to that numbered icon on your taskbar. For example, in this picture of my taskbar from earlier, I have Chrome, then Explorer, then Visual Studio Code in my taskbar. That means that win+1 will activate Chrome, win+2 Explorer, and win+3 VSCode.
      • If you have multiple windows open of the same application, holding the Windows key and pressing the corresponding # multiple times will cycle through the Windows. E.g. win+1, win+1 will get to my second Chrome window.
    • Win+left or win+right: snap the focused window to the side of the screen. You can just keep pressing these to move them to different monitors, but win+shift+left and win+shift+right are better shortcuts for that.
    • Win+up: maximize the current window.
    • Win+T: set the focus to the taskbar. Because I stream, I don’t like using alt+tab since it shows previews of windows even from my second monitor and I’m worried I’ll leak information. Instead, to get to the final icon in the taskbar, I press win+T → end → enter.
    • Win+E: open a new Explorer window.
    • Win+comma or win+semicolon: this brings up the emoji menu, which I use all the time. From there, just type something like “tada” and press enter: 🎉
    • While in most programs with an address bar: alt+D will bring you to your address bar.
    • When in a common file dialog (i.e. the “save” or “open” dialogs like this one), alt+T → alt+N will set the focus to the name/path section. You may think that only alt+N is needed, but if the focus is in the address bar at the top, then alt+N does not work.
    • Anything with a Quick Access Toolbar (i.e. all Office products or Explorer itself):
      • Right-click any shortcut in the ribbon and choose “Add to Quick Access Toolbar”
      • From there, you’ll see an icon appear in the upper left. Just like with win+#, now alt+# will activate that shortcut, where “#” is the index of the icon. For example, in this picture, alt+2 will make a new folder.
    • Text editing shortcuts like ctrl+backspace and ctrl+delete to delete the last/next word all at once.
  • Mouse shortcuts
    • Double-clicking a word in almost any program will select the whole word.
    • A double-click followed by dragging the cursor around will select entire words rather than individual characters (try it now to select a bunch of words in this bullet point!).
    • Triple-clicking text in almost any program will select the entire line.
    • triple-click followed by dragging the cursor around will select entire lines.
  • Console tips
    • In CMD, Doskey can be used for aliases, but I had some issue with it years ago that caused me never to look into it again. Instead, I just make .cmd  files in my %userprofile%  and run those. For example, I like the alias s  for opening my text editor, so I make %userprofile%\s.cmd  with these contents:
      • After that, I can type something like s new_file.js to make a file in VSC.
    • ConEmu is a great tabbed console emulator that lets you assign a global shortcut to your terminal. I use the shortcut so that I can access my console from anywhere in the operating system.
  • AutoHotkey
    • AutoHotkey lets you trigger commands either by typing arbitrary text (e.g. I can type  `vsc  and it will turn into  Visual Studio Code) or by pressing a keyboard shortcut. I uploaded my own AHK scripts here for reference. You can use this to fix typos that you make frequently, position windows in a particular way, format text, or really anything else that you would do yourself with a mouse and keyboard.

Text editor shortcuts 

Notes:

  • I don’t use VIM keybindings.
  • I’m not listing the actual keypresses needed to activate these since they’re not necessarily specific to a particular editor. Even if they were, I customize my shortcuts so that they’re not the defaults. To find out what these are for you, you should be able to search through your text editor’s list of shortcuts.
  • am going to list the name of the shortcut in parentheses that Visual Studio Code assigns, that way if it’s not obvious what my description refers to, you can at least try it out in VSC! Some of these may come from an extension, in which case the shortcut is a link to the extension.
  • I’m not going to include “obvious” ones like “copy and paste”, “go to the next tab”, or “comment code”.
  • I wrote blog posts about specific extensions and shortcuts for Sublime here and Visual Studio Code here.
  • Here’s a video from 2015 of me using many of these shortcuts and some extra features in Sublime.

Most used functions:

  • Multiple cursor management: these are all supremely useful for so many scenarios while developing that it’s hard to give a single example. Essentially, any time you find yourself wanting to use the find/replace dialogs, possibly with complex regex, you can probably do whatever you’re trying to do more easily with multiple cursors.
    • Select next instance of word (editor.action.addSelectionToNextFindMatch)
    • Ignore current instance of word (editor.action.moveSelectionToNextFindMatch)
    • Select all instances of word (editor.action.selectHighlights)
    • Extend line up or down (editor.action.insertCursorAbove)
  • Duplicate selection or entire line (lafe.duplicateCode)
  • Move entire lines up or down (editor.action.moveLinesUpAction): this is great for moving code into and out of block statements or just rearranging your code.
  • Quickly open a file (workbench.action.quickOpen)
  • Quickly navigate to a function (workbench.action.gotoSymbol)
  • Soft undo (cursorUndo): suppose you’re trying to use multiple cursors to select the next three instances of the word “hello”, but you accidentally select the next four instances. Some people would press escape and then try again, but with soft undo, you can simply undo the last cursor.
  • Close all windows to the right (workbench.action.closeEditorsToTheRight): useful when you have lots of temporary buffers open. I frequently find myself also using this in combination with the Windows shortcut alt+N for choosing “Don‘t save” when the dialog pops up.
  • Toggle words (extension.toggle): as mentioned in both the Sublime and VSCode blog posts, this is the best extension that you never realized you wanted. It can convert  true to  false ,  ==  to  !=, and whatever other pairs you may want (width/height, up/down, Monday/Tuesday/Wednesday/etc.).

Closing

I shared what I thought may be important, but you may have come into this post expecting something else. I’d love to hear how I can make this post better! Feel free to share feedback with me on Discord.

Visual Studio Code

Introduction

I imagine most people will find this from my stream with a particular section already in mind, in which case use the links below. If you didn’t come from the stream, I’d love to have you there! I code for 8 hours on most weekdays on a game called Bot Land. You should try it! 😉

Quick links to parts of this post:

Switching from Sublime 

I switched from Sublime to Visual Studio Code (VSC) on September 12th, 2018. I’d been using Sublime for about eight years. I was efficient and [mostly] happy with it. Those are the two qualities that you should want out of any editor in my opinion, so I’m not here to convince you to switch if you’re comfortable with what you’re using. My personal reasons for switching are:

  • VSC is more actively maintained than Sublime.
  • VSC is open source. At the very least, this means that if there are any core problems with the program, I could modify it myself instead of having to wait for another person to do it.
  • VSC is completely free, i.e. not even nagware. I’d already purchased Sublime a long time ago, so the reason this matters to me is not actually due to the price itself, but because I like being able to suggest my toolset to other people, and a free tool is much easier to convince someone to use than a [potentially] paid tool.
  • VSC seems to be more customizable than Sublime.
  • VSC does more out of the box than Sublime (e.g. Git integration, formatting code).

The catalyst for the switch was my frustration with specific plug-ins for Sublime. For example, a long time ago, the syntax highlighter I used was broken in such a way that a file containing a specific set of characters would crash all of Sublime. More recently, my ESLint plug-in wasn’t aware of nested configurations, so it was reporting almost every file as being erroneous. These sorts of problems really cut into development time.

Switching to VSC was no easy task. Using an editor for eight years, you start to get used to seemingly inconsequential quirks. The total transition time for me was somewhere between 10 and 20 hours, and there are still things that I haven’t customized to my liking yet.

My blog post on Sublime still resides here.

My OneNote notes on VSC are here (to see when these were last updated, go one directory up and look at the listing).

Extensions that I use 

This list only contains extensions that I felt were general enough to recommend. For example, I use this extension for AutoHotkey language support, but it’s kind of obvious that you’d want something like that if you find yourself modifying AHK files, so I’ll omit those from the list.

Each extension name is a link to its official page.

My favorite extensions 

Toggler

This is the holy grail of extensions that you don’t even realize you need until you try it. You specify arrays of transformations, and with a keyboard shortcut, you can switch between them. Common examples include converting true  to false  or !=  to  == . It maintains case (e.g.  True  → False , TRUE → FALSE) and works on multiple selections.

You can even cycle between multiple values. For example, I update the !today  command in my stream every day, so I use Toggler to change “Monday” to “Tuesday”, “Tuesday” to “Wednesday”, etc.

VSCode Eval

This evaluates JavaScript expressions. Most commonly, I find myself using this for mathematical operations. For example, suppose you have this code:

…and suppose you want to multiply each value by 15. I would make multiple cursors, add in * 15 , then run VSCode Eval on the selections, resulting in:

Since it’s just evaluating JavaScript expressions, you can do things like:

  • Generate a repeated string: '*'.repeat(80)
  • Use any Math.*  functions:  cos(PI * 2)

TODO+

This lets you write/manage a TODO list directly in VSC:

I use this all the time for notes about whatever task I’m working on. These notes almost always convert into Git commits, as opposed to, say, code documentation (which doesn’t belong in a TODO list).

I ran into a performance issue with the extension that was solved by modifying this setting: "todo.statistics.project.enabled": "false"

I also had to tweak the colors a bit (see the overview here), e.g. "todo.colors.done": "#75715e"

Code Ace Jumper

This is like EasyMotion for Sublime (or VIM). You invoke Ace Jumper and type a single character, and all instances of that character will be annotated with another character that lets you quickly navigate to exactly the one that you want.

If you’re primarily a keyboard user and find yourself wanting to jump to arbitrary characters on the screen, then this is the extension for you.

Useful extensions 

  • Bracket Pair Colorizer: if you’re lost in a sea of parentheses, braces, and brackets, this can help you reorient yourself. It assigns a color to each pair of opening/closing characters.
  • indent-rainbow: similar to Bracket Pair Colorizer, this is great if you’re confused about what indentation level you’re at; it will highlight the indentation levels with different colors.
  • GitHub Pull Requests: this lets you view pull requests from GitHub directly in VSC. At the time of writing (9/22/18), there are many actions that redirect you to GitHub, but it’s still helpful.
  • GitLens: to be honest, I’m not totally sure what this adds over vanilla VSC because I only ever tried VSC with this installed, but everyone seems to love this extension. I definitely do use the File History Explorer for showing the changes to a single file.
  • Multiple cursor case preserve: you have a line of code like  int someWidth = width;  and you want to change “width” to “height” in both instances using multiple cursors. With this extension, you don’t have to worry about their casing. However, keep in mind that this particular example is better solved by Toggler since you wouldn’t even have to type “height” at all!
  • One Dark Pro: the color theme I use is Atom One Dark Vivid.
  • Rewrap: wraps comments to a given line length. This is nice if you use a ruler like I do to keep your lines to X characters long (this is controlled by the editor.rulers  array in your settings).
  • Settings Sync: this lets you upload/download all of your settings, extensions, keyboard shortcuts, etc. all at once via GitHub gists.

Extensions I installed for Sublime parity 

These are extensions that provided functionality that I was used to in Sublime. If you’ve never used Sublime, I’d still recommend Bookmarks and expand-region.

  • Bookmarks: add a bookmark to different points of interest in a file so that you can quickly jump to them.
  • Center Editor Window: centers the editor window on the cursor.
  • Contextual Duplicate: duplicates the entire line if nothing is selected, otherwise duplicates the selected text.
  • Dumb copy-paste: ctrl+shift+V from Sublime, i.e. pastes code with whatever the source indentation was.
  • expand-region: ctrl+shift+space (“expand_selection”) from Sublime – expands the selection outward in scope.
  • Incremental Search: almost like ctrl+I from Sublime, except not exactly… I want the search term to go into the ctrl+F buffer so that I can use “Find Next” with my incremental search. I haven’t found an extension to replicate the behavior exactly yet.
  • Transformer: sort or reverse lines, or make the selected lines unique.
  • transpose: ctrl+T from Sublime – transposes characters around the cursor, e.g. converting “tihs” → “this”. I would also like to transpose words, but I haven’t found an extension for that.

Settings 

Here’s a dump of most of my settings from October 2nd, 2019. I think that most settings are so opinionated that it isn’t worth highlighting any or explaining how to set them; there are enough resources for that sort of thing online already.

I don’t plan on keeping that list updated. This entire section is only here because people have already specifically asked for it.

Conclusion 

I touched on this earlier: the straw that broke the camel’s back with Sublime was the ESLint plug-in that I was using, but I wasn’t exactly unhappy with Sublime to begin with. So while I’m moderately happy with VSC after two weeks of using it, I feel like the real value is going to be difficult to discern—there are issues that I would have had with Sublime if I’d kept using it, but I’ll never know what those are since I’ve made the switch already.

With that said, I have several gripes with VSC:

  • After hours of researching, I still have no idea how to smoothly use Git on Windows without having to type my password every time. I concocted such a ridiculous solution (read “Git setup”) that it annoys me just thinking about it.
  • The sidebar and panel desperately need an autoclose option. VTools had two quirks (that aren’t worth going into) that prevented it from being a viable option for me.
  • I’m missing minor functionality from several plug-ins: transposing words, highlighting TODO+ in exactly the way that PlainTasks did, diffing arbitrary text, etc.

Microsoft seems to release frequent updates to VSC, so I’m hopeful that the positives outweigh the negatives in the long run.

Growing pains 2

Sorry, no quick TL;DR for this post, but you can read just the first and last sections (background/conclusions) to get the best summary.

Background

This blog post and the first one in the series were the only two posts that I’ve disliked writing. It just sounds so self-entitled to write a post that’s seemingly about “having too many viewers”. However, I’ve always wanted to be as transparent as possible, and to that end, informing people about potential changes is crucial.

I’ve always loved interacting with chat. It’s something that separates the entire platform of live-streaming from watching prerecorded videos. However, as time has passed, I’ve gotten more and more comments saying, “when are you going to code?” and “it seems like you’re always talking to chat when I come in here”. I’ve noticed a steady decline in the pace at which I get features done, and my first and foremost goal of the stream has always been accountability. I tend to say that there’s exactly one way I can fail, and that’s to not finish Bot Land.

I think that coding and interactivity are generally at odds with one another. This comic illustrates exactly why. There are certain areas where it’s easier for me to split my attention, e.g. pure CSS work. Anything more mentally taxing than that and I’m just giving off the appearance of multi-tasking. At that point, my goal of remaining accountable is being compromised.

Potential solutions

There are really only two high-level ways to address this issue:

  • Stream less
  • Interact less

Streaming less is straightforward: I would change my schedule from 32 hours a week down to something like 24. I would then spend the 8 hours that I “gain” with my nose to the grindstone.

Interacting less is a trickier beast. As I mentioned earlier, interaction is core to the platform, not just my channel. I’ll talk about several potential high-level solutions and how I feel about them:

  • Sub-only mode (i.e. you have to spend $5/month just to be able to chat at all): this is incredibly restrictive and too “sellout-y” for me to seriously consider.
  • Follower-only mode (i.e. you have to click the follow button to be able to chat): this seems agreeable enough to myself and to viewers, but I don’t think it actually addresses the issue since I doubt it would cut down on messages; I only average about 20-25 new followers for an 8-hour stream, and I don’t know how many of those people type anything at all.
  • Slow mode (i.e. people can only send messages every X seconds as opposed to having no delay): again, this is probably agreeable enough (although I imagine less so than follower-only mode), but it could lead to longer messages that require the same amount of interaction.
  • Only respond to messages where people tag me (i.e. you have to type “Adam” somewhere in your message to get my attention): I think it’s worth giving this a shot. When chat gets busy on a “regular” day, this is what I tend to do anyway.
  • Respond to fewer messages arbitrarily (i.e. scanning chat and ignoring messages (perhaps the ones that someone else could answer with a command like “!faq”)): I think this dampens the overall mood/feeling of the stream. Almost every streamer with 1k+ viewers employs this strategy; they’ll pick out some messages from chat to respond to and pass over most of the others. You’ll probably never see a streamer with 1k+ viewers meaningfully interacting with absolutely everyone who comes through. Of course, I don’t have 1k viewers, but I’m also trying to develop a game while I stream.
  • Only respond to messages at certain times (i.e. something like the Pomodoro Technique where I would code for 25 minutes and then interact for some time): I feel like this would require a lot of work to get right. For example, I’d need a way of filtering messages such that I don’t have to read through 25 minutes’ worth of chat all at once, and it would still end with me missing something. As a viewer of other people’s streams, I can’t stand when they’re not interacting at all, so I think this isn’t a viable option.
  • Combined with any of the above, I could try to foster more self-sufficiency in chat, e.g. by having regular users answer questions for newcomers.

Impact and other thoughts

Something to keep in mind is that almost any solution is going to stunt the growth of the channel. If I’m cutting down on the amount of time I’m streaming, then I’m hurting my discoverability. If I’m cutting down on interactivity, then I’m hurting part of what makes the stream fun. These could make it so that the original issue simply disappears. While this would be a good thing for the development aspect of the stream, it detracts from the second major goal I have: marketing. I need people to know that Bot Land exists!

Related to that: the increased traffic could be a temporary uptick caused by any number of variables outside of my control: exam schedules, external sites directing more traffic to Twitch, etc. Regardless of how it happens, if my stream ends up with only 1-2 viewers at some point, I think this thought process is still helpful to publicize.

Another thing to consider is that some of these solutions only push off the problem until even more people join. I can’t stress enough that I’m not trying to assume that my channel will grow to 300+ viewers or that I’m Mr. Popular. Instead, I’m just trying to come up with more permanent solutions so that the next 8-9 months of development can go smoothly and I can launch the game in as good a state as it can be.

I think that there’s clearly a desire for “IRL Programming” streams from me where I focus almost entirely on chat interaction. The Visual Studio Code stream was great for that: I had a vague and unimportant goal (trying out a text editor), and I could prioritize interacting with chat. They would probably need to be standalone streams so that I could advertise them as such (a “free-for-all” stream for chat, so to speak), so I can’t promise that they’ll happen with regularity.

I do know what it’s like to be in a channel where 50 people are all shouting the same thing at a streamer. It’s a frustrating occurrence from the perspective of the viewer, but it got to be that way for a reason. For all we know, the streamers in those cases went through the same thought process that I did here and gradually came to the conclusion that they couldn’t interact with chat without sacrificing some other goal (which is usually to be entertaining!). It’s impossible to please everybody, and the dog who chases two rabbits catches neither. This dog wants to finish Bot Land and make a great game for you all to enjoy.

Conclusions

Unfortunately, I don’t have a single strategy going forward. I’m likely going to try different things: maybe taking off one day per week to code, maybe testing other ideas out… The whole reason I wrote this blog post is to let you all know that there are going to be changes to the stream even though I don’t know exactly what they’re going to be just yet.

Here are some things you can do as a returning viewer to help me out:

  • Help on-board new viewers by answering their questions. If they say “what’s Adam working on?”, feel free to type “!new”, “!botland”, or “!faq” (and don’t forget to @-tag them!). It’s nice to feel welcome as a new viewer, so even just saying “hi” to them is great!
  • Provide feedback to me over a Discord private message on absolutely anything: the stream/game, this post, the water bottle I drink from, etc. I read every PM, and by sending it over Discord, you’re cutting out the need for me to handle it immediately.
  • Be understanding with me. Transitional periods are rarely easy for everyone involved. I still want to provide entertaining and educational content, but I need to lower my overall stress level in order to do that.

I’m grateful for the support that you’ve all shown to me time and again while making Bot Land… I am living my dream right now and I am incredibly lucky to be doing so. I don’t want to take this opportunity for granted. Thank you for reading this and I hope we can find a happy equilibrium going forward.

 

Organizing your notes with OneNote

Background

I stream development on Twitch, which means people see almost everything I do on a computer for about 8 hours a day. I’ve gotten so many comments/questions about how I keep my notes organized that I wanted to share the tips that I’ve learned over the years.

As for why you should care about any of this: my philosophy is that taking notes allows you to apply your mental resources to more important areas. By writing notes, you will also solidify the concept in your brain (sometimes you’ll even clarify misunderstandings while writing them!). By organizing notes well, you’ll have this knowledge accessible to you and anyone you share them with for years to come.

This post does not focus on picking which note-taking software to use. I chose OneNote because it’s free, it syncs via the cloud, and it’s available on every platform I use. Those requirements may not be important for you; if you’ve already got another piece of software in mind, then skip the Specific tips section.

General tips

These tips apply to any software, not just OneNote.

Do as much or as little as you can

You likely don’t have a need to take notes for everything. I used to track my workouts in my notes (how far I ran, how long it would take, how much I lifted, etc.), but I never ended up using those notes for anything. I’ve since stopped taking them and I haven’t looked back.

In my opinion, the two properties that make for the best note-writing candidates are:

  • Knowledge that will probably never change (e.g. recipes, how to conjugate French verbs)
  • Knowledge that you may take you a while to re-learn (e.g. how to set up a virtual machine)

Specific categories or notes

Some people ask me for how I organize categories of notes (presumably so that they can get some ideas for starting out). OneNote has notebookscategories, and notes, but the concept of hierarchies isn’t specific to OneNote, which is why this is in the General section of this post. Here is a list of highlights from my hierarchy:

  • [Notebook] Personal – these are things that will likely never be shared with anyone
    • [Category] TODO
      • [Note] TODO: things I have to do in my life
      • [Note] ToBuy: products that I may be interested in buying at some point
  • [Notebook] Knowledge – these are sets of notes that I may eventually share with other people
    • [Category] Coding – notes about a specific programming language
      • [Note] Python
      • [Note] JavaScript
    • [Category] Programs – notes about specific programs that are downloaded
      • [Note] Sublime
      • [Note] FLStudio
    • [Category] Websites – notes about specific software/sites which aren’t downloaded
      • [Note] GitHub
      • [Note] CodeSandbox
    • [Cateogry] French
  • [Notebook] Work – work-specific notes, e.g. TODO, long-term TODO, meeting notes, etc. I suggest making one for each job that you have.
  • [Notebook] Private – this is password-protected and contains only sensitive information.
    • [Note] Health – I keep track of my health history. When you’re changing doctors or you’re at urgent care and have to remember when you had a certain surgery or what a particular doctor recommended, this is really useful.
    • [Note] Employment history – I track dates of employment, bosses’ names, company addresses, etc. This massively saves time when applying somewhere or filling out government forms.
    • [Note] Residential history – just like above, sometimes you’ll fill out a government form that asks where you’ve lived for the last 7 years, so I recommend tracking addresses, dates of move-in and move-out, and contact information.
    • [Note] Life – We gain so much wisdom throughout our lives that we end up forgetting. I keep track of things I’ve learned here like solving interpersonal problems, handling feedback (both giving and taking), dealing with anger, preventing myself from getting back pain, etc.

My biggest suggestions from the large list above: make at least a Knowledge notebook, and try to make the same four private notes that I did when you find yourself needing them.

Organizing a new note

Originally, I used to just produce a gigantic bulleted list of notes. I found that this was not consumable, which means I essentially wasted time organizing my thoughts that way. I’ve since switched to using headers, sub-headers, etc. If I’m ever writing about something technical like coding or using a program, I’ll almost always end up with a header at the bottom called “Troubleshooting” where I put all of the errors I’ve ever encountered and how I fixed them.

Next to the headers, I’ll try to include links to references where I originally found the information. Here’s an example:

By doing this, if I’m confused later when I go to read the note, I’ll have more material that I can look through.

Searching

Once you have a lot of notes, searching is going to be important. Always put something where you expect it to be. That tip comes from real-life cleaning; if you’re looking for your Bluetooth speaker and you don’t find it in the first drawer that you search, then once you do find it, you should put it back in that drawer since that’s where you’re going to search for it next time.

Applying this to digital searching means that you should add keywords when you can’t find something at first. For example, I have a note about which filters we have to order for our fridge. I may search for “fridge” in my notes and not find it because it’s listed under “refrigerator parts”. When I finally find that note, I should just put “(keywords: fridge)” next to it.

One last thing: suppose you didn’t find the note because you never wrote it – you should add it! If you looked for it once, then you’re probably going to look for it again.

Specific tips

These tips apply specifically to OneNote. All of them are built-in (at least on Windows) and require no extra configuration.

Version history

By right-clicking a note and choosing “Show Page Versions”, you can see the history of a particular note:

This lets you recover what a note used to say, e.g. if you want to see what was on your grocery list 4 weeks ago or you accidentally deleted part of a note from your phone.

Linking between notes

I write a lot of technical notes, and I find myself wanting to refer between them. For example, I have a note about the website GitHub and a note on the technology Git, so of course there’s some overlap. To form a link to a particular section of a note, right-click a line and choose Copy Link to Paragraph:

After that, just paste the link in another note. The only thing to be careful of is that these links won’t work when you export to a PDF, so if you share these notes with someone else, then you may need to send them multiple PDFs.

Find time/date of a particular line in your notes

You can right-click any line in your notes to see when it is you wrote that note. For example, I’ve apparently wanted to write this blog post for the last two months:

This is most helpful when I reread a note and say “wait, that’s not right…” Sometimes I learn new information that invalidates a note, but I wouldn’t know if I’d had that information at the time of writing without this feature.

Fuzzy searching

Searching for a word without quotation marks will actually search for multiple forms/tenses of that word. E.g. a search for making will find hits like “make”, “makes”, and “made”. If you don’t want this functionality, you can wrap your search terms in quotation marks.

Conclusion

I’ve been “serious” about writing digital notes for about 7 years now, so I hope you can cut out the first few years of ramp-up time after reading this post. Again, I highly suggest OneNote for getting started, but find whatever software/methods work for you.

Being a development streamer on Twitch

This blog post is a compilation of advice/tips on how to get started as a development streamer on Twitch. There are probably plenty of resources out there that cover this same sort of content for gaming streamers, so this will largely focus on development-specific topics.

Some quick background information about myself: I’ve been streaming the development of my game, Bot Land, on Twitch for about 1600 hours now. I started with essentially no Internet presence. My channel is by no means big, but I think it’s doing well for being in the Creative section on Twitch. You can track its growth here.

Why stream your development at all?

First, you should ask yourself, “what do I hope to get out of streaming?” Do you want to make a living off of it? Do you just want people to keep you company?

My two biggest reasons for streaming are:

  • Accountability: I find that when I’m coding completely on my own that I tend to wind up on Facebook, reddit, or Hearthstone somehow. Streaming forces me to avoid this. It also highly encourages me to start working at the same time every day.
  • Marketing: Bot Land can’t be successful without players. A major reason for streaming my development time was to build an audience for the game. I see this as the biggest difference between development streams and gaming streams: I’m making a product that I later need to sell.

You should be able to answer why you want to stream, that way you can steer yourself in the right direction. With that said, the most significant benefit I think you’ll get out of streaming is that a community will start to form around you and your product. Marketing aside, this confers many smaller benefits:

  • You won’t feel as lonely even if you’re developing the project by yourself. I once worked for 3 months on a project where I was the only developer, and the lack of regular social contact throughout the work day started to drive me insane (seriously).
  • People will offer to help with tasks that you would typically have to spend money on. For me, people offered to help code chat bots, make a web site, or even consult with me on technical issues.
  • Similar to the above, you’re networking without any extra effort. In the case of building a game, maybe someone in the stream knows an artist or musician to help fill out your team.
  • You can enter the feedback loop on what you’re developing much sooner than if you weren’t streaming. For example, if you’re making a game, you can have your viewers test it out without having to do a huge marketing push. To help smooth out this process, look into a public bug/issue tracker so that you don’t have to keep telling everyone “oh yeah, I already know about that bug”.
  • There’s another metric for progress. Instead of working on features and bugs, you’re also watching your viewership increase.

Your stream setup

As I mentioned in the intro, I want to cover topics specific to development, so I’m going to skip over advice on broadcasting software, computer specs, which microphone to buy, etc. However, keep in mind that a big reason people watch live streams as opposed to recorded videos is interactivity. Most people don’t want to actively watch someone code for 8 hours. To improve “watchability”, I highly suggest buying a microphone and a camera so that you can take advantage of the interactivity. Viewers want to know who’s behind the keyboard, and at the very least you’ll be able to respond to them faster if you have a microphone.

Keep in mind where the boundaries of your webcam are to your viewers. When playing games, there’s usually some unimportant part of the screen that you can cover up, but most developers tend to use their whole screen for typing code. If you don’t want to scroll code or move windows around all of the time, you could look into auto-hiding your video when your mouse/cursor gets close to it.

There are tons of streaming sites out there. I chose Twitch because I was most familiar with its culture. It’s possible to stream to multiple at once by using a service like Restream. I haven’t used this, so I can’t give much advice from a streamer’s perspective. From a viewer’s perspective, it’s annoying to me when it’s not obvious that a streamer is using this service. For example, if I’m sitting in a chatroom and I hear the streamer say “yeah, but only on Thursdays.”, I’ll be confused. I’ll scroll up in chat to see if I missed something. Then it turns out that they’re responding to someone from YouTube Gaming despite that I’m watching from Twitch. If you stream to multiple sites, consider showing chat on-screen. Still, I would say that at some point, consider picking one site and sticking with it so that your viewers have a cohesive experience.

Even if you’re not streaming to multiple sites, it’s helpful to respond in complete sentences. If someone types out “do you like lemonade?”, respond with “Yes, I like lemonade” instead of just “yes”. I know this sounds nit-picky, but it takes so little extra effort and helps to reduce confusion due to the stream delay (which can be up to 30 seconds sometimes on Twitch). Viewers will typically not do this, so try not to ask too many yes-or-no questions in a row.

I won’t comment on whether you should play music, but if you do, make sure that it’s not drowning out your voice.

Also, make sure your font size is legible. Not everyone is on the stream for the coding part, but the ones who are will want to be able to read what you’ve written.

Know your audience

In general, I think that you can sum up why viewers watch any stream with these two factors:

  • Personality: you’re entertaining, humorous, etc.
  • Competence: you’re really good at what you do.

There’s one other reason that’s specific to development: what you’re making is interesting. Once you have some viewers, try to find out why they’re watching you (you can even just ask them directly). Here are some reasons that I’ve heard for why people watch my stream:

  • They like to have a voice on in the background while they do their own work.
  • They like that I interact with chat.
  • They think Bot Land will be cool.
  • They say I have good keyboard skills.
  • They want to learn how to be a programmer or game developer.

Try to capitalize on these if you can. For example, enough people commented about my typing that I ended up pointing a camera directly at my keyboard and now I broadcast that too.

About personality: some people put on a persona when they stream. Based on what I’ve seen, I assume this is more popular with gaming streams rather than development streams. Either way, know your audience and find out whether it’s resonating with them.

About competence: I highly suggest honing your development skills off-stream. I find that streamers lose credibility if they are just hacking together their application with no technical direction. You should at least be able to explain in general why you’re doing something and what it means since your viewers will likely ask about it. You should also look into learning design patterns and tools (e.g. IDEs, debuggers, libraries, test frameworks) and figure out what would help you the most.

Another means of developing competence is to improve your execution. Learn how to type properly. Learn hotkeys for whichever commands you use most frequently. These improvements will affect all of your computer usage too, not just development, so it’s worth investing in. This lets you focus on the development aspect of your stream rather than the minutiae.

Most game development streamers try to make their streams as fun as possible. Some have games that can be played directly in the broadcast or in chat. Some have cool transition scenes when someone follows, subscribes, or cheers. I have a silly thing where people can control the lights in my room when they follow. I think that these sorts of things are hooks. They’ll get viewers to say “oh, that’s cool!” but you need the personality or competence to get them to stay.

Try to favor interactivity when possible. I’ve found that I get more followers if I take the ~1-2 minutes to explain what my game is about rather than linking to a canned YouTube video. This isn’t sustainable though; I can’t spend an hour every day introducing my game. At some point, you need to get back to work!

On favoring interactivity, I think that you should generally follow this quote: “never underestimate your ability to brighten someone’s day.” If someone does something nice for you, take some time to appreciate them, even if it’s just a “thank you”. Involve people as much as possible. Get a chat bot, add quotes from funny people, do events with your viewers, run giveaways, Skype with them, whatever you think you can handle to grow your community.

One more note about interactivity: it’s generally expected that you’re saying something throughout most of your broadcast. Development is a mindful activity, so you probably can’t talk about an unrelated topic while coding, but try to explain what’s going on with your code or why you’re approaching it a certain way.

Branching out into playing games will likely tank your viewer count for the time that you’re playing that game. This happens even with top-tier streamers that I’ve seen; I’ve watched people go from 22k concurrent viewers playing Hearthstone to 4k viewers when they play Duelyst within the same stream. Some part of your audience is watching you for you, but most of them are watching you for the combination of you and your activity (i.e. developing). If you plan on playing games anyway, then either don’t worry about your view count or follow the same general guidelines written here (be consistent, be entertaining, be competent).

Drawbacks of streaming

I’m not trying to convince you to avoid streaming, but you should be aware of what makes it difficult:

  • Development is already mentally taxing enough as it is. You need to be “on” for most of the day when you’re streaming. This can be hard for some people to do, especially when you’re usually talking to just a few viewers (i.e. you still need to form a habit of talking even when no one’s talking to you!). What’s more is that we can have a tendency to spiral into negativity when code doesn’t work for long enough. In my experience, this kind of negativity is not enjoyable to watch. Instead, it’s fun to watch a developer work through a problem while being positive about routes that they can pursue.
  • It’s easy to leak information. I’ve accidentally shown passwords, IP addresses, email address, etc. on-stream even though I have two monitors.
  • It’s another thing to maintain. You’ll end up putting many hours into finding moderation tools, chat bots, adding commands, building FAQs, emailing your community, finding art/overlays, chatting, etc. This is why I said it’s important to state your goals with streaming. One of my goals is marketing, and having a good stream will keep people coming back.
  • You’re displaying your code to the world. Let’s say you write a bug into some server code that you showed while streaming. If your application ever gets popular, people can weed through the videos to find potential exploits without telling you about them.
    • Your code is copyrighted when you write it, but that doesn’t matter to some people. For example, there are plenty of knock-off games in the various app stores that haven’t been shut down yet. Or maybe someone else takes your idea and beats you to market with it. Are you going to spend the time and money to legally pursue them?
    • The flip-side of this is that you may have copy/pasted code from the Internet or incorporated a library that you don’t have the license to use.
  • You’re interacting with the Internet. Sure, most people are going to be fine, but sometimes you’ll get a troll. That’s manageable. Rarely though, you’ll get a very persistent troll. It’s difficult to deal with them while still:
    • Keeping your cool
    • Keeping chat informed
    • Not giving attention to the troll

Other tips

These didn’t really fit into other sections, so here’s a mishmash of tips!

Watch your own broadcasts. I see streamers say “uh”, “um”, “basically”, etc. too much. Off-the-cuff speaking for many hours while programming is never going to be flawless, but try to eradicate as many filler words as possible from your speech.

Try to abide by a schedule, that way people can work you into their routine. I watch Twitch while eating lunch and sometimes while falling asleep, and it’s great when my favorite streamers are online for that time!

Don’t burn yourself out. I think consistency is more important than short bursts of progress. Don’t stream for several hours a day unless you know you can handle it.

I find it frustrating when I enter a stream and the streamer isn’t even present. Did they step out to get water? Are they heating up food? For this reason, I almost always put up a “BRB” screen with an estimated time of when I’ll be back. This means that every time I use the bathroom, take a snack break, or go to lunch that viewers are in the know.

On Twitch, you can apply to become a partner when your channel is big enough. At the time of writing this, Twitch has not updated their requirements specifically for Creative streamers, so it still appears as though you need 500+ concurrent viewers before they’ll accept you (which is next to impossible for 99% of the development streamers on Twitch). However, their guidelines are much more lax for development streamers. Once you have at least 25+ concurrent viewers, it wouldn’t hurt to apply. I’ve only been a partner for about two weeks, so I can’t comment too much on how exactly it will help your stream’s numbers, but it’s an official way of monetizing your channel.

Conclusion

Unless you’ve already released a playable game or you’re a famous developer, then it will be a slow climb to get viewers. Twitch is still a platform primarily associated with playing games. Keep at it though, and you’ll get there!

Redesigning Bot Land

My last post on this blog was nearly a year ago; I instead put my time toward recap videos. Now that Bot Land has been in development for a little over a year, I want to consolidate some the history behind its design!

The original design

Bot Land has always been an online strategy game with a focus on automation. However, our initial plan was for it to be a realtime player-vs-player game. This video sums up the gameplay. You make bots, write scripts, then throw them into the Arena to battle—sounds great! There was a big problem though: the strategy aspect was lacking.

When talking about strategy games, it’s important to be able to describe a player’s decision tree. A decision tree is formed around the rules of the game (“what can I do?”) combined with how you think about the state of the game (“what should I do?”).

In the original design of Bot Land, your main action consisted of choosing which bot you want to deploy. This was really two “sub-actions”:

  • Choosing which hardware your bot has (e.g. Missiles and Cloaking)
  • Choosing which script your bot has (e.g. only move while cloaked)

Bot hardware roughly follows a rock-paper-scissors model: Reflect will beat Missiles, but it will lose to Melee. The problem we faced with choosing a bot was that this wasn’t a meaningful decision. You couldn’t control where your bots were deployed, and the bots themselves didn’t have any knowledge of an enemy’s hardware. This meant that you may want to deploy a Reflect bot to counter the enemy’s Missiles bot, but you couldn’t guarantee that the two would meet up in the Arena.

For a minute, let’s consider a world where you could guarantee that your Rock bots encountered the enemy’s Scissors bots. The problem is that it’s not a difficult decision to make. Games like Starcraft that feature rock-paper-scissors mechanics aren’t as straightforward because it involves a lot of speed and dexterity to be able to pull off a particular strategy. In Bot Land, after you deploy your bot, your script takes over for you.

Without meaningful decisions to make in a game, there won’t be a high skill ceiling. That means that “pro” players won’t be much better than new players. This undermines a strategy game in my opinion. More importantly, playtesting of Bot Land was confirming our suspicions that the game wouldn’t be fun if we stuck with this design. This meant we had to revamp the decisions that a player could make.

Flux

I published this video at the end of July. It covers the section you just read above, but it also talks about how we planned on pivoting our game design. In short, we wanted to expand the player’s decision tree. Over the course of August, we tested concepts like:

  • Being able to choose a bot’s spawn location
  • Being able to control bots that were already deployed (via waypoints)
  • Building factories which would lock you in to a particular hardware loadout
  • Creating hero bots which could be teleported at will
  • Spawning scrap piles on the map to give players points of interest to contest
  • Having territory for players to generate money
  • Upgrading bots

In the end, we determined that the game still wasn’t very strategic. What’s more is that it was hard to tell if we were even closer to a solution. Maybe another week of prototyping would get us there, or maybe we were pursuing something that was impossible. I was the most stressed-out that I think I’ve ever been in my life. I was beginning to think that Bot Land was unraveling and that I wouldn’t even finish the project.

Right around this time is when Ian, the game designer, stepped down due to time constraints. He left the company on amicable terms.

I started to question all of our original assumptions about the game. I created a document while streaming and started brainstorming (it’s now 70 pages and largely unreadable, but feel free to check it out). Here are the most important conclusions:

  • If you’re expected to change scripts in a game, then the game shouldn’t be in realtime. There are two reasons for this:
    • It’s neither easy nor fun for most people to code quickly. It’s especially unfun on a mobile device.
    • A big problem with being expected to make major changes to automation while it’s running is that it means that the automation needs to run slowly enough for you to be able to identify where you need to make a change, but it needs to run quickly enough for you to know whether your change had any impact.
  • If you can’t immediately tell exactly how something is going to play out in an automation game, then the game should give you multiple attempts at winning. The reason software has bugs is because people make mistakes. I think it’s okay to punish certain mistakes in games, but I think it would be frustrating to lose in Bot Land just because you couldn’t accurately predict how several medium-sized programs would play out.

New design

I started the last two sections with videos, so here’s another one that covers the last section and some new stuff (hey, I mentioned at the beginning of this post that I’m just consolidating information here!).

The biggest change in the new design is that Bot Land will no longer be a realtime game. It’s still a strategy game involving automation, and you’re still playing against other people, it’s just that those people don’t happen to be present when you’re challenging them. This is very similar to games like Clash of Clans or King of Thieves.

As a player of Bot Land, you have two roles. As a defender, you set up your own Arena ahead of time. Your goal is to protect your CPU. As an attacker, you are matched against another player’s defense (and remember, the defender isn’t actually present during the game). You get three attempts (AKA phases) to take out their CPU.

In this new design, attackers take their time positioning their bots, choosing hardware, and rewriting scripts. When they’re ready, they can start the phase and watch their automation play out. Any damage that the defender sustains will persist throughout later phases. After the phase is over, the attacker can make adjustments to their strategy and pick up where they left off.

Because attackers get to react to what they’re seeing in the Arena, defenders need some kind of advantage too. Defenders are able to place more bots than attackers can, and they also get to install chips into their Arena. Chips can boost the damage of their bots, make them move faster, or perhaps even alter the rules of engagement (maybe one such chip will make your CPU immune to damage until the chip is destroyed).

After an attacker is finished, the defender will be given a replay of what happened. Maybe the attacker teleported over all of your bots and gunned down the CPU quickly, or maybe they whittled you down with fiery weapons. The defender can use this knowledge to patch up any holes in their defense.

Bringing this back to the decision tree of Bot Land, attackers now have these decisions:

  • High-level strategy
    • Do I want to put down many bots in one phase, or do I want to spread them out evenly over all phases?
    • Do I go after their chips, their bots, or their CPU?
  • Low-level strategy
    • Where should I put my bots?
    • What should their hardware be?
    • What should their behavior be?

It’s my goal as a game designer to give defenders all sorts of different tools so that attackers aren’t falling into the same patterns. It would be a shame if attackers could win most matches with the same strategy, so it’s your job as a defender to come up with something unique! There will be plenty of hardware and chips at your disposal, and of course you can always write custom scripts that will surprise attackers.

Conclusions

This new design of defenders and attackers is analogous to puzzle-makers and puzzle-solvers. Sure, there are going to be some dead-simple defenses that you come across and “solve” instantaneously, but my hope is that defenders will keep evolving them to the point where even seasoned players are challenged. It’s in this way that I think the new design comes together; a player’s ingenuity is what should decide how well they do in Bot Land.

I prototyped and playtested enough of the new design to the point where I can say that it’s worth pursuing. I’m sure there will still be tweaks down the road, but as long as they’re not major overhauls, I think we’re on track for a fun game!

My Sublime environment

Update (9/23/18): I’ve switched to Visual Studio Code. Read more here.

I always strive to be as efficient as possible in whichever editor I’m using at the time. I’ve settled on Sublime Text for the last few years because it is fast and customizable. I’ll share the plug-ins that I use the most while working on Bot Land, but keep in mind that I’m writing Bot Land in JavaScript (specifically ES6), so some of the plug-ins that I show may not be relevant for your project.

Just a note: to install any of these packages, take a look at the Package Control installation guide.

DocBlockr (link)

Description: forms comments and automatically uses the JSDoc style.

Explanation: JavaScript is not statically typed, so let’s say you write a function that takes in a person as an argument. Should that person be a plain JavaScript object? Should it be a Person? Is it optional? What is the return type of the function, if anything? Making JSDocs will clarify this for you, and DocBlockr makes it easy, even abiding by any rulers that you’ve set in Sublime so that comments don’t extend too far horizontally.

Extra details: one “gotcha” for this plug-in is that sometimes you want to write comments like this:

If you put the cursor on line one and try autoformatting (default: alt+Q on Windows), you’ll end up with this:

To fix this, make sure line 2 doesn’t have a trailing space.

Evaluate (link)

Description: runs the selected text through a Python eval() call.

Explanation: this is one of those plug-ins whose use is not immediately clear. It is just a wrapper around eval, meaning you could always open Sublime’s built-in Python interpreter (ctrl+backtick on Windows) and input your expression there. Here are a few instances where I’ve found it helpful (the first bullet point accounts for 99% of my uses with it):

  • Evaluate mathematical expressions: 54 * 32 turns into 1728. That’s pretty straightforward, but this can be very useful with multiple cursors. For a contrived example, imagine you have this:

Using multiple cursors, you could select both semicolons, insert *2 before each one, then evaluate the selections to give you:

  • If you’re actually coding in Python, then Evaluate can be useful for testing Python behavior from right inside Sublime. For example, evaluating [1, 2, 3] + [4, 5, 6] will give you [1, 2, 3, 4, 5, 6].
  • Generate long repeated strings: "*" * 80 will give me 80 asterisks in a row. I use this for logging to the console sometimes.

FileDiffs (link)

Description: this lets you diff selections or tabs of arbitrary content.

Explanation: every programmer has a need for diffing text at some point, so I don’t think there’s too much to explain here. One nice thing is if you’re looking through a file and you want to compare, say, two functions to see what the differences are, you can just highlight them both, right-click, and choose “Diff Selections”.

Sublime Text Git (link)

Description: this is an interface for Git directly in Sublime (e.g. you can do “git status”, “git diff”, “git log”, etc. from the command menu).

Explanation: I got this for performing “git diff” from inside Sublime, but I honestly don’t find myself ever using it. I instead end up using TortoiseGit on Windows, but I still wanted to keep this on the list since I think it’s a good plug-in.

Extra details: make sure you initialize your repo by going to Tools → Git → Init. Specify the parent of a “.git” folder. Then, to use any of the “Git:” commands, you need to be working on a file that is a descendant of the folder you chose.

GitGutter (link)

Description: this shows an icon in your gutter when a line in the current file is different from what you have in your Git repository.

Explanation: this plug-in provides something that is seemingly very insignificant, but I really like seeing an icon when I’ve modified a line. It’s hard for me to articulate why though; I think I just like knowing that I’m not crazy and that I did indeed change a file without having to actually perform a diff. Plus, if you see the icon on a blank line, you know you’ve changed whitespace.

Extra details: in all of my time using Sublime, I’ve never had performance problems until I installed GitGutter. After that, moving lines up and down started acting very slow, but only on Windows. I changed two settings and the problems were fixed (update: May 17th, 2018: there’s only one setting now, and perhaps it no longer negatively impacts performance):

  • Set “live_mode” to false.

The easiest way to make these changes is to go to Preferences → Package Settings → GitGutter → Settings – Default, but you really should override the defaults in the “Settings – User” file.

JsFormat (link)

Update (May 17th, 2018): I now use PrettierJS and a Sublime plug-in called JsPrettier to format files, but I’ll keep this section here since JsFormat is used in the video at the bottom of the post still.

Description: this runs JS Beautifier on the selected text, automatically correcting formatting and style.

Explanation: I installed this plug-in because the built-in command for “Indentation: Reindent Lines” never seemed to do what I wanted.

It can turn this code:

into this:

ReverseR (link)

Update (February 16th, 2017): I’ve switched to using ToggleWords because it was written more sanely. I suggest you look at their GitHub page and ignore this section on ReverseR.

Description: converts a selected word into its opposite (e.g. “true” becomes “false”, “left” becomes “right”).

Explanation: I made this plug-in because of how often I needed to edit a configuration file and toggle something like “isDevMode: true” to “isDevMode: false”. I figured I might as well add in more pairs of words that are opposites (or close enough to opposites, e.g. “x” and “y”, “width” and “height”).

It also maintains casing:

  • All lowercase: “true” becomes “false”
  • All uppercase: “TRUE” becomes” FALSE”
  • First letter capitalized: “True” becomes “False”

This means you can highlight Width in getWidth, run ReverseR, and now you’ll have getHeight.

Extra details: I did not ever plan on sharing this code, so I only uploaded it to http://botland.net, but if enough people say they like it, I could turn it into a proper Sublime package.

PlainTasks (link)

Description: this forms a TODO list with checkable items.

Explanation: I tend to keep “committable” items in a PlainTasks TODO list directly in Sublime, that way I can just switch tabs to see what I have left to do.

PlainTasks example

Extra details: the default color scheme is terrible. Go into Preferences → Package Settings → PlainTasks → Settings – User to change it:

EasyMotion (link)

Description: quickly navigates to a particular character on the screen.

Explanation: suppose you’re on a line of code and want to get a particular instance of the letter ‘h’ on the screen.

You can invoke EasyMotion (ctrl+; by default), then type ‘h’, and it will tag all of the instances of that letter on your screen with a single-character keyboard key:

Now I can choose which ‘h’ I want to navigate by pressing the corresponding highlighted character. For example, to go to the very first ‘h’ on the page, I can type ‘k’.

Extra details: EasyMotion also comes with a shortcut (ctrl+shift+; by default) which will select all text between the original and new cursor positions.

Other plug-ins / thoughts

I don’t think these are worth linking to, but I’ve installed several plug-ins just for syntax highlighting: batch, PowerShell, 6502 assembly, ES6, and probably a few others.

If you ever find yourself typing a block of code repeatedly, consider making your own snippet. For example, in Bot Land, I frequently need to get a component from an entity, so I wrote a snippet to do that. There are resources online that show you how to do this, so if you need help, seek those out or look at the existing snippets that come bundled with Sublime.

Demo

I recorded a quick demo of some the above plug-ins:

Blog changes

I’ve made six blog posts already, but now it’s time to announce a big change to the blog: it’s going to become much more interesting. How will I accomplish this? By violating something I wrote in the very first post of course!

I plan on making at least one post per week.

I wrote that post before I was on Twitch, Facebook, and Twitter. I think each platform can provide something unique. I want to pivot this blog so that I’m only posting meaningful content here, e.g. technical discussions, big milestones, etc. This is better than trying to shoe-horn a post in every week regardless of the quality. Plus, not many people have visited the blog:

blog_stats

If you still want a weekly dose a Bot Land, there are the recap videos on YouTube: