Scrumwave: An Online Generative Art Exhibition

Here’s the short version: I’ve made a new thing, and it’s a unified home for my bots on the Discord platform. Discord is a chat server similar to IRC or Slack with a nice web-based client and desktop & mobile apps. With this new set up, anyone can log into Scrumwave, the “server” that hosts these bots, and see what they’ve posted over time. There’s a guestbook where you can write your thoughts, just like at a museum or art gallery, and that’s it.

You can check it out at, or stick around for a bit of thinking around all this as well as some technical details.

Why do this?

In the wake of Twitter’s API changes last year, among a number of other technical and political events of various magnitudes, a number of people I know cooled on the idea of putting generative art, and more broadly automated processes we’ve referred to as “bots”, on Twitter.

I’ve done a minimal amount of work to keep them running, although a couple have gotten suspended due to more heavily automated tooling for copyright holders to issue DMCA takedowns on items that are clearly fair use and it’s absurd to think otherwise.

I also tried porting my bots to Mastodon, but honestly, the impact they have on that platform is much smaller and (this might be harsh but) it kind of feels like a waste of my time. I’m glad that there are some people who see my work there, but to convince someone I know that they should go look at my bots on Mastodon is a whole thing. I don’t think that Mastodon is, or should be, a drop-in replacement for Twitter, so I don’t think it’s reasonable to think that directly moving work originally intended for one place to another should necessarily make sense.

I had had in mind for a while now this idea of unifying my bots into one “place” online, where people could see this work passively or follow it using simple open web standards like RSS or Atom; where particularly good output could be flagged in some way and archived. Unfortunately, this is a lot of work for a hobby project and so it’s been languishing in my to do list application for years.

It occurred to me, though, that a platform like Discord provides just the right number of features to provide a sort of low-fidelity version of this. Using Discord’s webhooks, I was able to add posting to a Discord server with 5 lines of code. In the near future, I plan to add the ability for a channel to consolidate the best posts across all the bots based on “reaction emojis” people can assign to individual outputs—something else the Discord API should make pretty easy. If someone approached me and said that they wanted my bot to post in their Discord server (I doubt this would happen, but who knows?), it would be a pretty simple change to process an arbitrary number of webhook URLs each time a bot runs. Discord has the ability to set permissions on individual channels, so I can have spaces where bots can post but no visiting humans can. It’s like an automatically-enforced “quiet please” sign in a museum.

Putting the bots on Discord does mean that seeing their work requires a Discord login, but I’ve decided I’m okay with that, because Discord uses a single account to manage your access to any number of chat “servers”. It’s likely that a large number of people I know already have a Discord account, and if they don’t, the sign up process is simple and could be useful to them at some point in the future. It’s still a proprietary platform, but there’s some indication that they’re doing the bare minimum (1, 2) to address the problem of hosting hate speech on their service, something I have a hard time saying Twitter has done.

How does this work?

In the process of setting this all up, I finally accomplished a task I’ve been meaning to tackle for quite some time: merging my bots into a “monorepo”, a trendy concept in programming that I have a feeling is overapplied in a lot of companies, but seems fine here. All of my bots to date have been written in Ruby and I’ve generally relied on a lot of copy-and-pasted code to perform common tasks like managing command-line parameters, posting to Twitter and Mastodon, and doing similar operations in A/V manipulation libraries like imagemagick and ffmpeg. Over time that copy/paste has become kind of unmanageable, and trying to coordinate Ruby versions, gem versions, and installed binary dependencies (like imagemagick) has also been the source of a lot of unnecessary downtime for my bots. Since each bot is also its own git repo, I’ve been fairly neglectful in keeping the source code of my bots available on Github, even though some people have told me they’ve found that code useful in thinking about how to do similar work.

So with this I’ve started a new project, botter-heaven (with apologies to Hideo Kojima), to manage running all my bots. For the time being, the only thing that’s really unified beyond some code to handle command line parameter parsing is one set of Docker and Ruby Gem configurations, which makes the whole thing portable from one computer to another much more easily. Now that it’s all in one repo, though, I do aim to finally go back and clean up the code a bit, using the same methods for common needs like posting to Discord or adding text on top of images. This approach makes that work far, far easier than my original plan, which involved pulling code out into a Ruby gem and then adding another dependency to all my bots.

So far botter-heaven is running nicely on my ancient Mac Mini (“urza“), managing nine bots posting multiple times per day, but another benefit of this project is that I’ll soon be able to move this whole operation into the cloud and retire urza now that it can’t even install new versions of macOS.

Both Scrumwave as a Discord server, and botter-heaven as a piece of software, are absolutely works in progress. I’m not fully satisfied with either, but I’m excited to see where thinking about this work takes me over time.

Streaming Capture Card Input via VLC

I recently bought an Elgato Game Capture HD60 Pro, which provides me with an HDMI input on my PC that I can hook things like game consoles up to in order to stream/record their audio and video. Elgato provides a piece of software also called “Game Capture” that allows you to perform these tasks. It has a control center to mix audio levels between the HDMI input, your microphone, and the rest of your computer audio, as well as ways to manage overlays for webcams or other capture sources, and functionality for almost every livestreaming platform to let you stream straight from their suite instead of having to use something like the more complicated (but excellent) OBS Studio, the primary choice of most Twitch streamers nowadays.

To be honest, though, part of the reason I bought the card is just to be able to play console games in a window on my computer. I’m not sure if or when I’ll stream myself doing so, I just don’t have a separate TV in the same room as my computer and this seemed like a fun/easy way to get around it. Elgato’s software suite isn’t ideal for this; it has a bunch of extra controls on the screen to perform the functions I mentioned above and I’d really rather just have a simple resizable window with the game video in it.

Doing a bit of reading, I discovered that in Windows the Elgato cards make their input available as DirectShow sources (one for video and one for audio). Thinking back to how I could make use of that, it occurred to me that VLC actually allows you to read those as input streams!

I had to cobble together a few different tutorials to get what I wanted, which is the ability to have an icon on my desktop that I can double-click and have it stream the game console video and audio in a resizable window with no other chrome and minimal lag. I did manage to accomplish it, though, so here are the steps it required. All of this assumes that you are on Windows 10, have an Elgato HD60 series capture card, have verified that you can see/hear the input via the Game Capture software or something like OBS, and that you have VLC installed. You can probably use this information to adapt for other OSes, capture cards, etc, but I can’t help you with any more than what I’ve written below.

Make a .cmd file

We need to add a LOT of command line parameters to VLC, and they’re going to go far beyond the character limit in a Windows shortcut creation dialog, so we need to make an actual script that runs this command. Open a text editor (Notepad is fine). Start by putting the path to VLC into it (this might be different for you!), along with the parameter that will hide the play/pause/skip controls:

"C:\Program Files (x86)\VideoLAN\VLC\vlc.exe" --qt-minimal-view

Save the file somewhere (I have a “bin” folder in my home directory for miscellaneous files like this) and verify that when you open it, it opens VLC. There’ll be a terminal window showing the command, but don’t worry about that; we’ll deal with it later.

Add all the parameters to VLC

Here’s the fun part! The default parameters in VLC for viewing a DirectShow device assume basically nothing, and we need very specific values for a number of them. I’m going to first show you the full contents of my “elgato in vlc.cmd” file and then I’ll break down each of the non-default parameters and tell you which of them might need to be changed for your setup.

"C:\Program Files (x86)\VideoLAN\VLC\vlc.exe" --qt-minimal-view dshow:// :dshow-vdev="Game Capture HD60 Pro (Video) (#01)" :dshow-adev="Game Capture HD60 Pro (Audio) (#01)" :dshow-aspect-ratio=16\:9 :dshow-chroma= :dshow-fps=60 :no-dshow-config :no-dshow-tuner :dshow-tuner-channel=0 :dshow-tuner-frequency=0 :dshow-tuner-country=0 :dshow-tuner-standard=0 :dshow-tuner-input=0 :dshow-video-input=-1 :dshow-video-output=-1 :dshow-audio-input=-1 :dshow-audio-output=-1 :dshow-amtuner-mode=1 :dshow-audio-channels=2 :dshow-audio-samplerate=48000 :dshow-audio-bitspersample=16 :live-caching=1
  • :dshow-vdev: This is the name of the DirectShow video input stream. There are a couple ways to find this! The fastest is probably if you have ffmpeg installed on the command line. Just open up a terminal and run this command: ffmpeg -list_devices true -f dshow -i dummy . The Game Capture (Video) stream should be included. If you don’t, you can use VLC to figure this out. Open VLC and go to Media -> Open Capture Device... , then find it in the Video Device Name dropdown as shown below.
  • :dshow-adev: This is the same thing, but for your audio input. You can use the same methods listed above to find the correct string for this value as well.
  • :dshow-aspect-ratio: this should be 16\:9 for almost any modern device sending a signal over HDMI, but consult its manual and figure out the correct aspect ratio via its native resolution. I don’t know if you need to escape the : symbol with the backslash in front of it, but VLC put it there when I was copying parameters out of it and leaving it in doesn’t seem to hurt anything.
  • :dshow-fps: you can control this, but you probably want to just lock it at 60, from what little I know about these things.
  • :dshow-audio-channels: I set this to 2 to get stereo sound working. I’m not sure if you could make this work with surround sound or not; I don’t have a surround setup on my computer.
  • :dshow-audio-samplerate: 48kHZ is the frequency at which my card streams audio; if you have a different capture card you may want to double-check if it’s the same.
  • :dshow-audio-bitspersample: a tutorial I read said to put this at 16. I don’t really know when/why you would change this.
  • :live-caching: okay, this one is actually important. The default for streaming from a capture card is a 300ms buffer, which is wayyyy too much video lag to be able to play almost any video game. When I first set this up I set it to be 0 because obviously I don’t want any caching, right? Turns out zero is not a valid value and so it ends up inheriting the default value. If there’s a warning somewhere, it’s in a log file I haven’t looked at. Set this to 1 instead to add 1ms of video lag, which I’m sure is fine for all but the most hardcore of hardcore.

The rest of the values in this file are the defaults which I copied from VLC, which generates the list of parameters for you in a box under “Show more options” in the dialog screenshotted above.

Make an “invisible.vbs”

So we’ve got everything working, but you’ve got that ugly terminal window that opens alongside VLC, and closing it kills VLC. That’s not what I want! I think there are a few different ways to fix this, but the one I found involves a little bit… of VBScript. Aww yeah.

Open a new file and put this text in it:

CreateObject("Wscript.Shell").Run """" & WScript.Arguments(0) & """", 0, False

Save the file as invisible.vbs somewhere.

Make a desktop shortcut

Go in Windows Explorer to where you saved your invisible.vbs and right-click on the file. Choose Send To -> Desktop (create shortcut), then right-click on that shortcut and choose Properties. In the tab named “Shortcut”, in the box labeled “Target”, after the existing path to the VBScript file, add the path to your .cmd file. In my case the full target box looks like this:

C:\Users\casey\bin\invisible.vbs "C:\Users\casey\bin\elgato in vlc.cmd"

For the final touch, set whatever application icon you want via the “Change Icon” button below (I went with the VLC cone icon) and give the shortcut whatever name you want (I named it “Elgato”).

That’s it! You should now have the ability to invoke your desktop shortcut and see the input. One thing I’ve noticed is that the connection VLC makes occasionally has a barely noticeable lag to it– I don’t know enough about this stuff to understand why it only happens sometimes, but usually closing VLC and trying again fixes it.


Here’s a puzzle at the beginning of Hexologic.

Simple, right? Tap the only space until it has two dots in it.

Okay, let’s go a little bit further. Bigger board, throw in some spaces that are locked to a given number of dots:

Nice. This feels a little bit like a Sudoku puzzle, but with a ruleset that’s optimized for a phone interface. It’s just a matter of looking for the spot that has only one possible value and cascading from there. Not too bad.

The board can get pretty big, but the logic of figuring out whether each space should have one, two, or three dots remains straightforward. A good time-killer.

Once you start throwing other mechanics into the game, though, it starts to feel different. The dots in the long row have to total eleven, but the sum of the dots on each side of the > symbol have to satisfy the mathematical expression. Now we’re getting somewhere.

Hexologic has thrown a handful of different mechanics at me in the 67 levels I’ve played so far out of just short of 100 in the game. I wish there were more! The difficulty curve is extremely gentle but the back ~half of the game is enough to get you thinking.

It costs a couple dollars in mobile app stores and apparently came out last year! I stumbled across it on the App Store a couple nights ago and have been pleasantly surprised.

I Drank The Ghost???

Slay the Spire is a deckbuilding game I have become mildly obsessed with. It has roguelike elements, some of which (the powerful “relic” system) remind me of what I love about Nethack specifically and which very few roguelikes indulge in (but that’s another post), and one of them is a potions system. You have a specific number of potions you’re allowed to carry at a time (the number of which relics can augment); potions have a one-time effect; and you can buy potions in the shop alongside cards and relics.

Potions generally come in two varieties: potions that affect your character and potions that do something to your enemies. For example, a strength potion might give you 2 strength for the duration of the current fight, whereas a weak potion might apply the “weakness” debuff to an enemy. When you play a potion that affects your character, there’s a sort of “glug” sound effect that implies your character drinks the potion. When you play a potion that affects your enemies, a sound effect and animation occurs that implies you break the potion’s glass vial, presumably in a way where the contents touch your enemies.


Ghost in a Jar is a potion that affects your hero. It applies the buff called “Intangible”, which reduces any number of damage you take for a turn to 1. Let’s go back to the start of that explanation: Ghost in a Jar is a potion that affects your hero. As stated before, when you play a potion that affects your character, there’s a sort of “glug” sound effect that implies your character drinks the potion.

When I use the ghost in a jar, do I drink a ghost?

DO I DRINK A GHOST??????????????


My Favorite Things in 2018

I’ve been meaning to write more about things I’ve really enjoyed this year, but I haven’t done a… great job of that! Of course, with the end of the year approaching, people and media outlets alike have been sharing lists of their favorite games, movies, and music from 2018, and I finally decided to get my act together and write a little bit about a bunch of stuff I really liked this year. Will I publish this as is or will I get around to splitting each of these into their own blog posts like they probably could be? By the time you’ve read this, you’ll know!

Scales & Scoundrels

This graphic novel started in 2017, but the first two collected volumes came out as trade paperbacks in 2018, and wow I love it so much. The beautiful art, funny moments, and high-adventure story are the exact kind of thing that draws me to works of medieval fantasy in the first place, but over the course of the second volume I couldn’t help but be drawn into the deeper, more serious plot that reaches back to thousands of years of history. In a lot of ways it reminds me of Jeff Smith’s Bone, and I would hope that just by saying that I’ve got at least a couple people running to their comic book shop to pick this up.

This Sounds Serious

I’m not really a fan of the true crime genre, especially in the podcast medium in particular. I have a lot of complicated feelings about how the material is handled and I think it’s a tough topic to think about. Luckily, This Sounds Serious is a scripted comedy series that pokes fun at true crime tropes while also creating a bizarre universe of minor celebrities, religious cults, and pop culture memorabilia. The podcast is a production of a team of Canadian comedians who have been working in the world of comedy radio and podcasting for years; two of them were the creators of the popular show This is That. Season 2 is coming next year, so check it out now and get ready for things to get even weirder in 2019.


I came into Celeste knowing that it was a game by the creator of Towerfall, a game I really enjoyed but never had a local multiplayer crew to play regularly, and that it was based on a PICO-8 demo that I had played a little bit of when it first came out. I knew it would be a punishing 2D platformer, and that was all I needed to know to be excited about it. The game turned out to MASSIVELY exceed my expectations—the plot was far more engaging than I thought it would be, and the soundtrack is absolutely incredible. Celeste almost immediately became one of my favorite video games of all time; I love how challenging it is but how it manages to invite you to keep trying, keep going,  to get just a little bit further or find one more secret (and it’s kind of amazing how well that mechanical feeling ties into the storyline, as well). The multiple layers of hidden content are really awesome and I’ve been trying to avoid fully spoiling myself on what more there is in the game. At this point I’ve gotten every strawberry and completed some of the B-Sides, but still have more to go—and there are at least two more layers of challenge that I know of but haven’t even attempted to surmount yet.

Heroes Global Championship 2018

This is a sad one. For the last 3 or 4 years I’ve been getting more and more into the game Heroes of the Storm, a League of Legends-like MOBA made by Blizzard featuring all of the characters from their popular franchises like WarcraftStarcraftDiablo, and Overwatch. Playing the game itself is fun enough if you can get a few friends together on voice chat to play with you, but playing the game was in all honesty just a way to learn enough about the game to be able to watch pros play it in the company-run esports league called HGC.

HGC had great people doing commentary, exciting tournaments, surprising upsets, and even hype around the traditional off-season roster swaps that you hear sports fans freaking out about. I have a close-knit group of friends with whom I’d catch up on the week’s events and pass around clips, commentary, theories, and so forth. It was really fun to be involved in this as the game changed and grew.

It was announced this week that HGC would not return in 2019. It’s assumed by the player base that professional Heroes of the Storm is done forever; while it’s possible that Blizzard could bring it back or a third party could run an association for it, it seems unlikely given how unceremoniously Blizzard dumped the game into maintenance mode with very little notice.

I’m not really sure what esports I’ll be watching in 2019, but I’m pretty sad that it’s unlikely to be Heroes of the Storm!

The Coding Train

I was vaguely aware of The Coding Train under its previous name Coding Rainbow (presumably changed for legal reasons), but I had never really gotten into it. At some point this summer I just watched an episode on a whim and found the host’s enthusiasm infectious. I also found, as a person who programs for a day job and who has at times enjoyed writing software in their free time, that watching the edited version of the original streams was oddly relaxing in a Bob Ross sort of way. I knew that I could watch roughly 30 minutes of YouTube and at the end of it there would be a functioning piece of code. Anyone who’s spent their time writing software of any complexity, or spent much time around people who do, knows that the work rarely ties up with a bow so nicely, so it’s nice to escape into this world where every problem is nicely contained.

Slay the Spire

I tried avoiding this game all year. I knew I was going to get hooked, but I also was desperately hoping there’d be an iPad version announced, because it sounds so perfect for that platform that I just wanted to wait and start from there.

I lasted until sometime around late October, and I don’t even remember what it was that finally got me to crack and buy the game, but I did and I immediately fell down a rabbit hole. Now I’m staying up late playing the game, I’m watching YouTube videos and Twitch streams, and I’m pondering starting Twitch streams back up in 2019 because of it.

It’s basically a single-player deckbuilding game, but it has (sorry) roguelike elements. Permadeath is a factor, but for me what seals the deal on scratching my Nethack itch is the sheer variety of things you can collect in a given run. Obviously there are cards to choose to add to your deck, and they come in a variety of strategies you can use to try to win, but there is also a large collection of items called relics that you can earn via a variety of methods that give you ongoing, or sometimes consumable, powers that warp how you value your cards and your choices. The depth is beautiful, the balance between strategies is stunning, and I’ve barely even dipped my toe into the community’s stats-collecting and content-modding. The core loop of the game involves winning it with each of three different character classes at 21 different difficulties; in the first ~45 days of playing the game I’ve managed to win at the first 3 difficulties with 2 of the 3 classes and only the first 2 levels with the third. I’ve got a long way to go, and I can’t wait to keep trying.

There’s still no iPad version announced, but there is a Switch version coming early next year, which I only count as a runner-up solution because of the Switch’s relatively short battery life, a problem I expect I’ll start running into a lot when I buy this game on a second platform.

I was intrigued by the simplicity of this independently-owned blogging platform, which promises to let you publish an elegant website just by writing files to Dropbox. It feels very similar to blog engines that have been layered on top of static site generators like Jekyll or Middleman, but those have always felt so clunky to me, I decided I’d love to give something a try that promised to deliver a similar writing experience while streamlining the publishing portion for me. I set up to use it as a sort of “linkblog”, and it’s been going okay? I don’t exactly use it every day, but I have found it to be fast, reliable, and it makes me think about how I’d like to write more.


We started using GraphQL at work last year and I spent July 2017-August 2018 working on a team at work building out a GraphQL infrastructure, porting our ecosystem of a half-dozen or so independent apps to all share a stitched-together GraphQL API that ended up powering our company hack week. It was fun to get involved with software that’s still so actively being developed; I had the chance to contribute a few patches to the open-source community in the course of my work and also write an internal Ruby gem that I’m still hoping will be open-sourced some time in 2019. I don’t think GraphQL is a silver bullet but there are some applications of it that feel extremely clean and tie nicely into some of my favorite parts of programming.


I admit I’ve mostly fallen off here, but after joining Mastodon in 2017 and not really sticking with it, there was a fairly large exodus at one point in 2018 where a significant number of my friends were all using Mastodon regularly and so I did too. It was fun to spend time on it making jokes and chatting and generally “being online” in community with other people. I also enjoyed the freedom to make small patches to my own private server that changed the way the interface worked for me across all platforms without interfering with my ability to talk to people on other servers. I kinda hope that I’ll come back to it again, but I have to shamefully admit that the network effect is too strong for me to leave Twitter entirely this year.

Spelling Bee – NYT puzzle

Have you played the Spelling Bee! It’s super fun! I was hooked on it for a few weeks after it came out and I’ve fallen off but I still log in and check it out from time to time. I love how well it works on both desktop and mobile web. Its design adapts naturally to each platform. It’s so clean and crisp and pure and dang, what a good puzzle.

Sorry to Bother You

I watched the trailer for this when it was first announced and thought it looked extremely stylish, strange, and interesting. I avoided reading anything else about it from that point on until I saw the movie and if you haven’t been spoiled on it at all yet, I recommend you do the same. I don’t want to say much more because this movie ended up being far more than I was expecting but it was hilarious and bizarre and cool. This might be one of my favorite movies of the decade.


It won’t be a surprise when Lin-Manuel Miranda gets an Oscar and completes his EGOT, but Hamilton colleague Daveed Diggs might be right behind him, out to prove that he can act and write just as well as he performs on stage both on Broadway and as a rapper with his group clipping. He co-wrote the movie with his co-star Rafael Casal, the two of them having pitched the project years ago and finally getting to put it together in the wake of Diggs’ newfound stardom. It’s a moving, personal, funny, and extremely relevant story that you really should see.

Limetown Season 2

I wrote about Limetown’s first season just before the second one started and guess what: Season 2 also rules and continues to be an extremely compelling radio sci-fi drama that’s just a little bit creepy and overall really good. Both seasons are really short and very deserving of your time.

Killing Eve

I was feeling pretty blah about new TV shows after watching some let-downs this year (having three seasons of the extremely reliable British Bake-Off added to Netflix notwithstanding), but gave Killing Eve a shot after some friends were talking about it. (US readers, it’s currently on Hulu if you have a subscription to that.) It’s weird and self-aware and funny and just the right amount of pulpy (for now– I’m a little worried that Season 2 is going to feel like Alias if it goes in the direction I think it might). And just like Limetown, there are only 8 episodes! You can watch the whole story in a matter of days.

Favorite albums

  • BROCKHAMPTON – iridescence
  • Caroline Rose – Loner
  • The Go! Team – SEMICIRCLE
  • Hop Along – Bark Your Head Off, Dog
  • Janelle Monae – Dirty Computer
  • Jon Hopkins – Singularity
  • Justine Skye – ULTRAVIOLET
  • Kacey Musgraves – Golden Hour
  • Lena Raine – Celeste Original Soundtrack
  • Liza Anne – Fine But Dying
  • Nils Frahm – All Melody
  • Noname – Room 25
  • Ólafur Arnalds – re:member
  • Saba – CARE FOR ME
  • Sudan Archives – Sink (EP)