Hello there, delightful creature!

Welcome to DevChat #7! Here's what's on deck:

  • Aphantasia, and you!
  • 300 hours of podcasting
  • Ocular migraines
  • On your own right side
  • Progressive survival in Valheim
  • Typescript: Getting started
  • Typescript: All tests passing

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!

Aphantasia, and you!

Last week I talked at length about aphantasia (the inability to form mental images) and how I believed it impacted my life. I asked for readers to share their own stories with me so we could compare notes, and they did! I appreciate everyone who replied, and want to briefly discuss one story in particular:

Someone shared that they don't have aphantasia, but do have that whole "Severely Deficient Autobiographical Memory" thing. I had been thinking of my aphantasia as being explanatory for the fact that I don't have experiential memory, and it still might be in my case, but it turns out you can have SDAM while also being able to form mental images!

Just your weekly reminder that brains are really weird, no one understands them, and we're all quite different from each other in often surprising ways. We're all just doing our best here.

300 hours of podcasting

Last week the 300th episode of our "Coffee with Butterscotch" went live.

Three. Hundred. Episodes. For context:

  • November 2012: Sam and Seth (my brothers and co-founders) quit their jobs and started making games full time.
  • February 2013: The studio's first game (Towelfight 2) was published.
  • July 2014: I joined the team after finishing grad school.
  • March 2015: The first episode of Coffee with Butterscotch went live.
  • January 2016: Crashlands launched.

The podcast documents 6 of the just-over-8 years of our journey. From knowing nothing about making and selling games to... well, knowing some stuff about those things. Enough to survive this long, anyway. While we couldn't talk openly about everything (you know, NDAs and marketing strategies), we were pretty dang open throughout. I don't listen to our episodes when they come out, but do listen to them in a trailing 1-1.5 year window, so that I can see what we were doing and why, and how those things have panned out now with hindsight.

It's illuminating, if sometimes embarrassing. We'll always know more than our past selves, and a corollary of that is that everything we believed in the past is at least partially wrong. Being able to witness that journey by listening to my past dumb self say things I now completely disagree with is humbling!

Anyway, a huge thanks to those readers who have given the podcast a shot over the years. And if you haven't, now's as good a time as any!

And for those thinking about doing something similar, but worrying about whether or not anyone would care or worrying that you'll embarrass yourself: both of those things are okay. We learn from our mistakes, and there's no reason that some rando should care what we think!

When we first launched the podcast we already had four games out, two with over a million downloads each on mobile. Despite that, our first half year of podcasting yielded something like 30-80 listens per episode. Even today we get ~2000 per episode. That's not a tiny number, but it's not big either (in relation to some other niche podcasts), despite doing it for 6 years and having launched two well-received games in that time. It's still worth doing for ourselves, and for the listeners who do show up.

Ocular migraines

A year or two ago I was watching Netflix on my phone, when I suddenly realized that I couldn't see a portion of the screen. I don't mean it was black, or blurry, or anything like that. It just... wasn't. I moved my hand around in front of my field of view to see how much of my vision this was happening to; my hand would simply cease to exist in certain regions.

The best way I can explain it is if you were to take painting, cut a big hole into it, and then stitch the sides of the hole together to end up back with an intact painting that's just missing a part.

The impacted area slowly grew over the next ten minutes while my wife and I were getting ready to go to the ER, and while I was making phone calls to doctors I knew to ask if they knew what this was. Fortunately, a childhood friend of my brother's is an optometrist, and called back before we got in the car to say that it sounded like a textbook "ocular migraine". He said it would almost definitely go away in 20-30 minutes.

By that time it had already been almost 20 minutes, so I decided to wait a bit longer. Sure enough, my vision fully came back and I was none the worse for wear. There was no pain, only encroaching and horrifying vision loss.

I didn't know these were a thing until I had one, and I thought something extremely bad was happening. Maybe now if it happens to you it'll be less terrifying. Though probably you'll still want to get it checked out ASAP, since it still could mean something as bad as it seems!

On your own right side

Crashlands 2, our latest title, has been progressing beautifully. We're still in the R&D phase, so there is a lot of experimentation and rework going on. In particular, we've been trying to nail the first creature that you'll see in the game. Creatures always require a lot of design work, but that first creature requires even more. It's the first potentially-combative thing the player encounters, so it will be used to teach combat. It's the first living thing the player encounters, so it sets the vibe of the living world we've created. It needs to be something the player remembers.

As Seth and Sam have been repeatedly reworking this first creature, there has been a consistent claim from QA the whole time: the creatures eventually drift towards the right side of the world.

Every time this claim has come up, Seth has looked back at the code to look for an explanation, and tried to replicate what QA was seeing himself, all to now avail. The assumption was that there was some mismatch between design of the AI and player expectations creating this illusion. Our brains are wired to find patterns, and not wired at all to understand randomness (which is why simulated "randomness" has to be less random for people to believe it), so there must be something too random about the movement! Right?

Well, Seth finally found the explanation last week. It wasn't a psychological phenomenon at all, or even a design problem. It was a sneaky bug.

The creature AI has it moving around the map, eating resources when it's hungry, avoiding the player character, and preferring to be close to others of its own kind. All of this is done through biased-random choices. The creature AI could either move towards food, or move away from the player, or move towards its buddies. How does it choose? As it gets hungrier, we weight the choice towards food. As it gets closer to the player, we weight it towards moving away. When it's neither hungry nor in danger, we weight it towards moving towards buddies. But it's all still random so that you get the impression the creatures are understandable but not predictable.

So here's what happened. When the creature fell into that last category (not in hungry, not near the player), they would look for nearby buddies and, if they found one, move towards that buddy. But if they didn't find one they would move in a random direction. Simple enough. However, the creature was including itself in the list of buddies it could move towards! That meant that, on occasion, the creature would pick itself as the target to move towards.

That was the bug at the root of this.

The amusing consequence was that the creature would then ask, "in which direction from me is my buddy?" so that it would know in which direction to weight its random movement. To do that, Seth was using a built-in game engine function that gives the angle of the line between two (x,y) coordinates. Makes sense. But what happens when those two coordinates are the same (because they're both self)? In that case you could argue that the angle is undefined. Maybe you'd throw an error (just like you would if someone tried to divide by zero). The graceful-failure case is to choose a reasonable default, such as 0. That last thing is what the function did.

Taken together: a creature could find itself when looking for a buddy to move towards, and the direction "towards itself" was always 0°, and on the 2D game axis that is to the right. So it was indeed the case that all creatures would slowly drift to the right!

There are a few takeaways here:

  • Interesting AI can be quite hard to debug, because randomness can hide subtle biases.
  • Part of our design job is to exploit randomness, and more specifically how people are wired to interpret it. But it can be quite difficult to figure out if how someone then interprets it is because of a mistake you made in design, or a bug you've introduced, or a misunderstanding you have about the psychology of randomness.
  • When QA continues to insist something that you can't replicate, there's a good chance they're right about it.

Have any stories about randomness creating amusing or hard-to-find bugs? Tell me about them!

Progressive survival in Valheim

My wife and I got into Valheim last weekend, apparently along with the rest of the universe. Long story short: it deserves the attention it's getting.

Much like Terraria, Don't Starve, or A.R.K., I suspect Valheim would not be much fun in the long term playing solo. Also like those game, I suspect that the onboarding won't be nearly as fun without someone else off of whom to bounce all the "hmmmm, how do you think this works?" questions. I recommend playing with a buddy if you're going to give it a shot.

Unlike other survival games I've played, Valheim takes what I'll call a "progressive survival" design strategy. What I mean by this is that you get a lot of choice about how hard the game is for you, and what survival means. Their version of the hunger meter highlights this perfectly:

Usually in survival games you slowly die if you get too hungry, and different foods do more or less of a good job of filling you up. It's not super interesting, and is a constant thing you have to worry about. After all, if you can't find food you will simply die.

In Valheim food does heal you when you eat it, but it is framed as temporarily increasing your max health. If you are "starving", you simply have your baseline max health. You don't slowly die and you don't have to frantically search for food at the cost of anything else you might want to do. Want to just hang out in a safe zone and build houses? You can totally do that, and never have to eat a bite!

Valheim also limits how you eat: you can only eat one each of up to three different things, and until you've, uh, I guess "digested" those things you can't eat anything else. Each kind of food heals you for a different amount and can provide other bonuses, with the end result being that food is now something you can min-max in an interesting way if you want to.

And so Valheim takes that classic survival mechanic of starvation and makes it both interesting and non-punishing, all while having it dramatically influence some aspects of your gameplay experience. Most of the crafting and survival mechanics of the game have similar nuances in their design. You get to opt into the kind of gameplay experience you want and which parts you want to be hard.

I highly recommend giving it a shot. I even set up a dedicated server on AWS yesterday since it feels like my wife and I will be playing this quite a bit in the coming weeks.

Have you been playing Valheim? Have you noticed any other elements of "progressive survival" design? Tell me about it!

Typescript Handbook

I've talked about Typescript a lot recently, and will likely continue to do so. They just released a new version of the Typescript Handbook, and so far everything I've read of it has been stellar. If you've been on the fence, or don't see why people are into it, or have had trouble getting started, I highly recommend going through this new handbook.

Typescript: All tests passing

Last week marked week 3 of my attempt to convert Rumpus (the webtech powering our games and website) from plain Node.js to Typescript. The end result: all tests passed!

I still have a bunch of related work to do, in particular to update the build pipeline now that there's an extra compile step, but the most tedious part of the work is now complete. It's a huge weight off my shoulders, and I can be excited about working on Rumpus again (the absence of type support in such a large project was making things increasingly horrible).

I learned a ton of interesting stuff while doing this, and the level of competence I feel I have in Node.js, Typescript, and the associated tooling around these things has gone up way more than I expected. I couldn't have done this project at all a year ago. Maybe not even six months ago. But at this time it wasn't even a big deal. Sure, it was still the case that I didn't know how a lot of it would work and went down a lot of blind alleys, but I was able to problem-solve my way through without getting stuck. It was even fun.

I'll need to put together a bunch of articles on all the weird little lessons learned and technical tricks I came up with, but if there's anything you're particularly interested in hearing about let me know.

Next time

That wraps DevChat #7!

I've been having a great time hearing from readers. If you haven't said hello, please do!

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

Have a great week!

❤ Adam