Greetings, Earthers!

This is an archive of a DevChat newsletter. To get the next one early, and in your inbox, sign up! To read past issues, head to the archives!

Last week was a wild ride for yours truly. It began with distraction, middled with pills, and ended with the decision to convert the Rumpus code base from plain Node.js to Typescript! I'm both excited and horrified. Let's get into it.

Today we've got:

  • Focus juice
  • Why Rumpus is getting Typescripted
  • Terraria vs. Google
  • How to discount your game

Better Living Through Chemistry

TL;DR: I finally have an effective treatment for my recently-diagnosed ADHD, and life is much better.

If you've listened to our podcast in the past few months, there's a good chance you've heard us talking about what turned out to be an all-brothers problem: ADHD.

ADHD is a stupidly named neuroatypicality. It stands for "Attention Deficit Hyperactivity Disorder." As with pretty much any brain chemistry thing, there's a huge spectrum for what it actually means to have ADHD, and that spectrum has large overlaps with other neuroatypicalities. The "Hyperactivity" part really throws people off. Also, it's extremely poorly studied in adults.

I'm not an expert, so I'm not going to go on about it at length here. There are a few takeaways worth knowing, however:

  • ADHD rarely goes away in adulthood, so the rate at which adults have it is basically the same as for children. In other words, despite what everyone seems to think, ADHD is not a thing that only children deal with.
  • It's severely under-diagnosed, especially for women.
  • Just because you can pay attention to things that you like doesn't mean you don't have it. In fact, hyper focus, on very specific things, is a hallmark of ADHD.
  • Adults with untreated ADHD have built elaborate systems and rituals to compensate, so they might not realize they have it. For example, my keys and wallet never leave their respective pockets for any longer than it takes to (1) use them, or (2) move them into tomorrow's pair of pants. The moment I slip them into a coat pocket, or set them on the counter, I'm guaranteeing a future 10-20 minute desperate search.
  • Everyone tries to make treatment about capitalism. They say, "Well, if you're able to work you probably don't need treatment!" Or you'll get your treatment, but it's organized around your workdays. Sure, you probably need help to get through your work, but in my own experience my evenings and weekends are the worst, because socializing is hard with ADHD and making yourself do chores is even harder.
  • It's not just about attention. ADHD can dramatically impact mood and other facets of your life.
  • Did I mention it's truly stupidly named?

I've been working with my psychiatrist to find a pharmaceutical solution to my own ADHD, plus some recent mild depression. The last two months took one approach, which focused on the depression first but didn't help with anything. In the middle of last week I got switched onto first-line ADHD meds. The good stuff.

I was surprised to find that I didn't feel any different on the new meds. I was expecting, I don't know, to feel really energetic or something. But looking back at the week it was much easier for me to tackle hard problems, I didn't feel like I just needed to DO NOTHING during my evenings and weekends, work and socialization didn't make me exhausted, and overall I just felt happier. Apparently everyone around me noticed a positive difference, which is often the easiest way to find out that something about your brain has changed.

Anyway, why did I tell you all that? Isn't this a newsletter for tech and games!?

  1. I'd bet anything that ADHD is more prevalent in the tech community than average. Tech attracts nerds (which I mean endearingly, and in which I include myself), and nerddom is basically defined by an intense interest, even an obsession, for some particular topic. One might even call that... hyper focus?
  2. Mental health is real health, with physical, biological underpinnings. It has way too much stigma. I want to help normalize it, and I have a platform with which to do so. Yes, I've got ADHD. Plus a dash of depression (though it now seems that this was a consequence of the ADHD). And a huge dollop of aphantasia. Those are not personal failings, they are just facts. If the world I lived in was constructed differently, maybe these facts wouldn't impact my life at all. But I don't get a say in how the world is constructed. It just is. And there's no sense pretending like it was designed for me.
  3. You can't understand how other people experience the world, and so your assumptions about both yourself and other people are wrong. ADHD, and all the other ways my brain is atypical, have dramatically impacted my life, especially since for most of my life I didn't know that other people's brains worked differently. That was the fact that caused problems and distress! Why were certain things so hard for me? I must have just been LAZY! Nope: I was neuroatypical.

Brains are weird, no two are alike, the world wasn't designed for yours specifically, and basically nobody knows anything about how anyone else's brain works. It's amazing we can function in the world at all.

Once you go Typescript, there's no going back.

TL;DR: I'll be converting the entire Rumpus codebase to Typescript in the coming week(s). Plus, if you're a JavaScript programmer, and you aren't using Typescript, you're wasting your life.

There are two kinds of Node.js/JavaScript programmers: Those who absolutely love Typescript and won't stop talking about it (much to everyone's annoyance), and those who haven't learned enough of it to become such a person.

JavaScript is the programming language of the web and, therefore, the most popular language out there (depending on how you rank such things). Typescript is a "superset" of Javascript -- it includes JavaScript but also other stuff. In fact, Typescript compiles down to regular JavaScript, so all that other stuff also ends up being JavaScript. What is all that other stuff? As the name implies, Typescript allows you to pretend like JavaScript is a "strongly and statically typed" language.

What the heck is that, and why does it matter, you ask?

"Type" means "the particular kind of data that something is." A piece of data could be an "integer", "string" (computer science lingo for what the rest of us just call, you know, text), "boolean" (something that can be true or false), or one of any number of kinds of things.

Each programming language has its own beliefs about what types even are. For example, in JavaScript there is only one kind of number: its type is simply called "number". GameMaker Studio does this too††, only it calls this type a "real" (short for "real number"). In contrast, C++ has a whole bunch of different number types: 8-bit integers, 8-bit integers that can be negative, floats, doubles (big floats), etc.

A "strongly typed" language is one in which no ambiguity about types is allowed. It is in contrast to a "weakly" typed language.

For example, without being explicit a 3 could either mean the integer (whole number) value 3, or a floating-point decimal value 3, or even "3" as a piece of text representing a number. In contrast, 10.0 is probably meant to be a float, since you don't put decimals on integers. But is that definitely what it means?

Weakly typed languages just say, "eh, don't worry too much about it, it's likely we'll correctly guess what you were trying to do." This is great when the engine guesses right, but you can get into trouble if you don't know the details of how that guessing gets done. Would you be surprised to find that, in JavaScript, 10 + "10" yields the text "1010" while 10*"10" yields the number 100? It makes sense once you know why, but that's exactly it: with a weakly typed language you'll usually be fine but can easily run into troublesome surprises.

Weak types give you enormous freedom in how you code, allowing you to usually do what you want with less mental overhead and less code. But as a wise uncle once said, "With great freedom comes bad tools."

The real problem with weakly typed languages is that because there is so much flexibility in what you're allowed to do, and what you're doing isn't explicit, your tools (like your compiler/interpreter, code editor, linter, etc) are extremely limited in how much they can help you.

Which brings us back to Typescript. Typescript allows JavaScript to be strongly typed, while still making room for the flexibility and simplicity that JavaScript normally brings to the table. With Typescript you might now say, "This thing can be either a string or a number." Then, when you try to use that thing in a function which you've said only allows arrays, your editor and/or Typescript compiler can tell you that you've probably done something wrong.

The preventing-errors thing is great, but that's just a side effect of the true power of a strongly typed language like Typescript: your tools can know everything about your code. Your tools know what functions you've defined, what kinds of values they take, what kinds of values they return, whether they're asynchronous, what all your variables are called, and so on. You can start typing a variable name and your editor can auto-complete it for you. You can hover over a variable and see what could be inside of it. Suddenly the amount of mental overhead you need to do your work plummets, because you can now offload remembering things to your tools!

I started playing with Typescript 18 months or so ago, and was increasingly using it in small projects until around 9 months ago, at which point I began to always use it for new projects. I didn't get the full benefits for a while, since I had to learn how to use it effectively and get past the increased complexity of project setup that Typescript requires, but the more I learned the more obvious it became that Typescript made my life far, far easier.

Eventually, going back to plain JavaScript projects became something that filled me with dread. It was just so much harder. I started making heavy use of JSDocs in my old JavaScript projects because I was no longer willing to code without at least some type support. And, fortunately, Visual Studio Code can use the Typescript language server to provide a lot of Typescript benefits without you having to do any JSDocs or real Typescript stuff at all.

Still, every time I came back to one project in particular, all I could think about the entire time I worked on it was just how dang hard it was and how much I wished the project was in Typescript. That project is Rumpus (the webtech that powers the bscotch.net website, our games, and this very newsletter), which has been my main project now for years. It's a huge Node.js code base, and one that has grown quite organically.

It finally came to a breaking point last week. There are some issues in the core of Rumpus that create some inherent instability. So far those issues haven't caused any major outages, but they could do so at any moment. Last week I finally had the slack to go tackle those, but when I sat down to do it the code was so old, so bad, and so complicated that I couldn't make any headway. I'd been slapping JSDocs bandaids all over everything for the past year, but the net effect after all that time was that things were even more difficult to refactor because of how clunky JSDocs. It was time to bite the bullet and make the change. It was time to convert Rumpus into Typescript.

So now the old nightmare (not having Typescript) becomes a new one (figuring out how to convert a huge project, that wasn't designed around the idea of having a compiling step, to Typescript). But this nightmare actually sounds fun. More importantly, I get to dream about how amazing it will be to be on the other side of it, instead of the normal, ever-present dread that things will continue to be difficult forever.

Yes, JavaScript experts, I know there are also BigInts, that "numbers" are actually 64-bit floats, and that they get cast to 32-bit ints when doing bitwise operations, and so on. Also, I agree that all of that is super interesting. This isn't the time for all of that detail, but I'd love for you to @ me with your fun JavaScript technical facts!

†† Yes, you got me again. GameMaker does have various sorts of integers, but you can only get those by reading from a buffer or doing bitwise operations, and the moment you do anything else with them they get cast right back into reals, so they're pretty dang unstable.

Terraria vs. Google

In industry news, it was recently discovered that Terraria was coming to Google Stadia, and even more recently Terraria pulled the plug due to some very bad blood between the Terraria founder and Google.

Long story short: Google locked the Terraria dev out of all of his Google accounts, due to an unknown and unexplained violation of the Youtube Terms of Service. The Terraria dev tried to get it resolved for a month, before finally throwing up his hands, putting up both middle fingers, and yeeting Terraria off of Stadia.

On the one hand, this story is horrifying given how much I, and Bscotch, depend on Google accounts. On the other hand, it's inspiring to see an indie team out there who has had so much success that they can just walk away from the likes of Google. May we all be so successful, someday.

Discount Philosophy

This DevChat issue has already gotten pretty long, so I'm going to keep this one brief for now. It's a topic I want to dig super deeply into later as a self-contained article, but I'd like to share my initial thoughts here.

The question at hand: What do game discounts accomplish, and how can you use them effectively?

Price is the easiest lever you control when it comes to selling your game. Most stores let you go on sale with high frequency, and do little to dictate by how much you can set your discounts. The price point is simply a single number. And it is certain. Every other aspect of selling games is complicated and uncertain.

The advice you get in gamedev circles is all over the place for setting discounts. Some studios never put their games on sale. Others do so in a staged manner, perhaps starting 6 months after launch with a 10% discount and knocking it down further at every sale. Some participate in every platform sale (like the Steam Summer Sale), while others only do their own sales. Still others discount as frequently and as steeply as they can and throw keys into every game bundle under the sun.

What's the right move?

The core assumption about discounts is that making something cheaper will cause more people to buy it. While this is true, there is significant nuance here. Here are the things to consider:

  1. The number of sales you get is a direct function of visibility (how many people see your game), and conversion rate (the fraction of people who see your game that the buy it).
  2. Increased visibility usually comes with decreased conversion rate, because a broader audience is less likely to buy your game than the niched-down audience who was previously seeing it.
  3. Sale price may or may not impact visibility, depending on how store algorithms work, but is unlikely to impact visibility linearly. Marking your game at 30% off probably won't cause it to be shown to more people than if you only did 20% off, for example. It also probably won't cause it to be shown to exactly 30% more people than it otherwise would have been shown to (maybe more, maybe less). On the other hand, sometimes stores feature discounted games more aggressively at certain percentage or price thresholds.
  4. Sale price impacts conversion rate, but not in a linear way. For example, it's unlikely that discounting your game by half would cause twice as many people to convert. Could be more, could be less.
  5. The fact of being on sale impacts conversion rate.

The only things that matter when selling your game (or anything else), are visibility, conversion rates, and revenue per conversion. Assuming your goal is to do this for a living, of course. The lever we're pulling here is revenue per conversion (a.k.a. "price"). When do discounts generate more revenue for you?

The two things that can happen when you discount your game are:

  1. More people see it. (This happens if the store features your game because it's discounted, or if 3rd party sites write articles about it being on sale, and so on.)
  2. More people who see it buy it. (The reduced price point increases conversion rates.)

You don't control either of these outcomes, and neither of them behave predictably. Let's look at some scenarios:

Worst Case: The store doesn't give you a discount-induced visibility bump, so the same number of people see your game who otherwise would have without the discount. The decrease in revenue-per-user is not offset by the increase in conversion rates. Net effect: you generate less revenue than if you hadn't gone on sale.

Good Case: The store boosts visibility because of your discount. The boost is so large that it doesn't matter whether your sale price offsets the change in conversion rate. Net effect: you generate more revenue than if you hadn't gone on sale.

Good Case: The store doesn't boost visibility, but your conversion rates improve more-than-proportionally in relation to your discount rate. Net effect: you generate more revenue than if you hadn't gone on sale.

Best Case: The store boosts visibility because of your discount. Your conversion rates improve more-than-proportionally in relation to your discount rate. Net effect: you generate far more revenue than if you hadn't gone on sale.

Now for the most important bit: in all of our pricing and sales experiments so far, we've found the following to probably be true (analysis is hard):

  • The fact of being on sale boosts visibility in most stores, while the discount amount only matters in special circumstances.
  • Increasing the degree of the discount does increase conversion rate, but not fast enough. In other words, the steeper the discount the worse we do.
  • The prior fact goes out the window at certain thresholds and in special circumstances. For example, a $0.99 sale of one of our $6.99 mobile titles generated much more revenue than a 50% discount did (but a 50% discount did worse than a 30% discount).

The net conclusion from this was that we should always discount by the minimum amount possible that would be sufficient to participate in any increased store visibility.

I'd love to hear if this is consistent with your own data, if you've got it!

Next time

That wraps the DevChat #4!

Give me feedback! Specifically, which part of this issue interested you the most?

Share with others by forwarding or link directly to the archived post.

In past issues I implied that, at some point, I'd have replies to these go to my inbox. After some thought, I'd prefer to have any resulting discussion be out in the open for anyone to see. So: hit me up on Twitter with your thoughts! And if you think having comments on the archived post would be a good way to allow discussion, let me know! Finally, you can have real-time chats about this in the #podcast channel of the Bscotch Discord.

Have a great week!

❤ Adam